Skip to content

Feat/default policies#81

Merged
RonCodes88 merged 5 commits into
mainfrom
feat/defaultPolicies
May 8, 2026
Merged

Feat/default policies#81
RonCodes88 merged 5 commits into
mainfrom
feat/defaultPolicies

Conversation

@RonCodes88

Copy link
Copy Markdown
Collaborator

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_of arms so destructive shell, supply-chain RCE, secret reads, defence-evasion, destructive infra, and persistence shapes are blocked on first boot without an agentlock rules install step.

What changed

  • New embedded baseline at control-plane/internal/policy/baseline.yaml, loaded into the daemon binary via //go:embed from a new policy.DefaultBaseline() accessor. Replaces the hardcoded 22-line defaultPolicyYAML const
    in cmd/control-plane/main.go.
  • Thirteen gates shipped in enforce mode: 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.
  • Cross-harness coverage via any_of arms — every shell-side gate ORs tool: Bash (Claude Code/Codex), tool: Shell (Cursor preToolUse + beforeShellExecution synthetic), and tool_prefix: mcp_ (single-underscore prefix is
    a strict superset that catches both Claude/Cursor's mcp__* and Gemini's mcp_* wire shapes). Write/persistence gates additionally span Write/Edit/MultiEdit for Claude Code's three file-edit primitives.
  • Test coverage in control-plane/internal/policy/policy_test.go: new TestBaseline_CrossHarnessDeny (60+ sub-cases) asserts every gate denies on every harness wire shape and allows benign equivalents. Existing
    TestLoad_BaselinePolicyParses upgraded to assert all 13 required gate IDs and mode: enforce.
  • Docs refreshed: README.md, docs/guide/policies.md, docs/index.md, and control-plane/Dockerfile describe the new baseline + per-harness coverage matrix and call out the structural gaps (Codex has no Read tool;
    Gemini's native shell/file primitives bypass the daemon).

Test plan

  • bun test passes (cli) — not exercised; this PR does not modify cli/
  • cargo test passes (ledger) — not exercised; this PR does not modify ledger/
  • go test -race ./... passes (control-plane) — verified locally; all 7 packages green, including 60+ new TestBaseline_CrossHarnessDeny sub-cases
  • Manual test: wipe ~/.agentlock, boot daemon, confirm policy loaded: sha256:… (mode=enforce, gates=13) in the log; trigger rm -rf /, cat ~/.aws/credentials, curl … | bash, git push --force origin main, tee /etc/sudoers, crontab - from each detected harness and confirm deny in the ledger
  • CodeRabbit AI review run against the diff; all reported findings resolved (case-insensitive DROP TABLE, broader dd device coverage including nvme/vd/xvd, broader at scheduling pattern, gshadow / /private/etc/
    shell-side coverage, .bash_login / .zlogin redirect coverage)

Notes for reviewers

  • Mode flip: daemon now defaults to enforce (was monitor). First-boot installs will start blocking destructive shapes immediately. Operators who want monitor-only can mount their own policy via
    AGENTLOCK_POLICY=/path/to/policy.yaml or layer a per-rule mode: monitor override.
  • Cross-harness wire-truth: the any_of shape is load-bearing. Per-harness tool-name strings are documented inline at the top of baseline.yaml, citing the relevant handler files in control-plane/internal/api/ and the
    upstream harness docs. Cursor sends Shell (not Bash) on preToolUse; Gemini's MCP wire shape uses single-underscore prefixes; Codex has no Read tool at all (verified against OpenAI Codex hooks
    docs
    ).
  • YAML anchors are used inside each gate to keep regex content authoritative in one place per rule. The daemon's existing gopkg.in/yaml.v3 parser handles anchors natively; tests confirm the embedded blob loads cleanly with a
    deterministic sha256 hash.
  • Codex apply_patch reliability: per openai/codex#20204, apply_patch and MCP hooks fire inconsistently on Codex. The write/persistence gates therefore include Bash shell-side
    arms (catching tee /etc/sudoers, echo … >> ~/.bashrc, crontab -) so coverage stays reliable even when the file-edit hook drops.
  • Out of scope, tracked separately: native Gemini hook integration (run_shell_command / write_file / replace bypass AgentLock today — Gemini's surface is MCP-only). Until that lands, baseline rules cover Gemini only when
    the workflow uses an MCP shell or filesystem server.
  • Mirror PR upstream: a companion PR to openagentlock/rules propagates the same any_of shape and mcp_ prefix arms to the 13 corresponding registry rules so registry installs
    benefit from cross-harness coverage too.

Checklist

  • I read CONTRIBUTING.md
  • No secrets, real tokens, or .env content committed
  • Public docs updated if user-facing behavior changed (README.md, docs/guide/policies.md, docs/index.md, Dockerfile comment)

@RonCodes88 RonCodes88 merged commit d84977f into main May 8, 2026
6 checks passed
@knhn1004 knhn1004 deleted the feat/defaultPolicies branch May 9, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant