Lesson 5 / 25
Allow, Ask, Deny
Write a permission policy that auto-allows safe reads, asks for risky actions and denies dangerous ones.
Friction proportional to risk
Put read-only actions (reading project files, git status, running tests) in allow so the agent is useful. Put state-changing but recoverable actions (editing files, installing dev packages) in ask or allow them only on a branch. Put dangerous or irreversible actions (deleting outside the project, git push --force, reading secrets, network to unknown hosts) in deny. Anything not listed should default to ask, never to allow.
Allow, ask, deny
A permission policy sorts every action into three buckets, and unknown actions fall into the strictest one.
A project permission file
This is the shape used by Claude Code's settings.json; other tools have similar files. Rule syntax can change between versions, so check your tool's documentation.
{
"permissions": {
"allow": ["Bash(git status:*)", "Bash(git diff:*)", "Bash(npm test:*)", "Read(./src/**)"],
"ask": ["Bash(npm install:*)", "Edit(./package.json)"],
"deny": ["Read(./.env*)", "Bash(git push --force:*)", "Bash(rm -rf:*)", "Bash(curl:*)"]
}
}Check in the project policy
Commit the permission file so the whole team shares one baseline and changes are reviewed like code. Personal overrides go in a local, uncommitted file.
Quick check: How should an action that is not listed in the policy be treated?
- Allowed automatically
- Asked about, the safe default
- Ignored
- Deleted
Answer
Asked about, the safe default — Defaulting to ask (fail closed) means a forgotten case cannot silently run something risky.