Real file and shell access is what makes Claude Code powerful — and exactly why it asks before taking any action that isn't safely reversible.
1The Loop Has Four Steps, Not One
A single-shot answer skips straight from prompt to output. Claude Code instead reads the real code involved, forms a plan for the change, acts on that plan (with your approval), and then verifies the result by re-running a real command — closing the loop instead of trusting its own first answer.
2Permission Is Graded by Risk, Not Uniform
Reading a file is safe and unrestricted. Editing a file is easy to undo with version control. Running a shell command can range from harmless (npm test) to destructive or external (git push, rm -rf, a paid API call) — the permission system asks separately for these because their consequences are not the same.
3Step-by-Step Breakdown
The Loop Behind Every Task. Every Claude Code task, from a one-line bug fix to a multi-file feature, runs the same loop: Read the relevant code, Plan the change, Act by editing files or running commands, then Verify the result actually works — and it asks your permission before the risky Act step.
Why It Asks First. Editing a file is easy to undo. Running an arbitrary shell command isn't always — it could delete data, push to a remote, or call a paid API. Claude Code's permission system asks for explicit approval before actions like these, and lets you approve once, approve for the session, or deny and redirect it.
In the Fixly session above, why does Claude Code ask before running npm test and again before git push origin main, rather than asking once for the whole session?
- →Different actions carry different risk — running a local test suite is safely reversible, while pushing to a shared remote branch affects other people and is much harder to undo, so each is a separate permission decision.
- →Asking twice is a bug that should be reported.
Decide What You'd Approve. Given a real Fixly task — fixing sumTaskHours and confirming it with the test suite — decide which actions you'd pre-approve for the session and which you'd want asked about every time.
The Loop Repeats Until Verified. Claude Code doesn't stop at Act — after editing tasks.js, it re-runs npm test to confirm the fix actually passes, closing the loop. If it fails, it goes back to Read and Plan with the new failure information. Next module: steering that loop deliberately with CLAUDE.md and context choices.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
N/A — terminal-based tool.
N/A — terminal-based tool.
N/A — terminal-based tool.
N/A — terminal-based tool.
Accessibility (A11y)
1Permission Prompts Are Plain Text, Not Modal Dialogs
Because approval happens as text in the terminal, it works naturally with screen readers and any terminal accessibility tooling — there's no custom UI to navigate around.
SEO Implications
- 1
Target 'Claude Code permissions explained' and 'is Claude Code safe to use' separately
New users search for how the approval system works and for reassurance about safety as distinct questions.
Best Practices
Pre-Approve Local and Reversible Actions Only
Actions scoped to your working directory and undoable via git (edits, local test runs) are reasonable to pre-approve for a session. Actions that touch a shared remote, spend money, or delete data are worth keeping gated, even if it costs a few extra approvals.
Frequent Bugs
Pre-approving 'always allow' for a broad category like all shell commands, then being surprised when a destructive one runs unattended.
Pre-approve narrowly — specific safe commands or a safe directory scope — rather than an entire category, so the permission system still catches the actions that actually carry risk.
Real-World Examples
The Test Suite vs. the Push
A developer working on Fixly pre-approved `npm test` for the session since it's local and repeatable, but kept `git push` gated. Midway through, Claude Code proposed a push before the fix was fully verified — the gate caught it, and the developer asked for one more verification pass first.
// Pre-approved: npm test (local, reversible)
// Kept gated: git push origin main (external, harder to undo)