Skip to content

Add per-tool safe profiles and an isolation policy - #82

Merged
technicalpickles merged 4 commits into
mainfrom
safe-per-invocation-grants
Oct 21, 2026
Merged

technicalpickles merged 4 commits into
mainfrom
safe-per-invocation-grants

Conversation

@technicalpickles

@technicalpickles technicalpickles commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • safe now picks a tool profile from the command name (or SAFE_TOOL) and applies config/agent-safehouse/tools/<tool>.{sb,sh}: extra grants, env passthrough, and optionally an isolated XDG cache and state root under ~/.local/share/safe/<tool>. First two profiles are prime-agent and pi (the plannotator grant moves out of common.sb).
  • New SAFE_SOCKET_DIRS gives a command bind/accept/connect on unix sockets in the listed dirs. Safehouse has no flag for that, and its own SAFEHOUSE_ADD_DIRS, SAFEHOUSE_ADD_DIRS_RO and SAFEHOUSE_ENV_PASS already cover dirs and env, so that's the only gap I filled.
  • bin/safe-tmux drives a shell under safe from a detached tmux session, for poking at things without an interactive terminal.
  • ADR 0063 covers the per-invocation knobs. ADR 0064 (Proposed) is the isolation policy: deny, isolate, narrow, share read-only, share read-write, with the reasoning for each category. Shared mise and bundler stay writable on purpose, since agents have to install things, and the ADR lists that as a known gap with ways to close it.

XDG isolation only redirects cache and state. mise's trust state is seeded one way from the real one, so existing repos stay trusted but a mise trust run by the tool never touches yours.

Test plan

I could only test against a stubbed safehouse (it can't nest inside Claude's sandbox), so this needs a real run from a normal terminal:

  • safe prime-agent status and safe pi start, and a profiled tool can write its private root.
  • mise trust and mise install still work from inside safe prime-agent.
  • A daemon can bind a socket under a SAFE_SOCKET_DIRS dir, and safe zsh (no profile) behaves as before.

~/.config/agent-safehouse links into the main worktree, so the profiles only take effect after this merges.

Follow-up work

Audit of what the existing grants expose is in progress. First pass found some broad ones (cloud SSO token cache, MCP OAuth credentials, cached executables), and those get their own PRs.

🤖 Generated with Claude Code

technicalpickles and others added 4 commits October 21, 2026 08:23
safe gains SAFE_SOCKET_DIRS for per-invocation unix-socket grants
(safehouse has no flag for them); safehouse's own SAFEHOUSE_ADD_DIRS*
and SAFEHOUSE_ENV_PASS cover dirs and env. safe-tmux is the
tool-neutral way to drive a shell under safe from tmux.

ADR 0063 records the per-invocation knobs. ADR 0064 proposes the
isolation policy (deny/isolate/narrow/share) and records shared
mise and bundler access as an accepted, documented gap.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
bin/safe picks a tool profile from SAFE_TOOL or the command's basename
and applies config/agent-safehouse/tools/<tool>.{sb,sh}: extra grants,
env passthrough, unix-socket dirs, and an optional isolated XDG cache
and state root (mise's cache and state stay pinned to the real dirs so
trust survives the redirect).

prime-agent gets state, daemon and worker sockets, and isolated cache
and state. pi takes the plannotator grant out of common.sb.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Pinning MISE_STATE_DIR to the real dir let a sandboxed `mise trust`
write into the trust state that guards planted mise configs. With
SAFE_XDG_ISOLATE the tool's state is now its own copy, seeded one way
(cp -n) from the real trusted-configs and tracked-configs, so existing
repos stay trusted and the tool can't trust anything in yours. mise's
cache is ~/Library/Caches/mise on macOS (not XDG), so the old cache pin
pointed at an empty dir and is gone.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@technicalpickles
technicalpickles marked this pull request as ready for review October 21, 2026 13:34
@technicalpickles
technicalpickles merged commit 2f05ee2 into main Oct 21, 2026
1 check passed
@technicalpickles
technicalpickles deleted the safe-per-invocation-grants branch October 21, 2026 13:35
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