## Definition
A **permission policy** is the declarative allow/deny list that gates which tools and shell commands an agent may invoke without a human approval prompt. In Claude Code, this lives in `.claude/settings.json` under the `permissions` key.
## Two Categories
- **Allow list** — patterns the agent may invoke silently. Anything not allow-listed prompts the user for approval.
- **Deny list** — patterns the agent may *never* invoke, even with explicit user approval. Reserved for true safety rails (force push, recursive delete, publishing).
## Example
```jsonc
{
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(npm run lint:*)",
"Bash(git status)",
"Bash(git diff:*)"
],
"deny": [
"Bash(git push --force:*)",
"Bash(rm -rf:*)",
"Bash(npm publish:*)"
]
}
}
```
## Design Principles
- **Allow narrowly.** Avoid `Bash(*)` — you've turned the safety system off.
- **Deny absolutely.** The deny list is non-negotiable; a user can't approve a denied command with a "yes".
- **Split by scope.** Project-shared allowances live in `.claude/settings.json` (committed); personal allowances live in `.claude/settings.local.json` (gitignored).
## Verification
- Routine session should produce **zero** permission prompts for allowed patterns.
- Denied patterns block at the policy layer, observable when deliberately asking the agent to invoke one.
## Related
- [[Agentic CLI]]
- [[Hook]]
- [[AGENTS.md Convention File]]