Skip to content

Keep gh's token out of the sandbox - #1898

Merged
potiuk merged 1 commit into
apache:mainfrom
potiuk:sandbox-no-gh-config-read
Oct 29, 2026
Merged

potiuk merged 1 commit into
apache:mainfrom
potiuk:sandbox-no-gh-config-read

Conversation

@potiuk

@potiuk potiuk commented Oct 29, 2026

Copy link
Copy Markdown
Member

Summary

  • The local settings template let sandboxed Bash read ~/.config/gh/, so any unprompted sandboxed command could read gh's token in hosts.yml and send it to an allowed host.
    Nothing sandboxed needs the file: gh * is in sandbox.excludedCommands, so gh runs outside the sandbox and reads its own credentials there.
  • The template and the tools/sandbox-lint/expected.json baseline drop the grant, and sandbox-lint now refuses ~/.config/gh in allowRead, the same hard invariant ~/.config/apache-magpie has.
  • secure-agent-setup.md, secure-agent-internals.md and the agent-isolation spec replace the "bash can read it, the agent can't" split with the actual model: denied to both, used only by the excluded gh.
    The isolated-setup fingerprint moves, so setup-isolated-setup-update tells installed setups to refresh.

Type of change

  • Skill change (.claude/skills/<name>/) — eval fixtures updated below
  • Tool / bridge contract (tools/<system>/*.md)
  • Python package (tools/*/ with pyproject.toml)
  • Groovy reference impl
  • Cross-cutting (RFC, AGENTS.md, sandbox, privacy-LLM)
  • Documentation (docs/, README.md, CONTRIBUTING.md)
  • Project template (projects/_template/)
  • CI / dev loop (prek, workflows, validators)
  • Other:

Test plan

  • prek run --all-files passes (--skip workspace-pytest, then workspace-pytest for the changed members)
  • For Python packages touched: uv run pytest / ruff check / mypy passes — tools/sandbox-lint (new allowRead cases for ~/.config/gh and ~/.config/gh/), tools/agent-isolation/tests/test_sandbox_add_project_root.py
  • For Groovy bridges touched: command-line invocation tested end-to-end
  • For skill changes: eval suite passes for the affected skill
  • For skill behaviour changes: a new or updated eval fixture is included in this PR
  • Other: on a live install, removing the user-scope grant makes test -r ~/.config/gh/hosts.yml fail inside the sandbox while plain gh commands keep working.

RFC-AI-0004 compliance

  • HITL — any new mutation is gated on explicit user confirmation
  • Sandbox — no new unrestricted host access; network reach declared in the adapter
  • Vendor neutrality — placeholders (<PROJECT>, <tracker>, <upstream>, <security-list>) used in all skill / tool prose (the check-placeholders prek hook is the mechanical gate)
  • Conversational + correctable — agentic-override path documented if behaviour is adopter-tunable
  • Write-access discipline — no autonomous outbound messages; drafts only, sent on confirmation
  • Privacy LLM — private content does not reach a non-approved LLM; redactor invoked where needed

Linked issues

None.

Notes for reviewers (optional)

  • What changes for an existing install: a sandboxed gh inside a pipe or $(…), or a sandboxed git push over HTTPS through gh's credential helper, can no longer read the token.
    Both already fail inside the sandbox on TLS verification, so the documented route (gh as a plain command, git push with an approved bypass) is unchanged.
  • An existing install keeps its user-scope grant until the operator removes ~/.config/gh/ from sandbox.filesystem.allowRead; complete-upgrade stops proposing to add it.
  • RFC-AI-0002 and RFC-AI-0004 still describe the original split. They record the design as decided and are left as they are.

Generative AI tooling was used: Claude Code (Opus 5.5).

🤖 Generated with Claude Code

The local settings template granted sandboxed Bash a read of
~/.config/gh/, so any unprompted sandboxed command could copy the gh
token in hosts.yml. Nothing sandboxed needs it: `gh *` is in
sandbox.excludedCommands and reads its own credentials outside the
sandbox.

The template and the sandbox-lint baseline drop the grant, and
sandbox-lint now refuses ~/.config/gh in allowRead, as it does
~/.config/apache-magpie. The setup docs and the spec say why, and the
isolated-setup fingerprint moves so installed setups are told to update.

Generated-by: Claude Code (Opus 5.5)
@potiuk
potiuk enabled auto-merge (squash) October 29, 2026 10:13
@github-actions github-actions Bot added family:setup setup-* skills family:tools tools/* family:docs Docs, MISSION.md, READMEs capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) substrate:sandbox Tool substrate: agent isolation, egress control, settings audit labels Oct 29, 2026
@potiuk
potiuk disabled auto-merge October 29, 2026 18:10
@potiuk
potiuk merged commit 4a60ffa into apache:main Oct 29, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) family:docs Docs, MISSION.md, READMEs family:setup setup-* skills family:tools tools/* substrate:sandbox Tool substrate: agent isolation, egress control, settings audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant