[codex] Harden multi-user wrap socket permissions#235
Merged
Conversation
…design When the server runs as root and `agentsh wrap` runs as an unprivileged user, the wrap process cannot connect to the notify sockets (root:root 0700 directory blocks traversal). This spec designs the fix: chown the directory/sockets to the caller UID with SO_PEERCRED verification as defense in depth, gracefully falling back to relaxed permissions when the server lacks CAP_CHOWN. Co-Authored-By: Claude Opus 4.6 <[email protected]>
6 tasks: protocol change, permission helpers, wiring, getConnPeerCreds, SO_PEERCRED verification, final validation. TDD throughout. Co-Authored-By: Claude Opus 4.6 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CallerUIDfrom the CLI intowrap-initand use it to establish per-caller socket ownership and permissions for notify/signal/ptrace socketsSO_PEERCREDWhy
agentsh wrapcould fail or become unsafe in multi-user/root-server scenarios because socket setup relied on permissive filesystem access and a single wrong local connection could consume the only accept attempt. This change hardens the handoff by propagating caller identity, validating socket setup up front, and rejecting unexpected peers without losing the listener.Impact
Linux multi-user wrap flows are stricter and more resilient. Legacy clients that omit
caller_uidstill use the compatibility fallback path.Test Plan
go build ./...go test ./... -count=1GOOS=windows go build ./...GOOS=darwin go build ./...go test ./internal/api/ -run 'TestWrapInit_CallerUID|TestWrapInit_NotifyDirPermissions|TestSecureNotifyDir|TestSecureSocket|TestGetConnPeerCreds|TestAcceptNotifyFD|TestAcceptSignalFD_ContinuesAfterWrongUID|TestAcceptPtracePID_ContinuesAfterWrongUID' -vNotes
A residual limitation remains on the explicit permissive fallback path (
CallerUID == 0or any environment where ownership cannot be tightened): a hostile local peer can still consume the fixed 30s accept window by repeatedly reconnecting. That is an availability limitation on the fallback path, not an authorization bypass.