Let policy config allow every program and set read roots - #192
Merged
Conversation
`policy.shell.allow = ["*"]` now allows every program, mirroring the wildcard `policy.network.allowed_hosts` already accepts. Deployments that want arbitrary shell execution had to allowlist `bash` and route every command through `bash -c` — a bypass dressed up as an allowlist entry, which taught agents a worse habit than simply saying "any program". The builder also stopped pinning the last three `PolicySettings` fields to their defaults. `policy.allowed_read_roots`, `policy.sensitive_path_patterns`, and `policy.shell.mode` are configurable, so an embedder can state the exact filesystem an agent sees instead of inheriting the working directory and temp directory forever. Unset keeps today's behavior in every case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pbdeuchler
approved these changes
Jul 27, 2026
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
Two related gaps in the policy surface:
policy.shell.allowhad no wildcard.policy.network.allowed_hostsaccepts*; the shell allowlist did not. A deployment that wants arbitrary shell execution had to allowlistbashand route every command throughbash -c— a bypass dressed up as an allowlist entry, which teaches agents a worse habit than simply saying "any program" and makes the profile's real surface depend on knowing the trick.Three
PolicySettingsfields were unreachable from config.policy_from_configpinnedallowed_read_roots,sensitive_path_patterns, andshell_modetoPolicySettings::default(), with a comment marking it as pending work. An embedder could therefore state the exact filesystem an agent may write, but never the one it may read — read roots stayed at the working directory plus the temp directory forever, regardless of what the deployment intended.Changes
allowed_shell_commandsshort-circuits on a*entry, mirroringallowed_hosts.ShellModeremains the only shell restriction under a wildcard, and an empty list still denies every external command.policy.allowed_read_roots— empty (the default) keeps the built-in roots; a non-empty list replaces them. Configuredallowed_write_rootsstay readable either way, so an agent allowed to modify a tree can still inspect it.policy.sensitive_path_patterns— absent keeps the built-in globs; an explicit list replaces them, and[]disables the check for deliberately unguarded deployments.policy.shell.mode—"strict"(default) or"relaxed", mapping to the existingShellMode.policy_from_confignow sets every field explicitly, so the..defaultsstruct update is gone and a future field addition is a compile error rather than a silent default.Every new knob's unset form reproduces current behavior exactly, so this is additive for existing configs.
deny_unknown_fieldsstill applies, so the new keys are opt-in by name.Verification
cargo fmt --all --check,cargo clippy --workspace --all-targets --all-features -- -D warnings, andcargo test --workspace --all-featuresall pass (withPLAYWRIGHT_DRIVER_VERSIONset, per the CI workaround).New tests: wildcard accepts any program while strict mode still rejects
eval; an empty allowlist denies every external command but still permits bare assignments; and a table overpolicy_from_configcovering unset/explicit read roots, unset/empty/explicit sensitive patterns, and both shell modes.Downstream
Outpost's unrestricted tool-access profile is the motivating consumer — it currently allowlists
bash, and its Halter sessions read from a different tree than its Claude Code sessions. It is pinned to this commit by rev until a release contains it.