Rules reference
block denies the tool call before it runs. warn lets it run but tells Claude why to be careful. Override any rule in .anchorwatch.json.
Bash commands
| Rule | Default | Triggers | Claude is told to |
|---|---|---|---|
rm-recursive-dangerous |
block | rm -r/-rf whose target is /, ~, $HOME, ., .., *, a system directory (/usr, /etc, /var, /Users, …), the project root, or .git |
List what would be deleted, then delete specific paths |
rm-recursive |
warn | any other recursive delete (rm -rf node_modules) |
Confirm the path is inside the project and intended |
git-force-push-protected |
block | git push --force/-f/--force-with-lease where the target branch (explicit refspec or current branch) is protected |
Use a feature branch and a PR; the user runs it if history truly must change |
git-force-push |
warn | force push to any other branch | Prefer --force-with-lease; confirm if the branch is shared |
git-push-delete |
warn | git push --delete, --mirror, :branch |
Confirm ref deletion |
git-destructive |
block | reset --hard, clean -f/-d/-x, checkout -- ., restore ., stash drop/clear, branch -D, filter-branch, filter-repo |
Stash or commit first; ask |
sql-destructive |
block | DROP TABLE/DATABASE/SCHEMA, TRUNCATE, DELETE FROM x with no WHERE — in any CLI |
Write a migration or a scoped statement and confirm |
pipe-to-shell |
block | curl … | sh, wget … | bash, incl. | sudo bash |
Download to a file, inspect, then run |
disk-destroy |
block | mkfs, dd if=, fdisk, parted, shred, diskutil erase, > /dev/sdX |
— |
perm-broad |
block | chmod 777/a+rwx, chown -R … / |
Use minimal permissions |
env-read |
block | cat/head/tail/less/bat on .env, .env.* (not .env.example/.sample/.template/.dist) |
grep -oE '^[A-Za-z_][A-Za-z0-9_]*' .env to list names; ask the user for a value |
env-dump |
warn | bare env, printenv, set, export -p (piping into grep/rg/awk is fine) |
Grep for the variable you need |
publish |
warn | npm/pnpm/yarn/bun publish, cargo publish, gem push, twine upload, gh release create, docker push, fly deploy, vercel --prod, terraform apply/destroy, pulumi up, kubectl delete/apply, helm install/upgrade, cloud CLI deletes, supabase db reset/push, prisma migrate reset |
Only if the user asked for exactly this; otherwise confirm |
sudo |
warn | any sudo |
Make sure a system change is expected |
kill-broad |
warn | kill -9 -1, killall, pkill -f |
Target the specific PID |
system-config |
warn | appending to ~/.zshrc/.bashrc/.profile, writing /etc/hosts, crontab changes |
Get approval for persistent system changes |
Commands are split on ;, &&, || and | and each segment is checked, so cd /tmp && rm -rf /var/lib is still caught. sudo prefixes are seen through.
File operations (Edit, Write, MultiEdit, NotebookEdit)
| Rule | Default | Triggers |
|---|---|---|
secret-files |
block | .env* (except example/sample/template/dist/schema), *.pem, *.key, *.p12, *.pfx, *.jks, id_rsa/id_ed25519/…, credentials*, secrets.*, .netrc, .npmrc, .pypirc, .git-credentials, *service-account*.json, anything under ~/.ssh, ~/.aws, ~/.config/gh, ~/.kube, ~/.gnupg, ~/.docker/config.json |
git-internals |
block | any path inside .git/ (hooks excepted) |
lockfiles |
warn | package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lock*, Cargo.lock, poetry.lock, uv.lock, go.sum, Gemfile.lock, composer.lock, Pipfile.lock, flake.lock |
self-config |
warn | .claude/settings.json, .claude/settings.local.json, ~/.claude.json, .mcp.json, plugin manifests, .anchorwatch.json, .quality-gates.json |
infra-files |
warn | .github/workflows/*, Dockerfile, fly.toml, vercel.json, netlify.toml, serverless.yml, *.tf |
outside-project |
warn | a write outside the working directory (temp dirs and ~/.claude excluded) |
Read
| Rule | Default | Triggers |
|---|---|---|
secret-read |
block | Read tool on the same secret-bearing files as secret-files |
After a write (PostToolUse)
| Rule | Default | Triggers |
|---|---|---|
secret-scan |
warn | the written content contains an AWS key (AKIA…), GitHub token (ghp_, github_pat_), Stripe live key, Anthropic or OpenAI key, Slack token, Google API key, SendGrid or Twilio key, a PRIVATE KEY block, a database URL with an embedded password, a JWT, or a hard-coded literal assigned to a name like password/secret/token/api_key (env lookups and obvious placeholders are ignored). Markdown and .env.example are skipped. |
When it fires, Claude is told which pattern matched and roughly where, and instructed to move the value to an environment variable and to tell you to rotate the credential if it's real.