Skip to content

[codex] Harden multi-user wrap socket permissions#235

Merged
erans merged 19 commits intomainfrom
feat/multi-user-wrap-socket-permissions
Apr 16, 2026
Merged

[codex] Harden multi-user wrap socket permissions#235
erans merged 19 commits intomainfrom
feat/multi-user-wrap-socket-permissions

Conversation

@erans
Copy link
Copy Markdown
Collaborator

@erans erans commented Apr 16, 2026

Summary

  • thread CallerUID from the CLI into wrap-init and use it to establish per-caller socket ownership and permissions for notify/signal/ptrace sockets
  • validate socket permission setup synchronously and enforce peer UID checks on notify, signal, and ptrace accept paths using SO_PEERCRED
  • add Linux/Linux+cgo coverage for peer credentials, permission modes, UID rejection, matching-UID success, and accept-loop continuation after wrong-UID peers

Why

agentsh wrap could 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_uid still use the compatibility fallback path.

Test Plan

  • go build ./...
  • go test ./... -count=1
  • GOOS=windows go build ./...
  • GOOS=darwin go build ./...
  • go test ./internal/api/ -run 'TestWrapInit_CallerUID|TestWrapInit_NotifyDirPermissions|TestSecureNotifyDir|TestSecureSocket|TestGetConnPeerCreds|TestAcceptNotifyFD|TestAcceptSignalFD_ContinuesAfterWrongUID|TestAcceptPtracePID_ContinuesAfterWrongUID' -v

Notes

A residual limitation remains on the explicit permissive fallback path (CallerUID == 0 or 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.

erans and others added 19 commits April 16, 2026 10:57
…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]>
@erans erans marked this pull request as ready for review April 16, 2026 20:16
@erans erans merged commit acd7968 into main Apr 16, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant