diff --git a/bin/safe b/bin/safe index 65ac8a3..bf77a76 100755 --- a/bin/safe +++ b/bin/safe @@ -37,8 +37,22 @@ if [ -f "$profiles/role-$role.sb" ]; then role_profile="--append-profile=$profiles/role-$role.sb" fi +# Optional safehouse features, each a deliberate hole in the sandbox: +# clipboard pbcopy/pbpaste work. Sandboxed code can also read the +# clipboard. +# keychain Keychain reads. Needed because gh keeps its token there; +# without it `gh auth status` says the token is invalid. +# Sandboxed code can read EVERY Keychain item you own. A +# narrower option is a dedicated token via --env-pass. +# launch-services `open` works (MCP OAuth sign-in, plannotator opening a +# browser). Without it: kLSUnknownErr -10810 from +# RunningBoard. Anything it launches runs OUTSIDE the +# sandbox with your full privileges, so it is an escape +# hatch (`open -a Terminal ...`) the role escape guards don't +# cover. +# Rationale and tradeoffs: doc/adr/0060-agent-safehouse-wrapper.md. exec safehouse \ - --enable=clipboard \ + --enable=clipboard,keychain,launch-services \ --env-pass=SSH_AUTH_SOCK,GIT_CONFIG_GLOBAL \ --append-profile="$profiles/common.sb" \ ${role_profile:+"$role_profile"} \ diff --git a/doc/adr/0060-agent-safehouse-wrapper.md b/doc/adr/0060-agent-safehouse-wrapper.md index 4449a14..40c79e2 100644 --- a/doc/adr/0060-agent-safehouse-wrapper.md +++ b/doc/adr/0060-agent-safehouse-wrapper.md @@ -38,7 +38,7 @@ it (`safe pi`). It: - appends `config/agent-safehouse/common.sb`, then `role-$DOTPICKLES_ROLE.sb` when one exists. Role rules come last so their denies win. -- enables `clipboard`. +- enables `clipboard`, `keychain`, and `launch-services`. - starts a **dedicated ssh-agent** at `~/.ssh/agent/safehouse.sock`, fills it with `bin/load-agent-ssh-keys` (Keychain passphrase per [ADR 0030](0030-ssh-keychain-loading-at-login.md), skipping keys Automic Vault @@ -77,4 +77,6 @@ The split between files follows role, not convenience: dedicated agent has nothing to sign with. Signing inside the sandbox on an AV machine would need `av-gpg` reachable from the sandbox. Not done. - `--enable=clipboard` lets sandboxed code read the clipboard. +- `--enable=keychain` lets `gh` read its token from the Keychain (`gh auth status` reports it invalid without this), but sandboxed code can read every Keychain item the user owns. Accepted tradeoff; a narrower option is a dedicated token passed via `--env-pass`. +- `--enable=launch-services` lets `open` work (MCP OAuth sign-in, plannotator), but anything it launches runs outside the sandbox with full privileges. Accepted tradeoff: this is a sandbox escape hatch (e.g. `open -a Terminal`), and the escape guard in `role-work.sb` does not cover it. - No Linux story; safehouse is Seatbelt-only.