3 permission presets for Claude Code (strict, balanced, autonomous) and the gap none of them close A developer published three permission presets for Claude Code's `.claude/settings.json` — strict, balanced and autonomous — that control which shell commands the agent may run without confirmation, and documented two gaps the presets cannot close: prefix matching lets `Bash(git:*)` permit `git push --force` and `git reset --hard`, and a `Read(./.env)` deny rule does not stop a `cat .env` run through Bash. The developer recommends `PreToolUse` hooks that inspect the full command and can block it with `exit 2`, and released two MIT-licensed hook scripts, one blocking destructive git commands and one preventing secrets from being written to files. The presets and hooks are also bundled with six skills and CLAUDE.md templates in a US$9 unofficial starter kit. Every "Allow this command?" prompt in Claude Code is a small interruption. Click "always allow" enough times and you end up with a settings.json nobody has read. Here are three presets I keep in .claude/settings.json , from most to least careful, and the one thing none of them can do. Rules are matched in this order: deny beats ask , and ask beats allow . Anything not listed falls back to defaultMode . Read-only git is free. Commits, pushes and installs need a confirmation, and network tools are off. { "permissions": { "defaultMode": "default", "allow": "Bash git status ", "Bash git diff: ", "Bash git log: " , "ask": "Bash git commit: ", "Bash git push: ", "Bash npm install: ", "Bash pnpm add: ", "Bash yarn add: " , "deny": "Read ./.env ", "Read ./.env. ", "Read ./secrets/ ", "Bash curl: ", "Bash wget: ", "WebFetch" } } Edits are accepted automatically acceptEdits . Lint, tests and type checks run without asking, and anything that leaves your machine or changes dependencies still asks. { "permissions": { "defaultMode": "acceptEdits", "allow": "Bash git status ", "Bash git diff: ", "Bash git log: ", "Bash git add: ", "Bash npm run lint: ", "Bash npm run test: ", "Bash npm test: ", "Bash npx tsc --noEmit: " , "ask": "Bash git push: ", "Bash npm install: ", "Bash pnpm add: ", "Bash yarn add: " , "deny": "Read ./.env ", "Read ./.env. ", "Read ./secrets/ " } } All of git and npm are allowed. Use it only where a bad command costs you a branch, not a production database. { "permissions": { "defaultMode": "acceptEdits", "allow": "Bash git: ", "Bash npm: ", "Bash npx: ", "Bash pnpm: ", "Bash node: ", "WebFetch", "WebSearch" , "deny": "Read ./.env ", "Read ./.env. ", "Read ./secrets/ " } } Look at the autonomous preset again: Bash git: allows git push --force and git reset --hard too. Permission rules match a command by its prefix. They can't tell a safe git push from a destructive one. There's a second gap. Read ./.env blocks Claude's Read tool, but it isn't a rule about the shell. A cat .env through Bash is a different tool and needs its own handling. That's what hooks are for. A PreToolUse hook is a script that sees the full command before it runs and can block it with exit 2 , so it can reject git push --force while allowing a normal push, or refuse any command that touches .env . Two free ones one blocks destructive commands, tested against bypasses like git push origin +main ; one stops secrets from being written into files are here: https://github.com/kailucho/claude-code-hooks-seguridad https://github.com/kailucho/claude-code-hooks-seguridad free, MIT . Presets for convenience, hooks for safety. You want both. The three presets, the hooks, 6 skills /commit , /pr , /review , /tests , /plan , /debug and CLAUDE.md templates for React, Node and GraphQL come together in the Starter Kit for Claude Code US$9, unofficial : https://luijhy.gumroad.com/l/starter-kit-for-claude-code https://luijhy.gumroad.com/l/starter-kit-for-claude-code