fix(acp): reject unattended permission requests - #4609
Open
jmecom wants to merge 3 commits into
Open
Conversation
Default managed sessions to dontAsk and reject or cancel permission prompts instead of selecting allow_once. Explicit owner-selected non-interactive modes remain available. Co-authored-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Jordan Mecom <jm@squareup.com>
Co-authored-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Jordan Mecom <jm@squareup.com>
jmecom
marked this pull request as ready for review
August 3, 2026 21:00
The permission tests re-implemented the `reject_once` lookup in the test body rather than calling the code under test, so they would all still pass if the harness went back to selecting `allow_once`. They could not call it directly: `handle_permission_request` is a method on `AcpClient`, which owns a live `Child` and its stdio pipes. Extract the choice into `permission_denial_response` and point the tests at it. No behaviour change. This covers the cancelled fallback, which had no test despite being the fail-closed backstop for adapters that offer no `reject_once`, plus the empty-option-list and missing-`optionId` edges. Also drops `find_allow_once_returns_none_when_absent`, which asserted a property of a search no production path performs any more. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Eli Foster <efoster@squareup.com>
elifoster-block
approved these changes
Aug 4, 2026
elifoster-block
left a comment
There was a problem hiding this comment.
LGTM - expanded test coverage and removed an unused function.
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.
This change removes the ACP permission-bypass mode, defaults managed sessions to
dontAsk, and answers permission requests withreject_onceor cancellation in both ACP read loops.Unattended operations that require interactive approval now fail closed instead of being silently authorized. Explicit non-interactive modes that do not bypass a permission request remain available.
Both layers have to change together:
apply_permission_modetreats an unsupported mode and a failedset_config_optionas non-fatal by design, so a request can still reach the harness even in a non-interactive mode. RemovingbypassPermissionsfrom the enum rather than only changing the default means the mode cannot be restored by configuration alone.The scope of the guarantee is that
buzz-acpnever grants approval. An agent that pre-authorizes tools in its own configuration (for example Claude Code'ssettings.json) still runs them without asking, which is outside this harness.Testing
env -u BUZZ_ACP_LAZY_POOL bin/cargo test -p buzz-acpat16fff4d: 671 library tests and 9 integration tests passedcargo clippy -p buzz-acp --all-targets -- -D warningsandcargo fmt -p buzz-acp -- --check: cleangit diff --check origin/main...codex/security-acp-shell-auto-approvalThe permission tests previously re-implemented the
reject_oncelookup in the test body instead of calling the code under test, so they would have passed unchanged if the harness went back to selectingallow_once. They could not call it directly, becausehandle_permission_requestis a method onAcpClient, which owns a liveChildand its stdio pipes. The choice is now a free function,permission_denial_response, and the tests exercise it:reject_oncepreferred over offered allow options, the cancelled fallback when noreject_onceexists, an empty option list, and areject_oncemissing itsoptionId. The cancelled fallback had no coverage before despite being the fail-closed backstop.Operator notes
BUZZ_ACP_PERMISSION_MODE=bypassPermissionsno longer parses, so a process configured with it fails to start rather than silently downgrading.dontAsk. The desktop has no permission prompt, so operations needing approval now fail with no in-app way to approve them.Originating Buzz thread:
buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1