Skip to content

test(agent-code, agent-legacy): pin tool and grant guards at entry points - #90

Merged
SaulBuilds merged 2 commits into
mainfrom
test/runtime-tool-grant-pins
Oct 26, 2026
Merged

SaulBuilds merged 2 commits into
mainfrom
test/runtime-tool-grant-pins

Conversation

@SaulBuilds

Copy link
Copy Markdown
Contributor

Tests only. Pins existing guards at the tool execute and grant-check entry points. No production code changes.

New file agent-code/tests/tool_entry_pins.rs (sets a fake HOME and git env-config once for the binary; nothing touches the real home):

  • file_write_traversal_is_refused_before_any_directory_is_created
  • file_write_through_an_escaping_dir_symlink_creates_nothing_outside
  • file_write_inside_the_workspace_still_works (control)
  • shell_exec_does_not_pass_the_callers_home
  • shell_exec_does_not_pass_the_callers_environment_or_git_config
  • git_ops_commit_does_not_use_the_callers_git_identity

New file agent-legacy/tests/grant_and_approval_pins.rs:

  • check_grant_rejects_an_untrusted_issuer_once_strict (+ control check_grant_accepts_an_enrolled_issuer_when_strict)
  • grant_signature_binds_the_revoked_flag
  • an_unbounded_approval_timeout_still_auto_denies_within_the_ceiling

Standard: met

  • Revert check, per guard (reverted, new tests run, restored). None of these reverts failed an existing test before this PR:
    • file_write lexical + ancestor containment → both escape tests red; ancestor check alone → symlink test red
    • shell_exec isolated HOME → HOME test red; env_clear → env test red
    • git_ops isolated HOME / env_clear → identity test red
    • check_grant trust-anchor re-check → strict test red
    • revoked in the signing pre-image → revoked test red
    • approval timeout clamp → timeout test red
  • cargo +1.96.0 test -p citrate-agent-code -p citrate-agent-legacy: code 55 → 61, legacy 147 → 151, all green.
  • rustfmt clean; clippy reports nothing in the new files.
  • Tests write only under temp dirs; spawned processes run in temp workspaces.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4

…/ check entry points

agent-code (tool execute):
- file_write refuses an escaping path (.. chain, escaping dir symlink)
  before any directory is created outside the workspace.
- shell_exec and git_ops do not pass the caller's HOME, environment or
  git config to the spawned process (fake HOME + env config fixture).

agent-legacy:
- check_grant re-checks the issuer trust anchor at use time once strict.
- the grant signature pre-image binds the revoked flag.
- an unbounded approval timeout still auto-denies within the ceiling.

Each new test goes red when the guard it pins is reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGMeatV8UjtCB4CTbWuAv4

@Matr0xshka Matr0xshka left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAC independent review] APPROVED at 4c18877
Reviewer: MAC-lane independent reviewer agent (did not author this PR). Not Codex, not DGX. Per owner decision 2026-10-23 this review stands in for the Codex and DGX gates.

Head 4c188773de3c60526b0f78d13d3c65604f3f5174, checked live over REST. Base main at merge-base ce34d3e9. Tests only: agent-code/tests/tool_entry_pins.rs (+220) and agent-legacy/tests/grant_and_approval_pins.rs (+125); no production file changes. No earlier reviews and no Codex result exist for this PR. Own worktree and target dir, macOS arm64, cargo +1.96.0.

What I ran

  • cargo test -p citrate-agent-code -p citrate-agent-legacy --locked: agent-code lib 55 + tool_entry_pins 6 = 61; agent-legacy lib 147 + grant_and_approval_pins 4 = 151; 0 failed. Matches the body (55 → 61, 147 → 151).
  • #90's tool_entry_pins.rs also passes 6 of 6 on top of #91's head (copied in, not committed), so the two PRs compose.

Revert check (reproduced, one guard at a time)

Production file copied aside, minimal revert applied, new binary run, file restored (no git stash; git status clean afterwards):

Guard reverted New tests red
file_write ancestor containment off file_write_through_an_escaping_dir_symlink_creates_nothing_outside
file_write lexical containment + ancestor containment off that test and file_write_traversal_is_refused_before_any_directory_is_created
shell_exec passes the caller's HOME shell_exec_does_not_pass_the_callers_home
shell_exec without env_clear() shell_exec_does_not_pass_the_callers_environment_or_git_config
git_ops without env_clear() git_ops_commit_does_not_use_the_callers_git_identity
check_grant issuer trust re-check off (mcp_server.rs:326) check_grant_rejects_an_untrusted_issuer_once_strict
revoked dropped from the signing pre-image (canonical.rs:193) grant_signature_binds_the_revoked_flag
approval timeout clamp off (delegation.rs:58) an_unbounded_approval_timeout_still_auto_denies_within_the_ceiling

The shell and git tests do not pass vacuously: with the guard reverted, the spawned git really sees the leaked identity.

Code reading

  • The binary sets a fake HOME with a .gitconfig and GIT_CONFIG_* env once, through a OnceLock, before any spawn; nothing reads or writes the real home.
  • The approval test uses start_paused time, so the one-hour ceiling is checked without waiting.
  • The strict-mode test has a control with the issuer enrolled, so the refusal is the trust anchor and nothing else.

