Repository navigation
fix(sandbox): let vetted-op writes run outside the sandbox, on the discovered policy only - #1956
Merged
Merged
Conversation
On the Claude Code secure setup every vetted-op write failed before it started: the sandbox cannot read ~/.claude/magpie, so uv reported the project directory missing, and a sandboxed gh could not verify TLS anyway. Skills fell back to bare gh writes, bypassing the catalogue. Exclude both launcher forms of vetted-op from the sandbox, as vetted-op-tracker already is, and keep both in permissions.ask. Each operation is a fixed gh argv with no shell and a workspace-only body, so the exclusion reaches less than the bare `gh *` one; the prompt stays the gate on every write. sandbox-lint now fails an excluded or allowed write dispatcher that no ask rule matches. The setup guide, install and verify skills, the vetted-ops README and the sandbox spec drop the old "never exclude vetted-op" rule. Closes apache#1952 Generated-by: Claude Opus 5
vetted-op and vetted-op-tracker run outside the sandbox, but accepted --config naming any policy file. An agent-written policy could set its workspace to a private directory such as ~/.ssh (owned by the user and mode 0700, so it passes the workspace check) and post a key from it as a comment on a repository the policy chose; only the ask prompt stood in the way. Both now refuse --config whenever an operation runs and use only the discovered policy (the committed one, else an untampered personal copy), which the secure setup write-denies. A dry run, `policy` and `list-ops` still take it, as does vetted-op-read, which refuses writes before it reads the policy. No skill passes --config to a write dispatcher. Tests that execute writes now install their policy at the discovered path. Generated-by: Claude Opus 5
The write dispatchers discover their policy from the directory they run in, but only the project's own `.apache-magpie-overrides/tools/vetted-ops` was write-denied. An agent could plant a policy (say, a workspace of ~/.ssh) under any directory it can write and run vetted-op from there, getting past the --config refusal. vetted-op-tracker had the same gap. Deny `//**/.apache-magpie-overrides/tools/vetted-ops/**` everywhere, required by sandbox-lint, and refuse a committed policy with a symlink anywhere on its path, as the personal layers already were. The isolated-setup-update skill no longer reports an excluded vetted-op as a must-fix. Generated-by: Claude Opus 5
Merged
10 of 11 tasks
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
Closes #1952.
vetted-opwrite failed before it started ("Project directory~/.claude/magpie/vetted-opsdoes not exist"): the sandbox cannot read~/.claude/magpie, and a sandboxedghcould not verify TLS anyway. Skills fell back to bareghwrites, bypassing the catalogue. Both launcher forms ofvetted-opare now insandbox.excludedCommands, asvetted-op-trackeralready was, and both stay inpermissions.ask.ghargv with no shell, parameters that may not start with-, and a body read only from the owner-only workspace — less reach than the baregh *exclusion — and every write still prompts.sandbox-lintnow fails an excluded or allowed write dispatcher that noaskrule matches.--configundid that bound: an agent-written policy could setworkspace = "~/.ssh"(yours, mode 0700, so it passes the workspace check) and post a key from it to a repository it chose.vetted-opandvetted-op-trackernow refuse--configwhenever an operation runs and act only on the discovered, write-denied policy. A dry run,policyandlist-opskeep it, as doesvetted-op-read, which refuses writes before reading the policy. This also closes the same gapvetted-op-trackeralready had onmain.--configrefusal (the same was true forvetted-op-trackeronmain). The policy path is now write-denied everywhere withEdit(//**/.apache-magpie-overrides/tools/vetted-ops/**), enforced bysandbox-lint, and a symlink anywhere on the committed policy's path is refused, as it already was for the personal layers.~/.config/apache-magpie/vetted-ops/, which no sandboxed command or agent file tool can write. Every policy file is read withO_NOFOLLOWcomponent by component, and the home directory comes from the password database, not$HOME.vetted-op" rule is dropped from the setup guide, theisolated-setup-install/isolated-setup-verifychecklists, the vetted-ops README, the sandbox spec and the threat model (C-E3).Type of change
tools/sandbox-lint,tools/vetted-ops).claude/settings.json,tools/sandbox-lint/expected.json)isolated-setup-install,isolated-setup-verify)Test plan
prek run --all-files --skip workspace-pytestpassespytestpasses fortools/sandbox-lintandtools/vetted-ops(run outside the sandbox: three personal-policy tests write fixtures under a.git/**/apache-magpie/tools/vetted-ops/path the sandbox write-denies)ask, and an allowed one, are invariant errors;vetted-op *does not catchvetted-op-read; both write entry points refuse an agent-written--configbefore anything runs (the~/.sshworkspace shape); dry run andvetted-op-readkeep--configsetup-isolated-setup-verifyeval,step-1-classify/case-7(fixture updated): PASSsetup-isolated-setup-verifyeval suite — not runRFC-AI-0004 compliance
vetted-op/vetted-op-trackerwrite keeps itsaskprompt;sandbox-lintenforces itgh *one, and the write entry points no longer act on a policy the agent can writeNotes for reviewers
vetted-opentries insandbox.excludedCommandsandpermissions.ask(isolated-setup-updatewill report the drift).mkdir -p ~/.config/apache-magpie/vetted-ops && cp .apache-magpie-overrides/tools/vetted-ops/config.toml ~/.config/apache-magpie/vetted-ops/<project>.toml. Until then,vetted-op/vetted-op-trackerwrites are refused with the command to run. Reads are unaffected.🤖 Generated with Claude Code