diff --git a/.beans/dotfiles-ubwz--add-role-homesb-for-safe-wrapper.md b/.beans/dotfiles-ubwz--add-role-homesb-for-safe-wrapper.md new file mode 100644 index 0000000..5ecdacf --- /dev/null +++ b/.beans/dotfiles-ubwz--add-role-homesb-for-safe-wrapper.md @@ -0,0 +1,17 @@ +--- +# dotfiles-ubwz +title: Add role-home.sb for safe wrapper +status: completed +type: task +priority: normal +created_at: 2026-10-16T15:03:07Z +updated_at: 2026-10-16T15:03:42Z +--- + +bin/safe on the home role only gets common.sb. Smoke test (2026-10-16, picklebook-air) showed ~/.pickles/bin and ~/.gitconfig.d/claude-agent-home are EPERM: the symlink targets live in ~/github.com/technicalpickles/dotfiles, which nothing grants. Add config/agent-safehouse/role-home.sb with a read-only grant on the checkout, update ADR 0060. + +## Checklist +- [x] role-home.sb +- [x] re-run smoke test under safe +- [x] ADR 0060 consequences updated +- [x] PR diff --git a/config/agent-safehouse/role-home.sb b/config/agent-safehouse/role-home.sb new file mode 100644 index 0000000..4da6ece --- /dev/null +++ b/config/agent-safehouse/role-home.sb @@ -0,0 +1,12 @@ +;; Safehouse overrides for DOTPICKLES_ROLE=home. Appended by bin/safe after +;; common.sb. + +;; Dotfiles checkout, read-only. It's the real target of ~/.pickles (bin/ is on +;; PATH), ~/.gitconfig and ~/.gitconfig.d (claude-agent-home lives there), and +;; common.sb only grants the links themselves. Read-only on purpose: the checkout +;; is also where shell rc files, ~/.config/* and bin/safe link into, so write +;; access here would reach files that run outside the sandbox later (the escape +;; guard in role-work.sb, ADR 0060). Edit dotfiles outside the sandbox. +(allow file-read* + (home-subpath "/github.com/technicalpickles/dotfiles") +) diff --git a/doc/adr/0060-agent-safehouse-wrapper.md b/doc/adr/0060-agent-safehouse-wrapper.md index 40c79e2..38df43e 100644 --- a/doc/adr/0060-agent-safehouse-wrapper.md +++ b/doc/adr/0060-agent-safehouse-wrapper.md @@ -56,6 +56,8 @@ The split between files follows role, not convenience: - `role-work.sb`: everything Gusto- or pickleton-specific: `~/pickleton` read/write, pickletown config and dolt info file, `/pkg`, and the dotslash cache for Gusto's managed pi. +- `role-home.sb`: read access to the dotfiles checkout, which is where the + symlinks point on home machines. `safehouse` itself installs through mise's github backend (macOS only). @@ -72,9 +74,14 @@ The split between files follows role, not convenience: merge. This is an interim deny list, not a full model. Other execute-later paths (mise tasks, lefthook config, LaunchAgent sources, ...) aren't covered yet, and Claude Code launched from the pt root has the same exposure. -- Home role gets only `common.sb` for now, and is untested there. Where - Automic Vault serves the agent key, `load-agent-ssh-keys` skips it, so the - dedicated agent has nothing to sign with. Signing inside the sandbox on an AV +- Home role adds `role-home.sb`: a read-only grant on + `~/github.com/technicalpickles/dotfiles`, the target of `~/.pickles` and + `~/.gitconfig*` there. Without it `git config` couldn't read + `claude-agent-home` and `~/.pickles/bin` was EPERM. Read-only, since write + access would reach the same execute-later files the work escape guard covers. +- Signing on home is still open. Where Automic Vault serves the agent key, + `load-agent-ssh-keys` skips it, so the dedicated agent has nothing to sign + with (`ssh-add -l` reports no identities). 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`.