Feat/default policies#81
Merged
Merged
Conversation
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
Ship a 13-gate enforce-mode baseline policy that fires on every supported harness (Claude Code, Codex CLI, Cursor, Claude Desktop, Gemini-via-MCP) out of the box, replacing the prior single-gate monitor-mode default. Each gate
uses cross-harness
any_ofarms so destructive shell, supply-chain RCE, secret reads, defence-evasion, destructive infra, and persistence shapes are blocked on first boot without anagentlock rules installstep.What changed
control-plane/internal/policy/baseline.yaml, loaded into the daemon binary via//go:embedfrom a newpolicy.DefaultBaseline()accessor. Replaces the hardcoded 22-linedefaultPolicyYAMLconstin
cmd/control-plane/main.go.enforcemode:rogue.destructive-bash,supply-chain.installer-curl-bash,rogue.eval-untrusted,rogue.reverse-shell,rogue.security-disable,rogue.permission-loosening,rogue.k8s-destructive,rogue.git-force-push,rogue.secret-read,exfil.cloud-cred-read,rogue.system-auth-write,rogue.shell-rc-write,rogue.cron-persistence.any_ofarms — every shell-side gate ORstool: Bash(Claude Code/Codex),tool: Shell(Cursor preToolUse + beforeShellExecution synthetic), andtool_prefix: mcp_(single-underscore prefix isa strict superset that catches both Claude/Cursor's
mcp__*and Gemini'smcp_*wire shapes). Write/persistence gates additionally spanWrite/Edit/MultiEditfor Claude Code's three file-edit primitives.control-plane/internal/policy/policy_test.go: newTestBaseline_CrossHarnessDeny(60+ sub-cases) asserts every gate denies on every harness wire shape and allows benign equivalents. ExistingTestLoad_BaselinePolicyParsesupgraded to assert all 13 required gate IDs andmode: enforce.README.md,docs/guide/policies.md,docs/index.md, andcontrol-plane/Dockerfiledescribe the new baseline + per-harness coverage matrix and call out the structural gaps (Codex has noReadtool;Gemini's native shell/file primitives bypass the daemon).
Test plan
bun testpasses (cli) — not exercised; this PR does not modifycli/cargo testpasses (ledger) — not exercised; this PR does not modifyledger/go test -race ./...passes (control-plane) — verified locally; all 7 packages green, including 60+ newTestBaseline_CrossHarnessDenysub-cases~/.agentlock, boot daemon, confirmpolicy loaded: sha256:… (mode=enforce, gates=13)in the log; triggerrm -rf /,cat ~/.aws/credentials,curl … | bash,git push --force origin main,tee /etc/sudoers,crontab -from each detected harness and confirm deny in the ledgerDROP TABLE, broaderdddevice coverage includingnvme/vd/xvd, broaderatscheduling pattern,gshadow//private/etc/shell-side coverage,
.bash_login/.zloginredirect coverage)Notes for reviewers
enforce(wasmonitor). First-boot installs will start blocking destructive shapes immediately. Operators who want monitor-only can mount their own policy viaAGENTLOCK_POLICY=/path/to/policy.yamlor layer a per-rulemode: monitoroverride.any_ofshape is load-bearing. Per-harness tool-name strings are documented inline at the top ofbaseline.yaml, citing the relevant handler files incontrol-plane/internal/api/and theupstream harness docs. Cursor sends
Shell(notBash) onpreToolUse; Gemini's MCP wire shape uses single-underscore prefixes; Codex has noReadtool at all (verified against OpenAI Codex hooksdocs).
gopkg.in/yaml.v3parser handles anchors natively; tests confirm the embedded blob loads cleanly with adeterministic
sha256hash.apply_patchreliability: per openai/codex#20204, apply_patch and MCP hooks fire inconsistently on Codex. The write/persistence gates therefore includeBashshell-sidearms (catching
tee /etc/sudoers,echo … >> ~/.bashrc,crontab -) so coverage stays reliable even when the file-edit hook drops.run_shell_command/write_file/replacebypass AgentLock today — Gemini's surface is MCP-only). Until that lands, baseline rules cover Gemini only whenthe workflow uses an MCP shell or filesystem server.
openagentlock/rulespropagates the sameany_ofshape andmcp_prefix arms to the 13 corresponding registry rules so registry installsbenefit from cross-harness coverage too.
Checklist
CONTRIBUTING.md.envcontent committedREADME.md,docs/guide/policies.md,docs/index.md,Dockerfilecomment)