Findings

None blocking. Note for whichever of #90/#91 merges second: the module doc of tool_entry_pins.rs mentions "the post-create_dir_all re-check", which #91 removes; the tests themselves still pass on #91.

CI at the head

All check runs succeeded: ci, rust, audit, secret-scan, HIC terminology guard, Windows (agent-shell tests + agent-sidecar release build), CodeQL (actions, python, rust). Behind main (#86 merged since); merges cleanly.

Standard: met

Every new test goes red when its guard is reverted (reproduced above) and green with it; controls rule out vacuous passes; tests only, no dead code.

verification cleared: yes (tests-only pins on workspace confinement, process environment isolation and grant/approval checks; no production change).

@BerryManifold BerryManifold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAC independent review] APPROVED at 4c18877
Reviewer: MAC-lane independent reviewer agent (did not author this PR). Not Codex, not DGX. Per owner decision 2026-10-23 this review stands in for the Codex and DGX gates.

Head 4c188773de3c60526b0f78d13d3c65604f3f5174, checked live over REST. Base main at merge-base ce34d3e9. Tests only: agent-code/tests/tool_entry_pins.rs (+220) and agent-legacy/tests/grant_and_approval_pins.rs (+125); no production file changes. No earlier reviews and no Codex result exist for this PR. Own worktree and target dir, macOS arm64, cargo +1.96.0.

What I ran

  • cargo test -p citrate-agent-code -p citrate-agent-legacy --locked: agent-code lib 55 + tool_entry_pins 6 = 61; agent-legacy lib 147 + grant_and_approval_pins 4 = 151; 0 failed. Matches the body (55 → 61, 147 → 151).
  • #90's tool_entry_pins.rs also passes 6 of 6 on top of #91's head (copied in, not committed), so the two PRs compose.

Revert check (reproduced, one guard at a time)

Production file copied aside, minimal revert applied, new binary run, file restored (no git stash; git status clean afterwards):

Guard reverted New tests red
file_write ancestor containment off file_write_through_an_escaping_dir_symlink_creates_nothing_outside
file_write lexical containment + ancestor containment off that test and file_write_traversal_is_refused_before_any_directory_is_created
shell_exec passes the caller's HOME shell_exec_does_not_pass_the_callers_home
shell_exec without env_clear() shell_exec_does_not_pass_the_callers_environment_or_git_config
git_ops without env_clear() git_ops_commit_does_not_use_the_callers_git_identity
check_grant issuer trust re-check off (mcp_server.rs:326) check_grant_rejects_an_untrusted_issuer_once_strict
revoked dropped from the signing pre-image (canonical.rs:193) grant_signature_binds_the_revoked_flag
approval timeout clamp off (delegation.rs:58) an_unbounded_approval_timeout_still_auto_denies_within_the_ceiling

The shell and git tests do not pass vacuously: with the guard reverted, the spawned git really sees the leaked identity.

Code reading

  • The binary sets a fake HOME with a .gitconfig and GIT_CONFIG_* env once, through a OnceLock, before any spawn; nothing reads or writes the real home.
  • The approval test uses start_paused time, so the one-hour ceiling is checked without waiting.
  • The strict-mode test has a control with the issuer enrolled, so the refusal is the trust anchor and nothing else.

Findings

None blocking. Note for whichever of #90/#91 merges second: the module doc of tool_entry_pins.rs mentions "the post-create_dir_all re-check", which #91 removes; the tests themselves still pass on #91.

CI at the head

All check runs succeeded: ci, rust, audit, secret-scan, HIC terminology guard, Windows (agent-shell tests + agent-sidecar release build), CodeQL (actions, python, rust). Behind main (#86 merged since); merges cleanly.

Standard: met

Every new test goes red when its guard is reverted (reproduced above) and green with it; controls rule out vacuous passes; tests only, no dead code.

verification cleared: yes (tests-only pins on workspace confinement, process environment isolation and grant/approval checks; no production change).

@Matr0xshka Matr0xshka left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval at 595ae15, recorded on the owner's instruction (merge train).

595ae15 is the head approved by the [MAC independent review] APPROVED review (4c18877), with only the default branch merged in since.

What this approval measured:

  • Independent MAC-reviewer approval at the reviewed head (this stands in for the Codex and DGX gates, per the owner's 2026-10-23 decision).
  • Note: agent-code/legacy guard pins.
  • CI at 595ae15: ci=success, secret-scan=success.

This does not record a fresh, independent re-run of the tests.

@BerryManifold BerryManifold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval at 595ae15, recorded on the owner's instruction (merge train).

595ae15 is the head approved by the [MAC independent review] APPROVED review (4c18877), with only the default branch merged in since.

What this approval measured:

  • Independent MAC-reviewer approval at the reviewed head (this stands in for the Codex and DGX gates, per the owner's 2026-10-23 decision).
  • Note: agent-code/legacy guard pins.
  • CI at 595ae15: ci=success, secret-scan=success.

This does not record a fresh, independent re-run of the tests.

@SaulBuilds
SaulBuilds merged commit 8d2d367 into main Oct 26, 2026
10 checks passed
@SaulBuilds
SaulBuilds deleted the test/runtime-tool-grant-pins branch October 26, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants