
Claude Code needs permission to use tools on your machine. That is not friction to erase. It separates “inspect this repository” from “run an unknown command, edit a protected file, or call an external service.”
Good permissions make safe work quick and risky work visible. They do not turn a prompt into a security policy, and they do not decide whether a business action should happen.
What are Claude Code permissions?
Claude Code permissions govern tool calls: reading and editing files, shell commands, web fetches, and MCP tools. Use /permissions to see every rule and the settings file it came from. A change there takes effect on Claude’s next tool call, including during an active turn.
| Rule | Effect | Use it for |
|---|---|---|
deny | Blocks a matching call. | A path, command, or tool Claude must not use. |
ask | Requires confirmation. | A consequential action needing a human decision. |
allow | Runs without a prompt. | A narrow, reviewed repeat action. |
Claude Code evaluates rules in this order: deny, then ask, then allow. Specificity does not change that order. A narrow allow cannot create an exception to a broad deny, and an ask rule still prompts when an allow also matches. Prompts and CLAUDE.md influence what Claude tries; they do not grant access.
Put rules in the right place
Use the smallest scope that fits the job. Shared project rules live in .claude/settings.json. User defaults live in ~/.claude/settings.json, and private project overrides in .claude/settings.local.json. Managed settings give the organization a policy that lower-precedence sources cannot override. Permission arrays combine across applicable sources: adding a local allow cannot defeat a matching deny from another scope. The settings guide explains which files apply to a checkout and how to share them.
Project allow rules grant capability, so Claude Code shows a workspace-trust dialog before applying them. Review that dialog, especially in a repository you did not write.
{
"permissions": {
"allow": ["Bash(npm run lint)", "Bash(npm test *)", "Edit(/src/**)"],
"deny": ["Read(/.env)", "Read(/.env.*)", "Read(/secrets/**)"],
"ask": ["Bash(git push *)"]
}
}
For project settings, paths beginning with / are anchored to the project’s primary working directory. This example permits the named commands and edits under that top-level src directory, blocks root environment files and the root secrets directory, and asks before a push. It does not establish that npm run lint or any allowed command is harmless; it only avoids a Claude Code prompt for a matching tool call. Keep the allow list short enough that a reviewer can explain every entry.
Write rules that match what you mean
Rules use the form Tool or Tool(specifier). Bash(npm run build) matches one exact command. A wildcard can match a command family, but its position matters: Bash(git log *) limits the family to git log, while Bash(git *) permits every Git subcommand.
For file tools, paths use gitignore-style patterns. In project settings, Edit(/src/) is anchored to the primary working directory. An unanchored allow rule such as Edit(src/) instead covers src under the current directory, which can change during a session; a deny or ask rule with that same relative shape can match a src directory at any depth below the current directory. Use ~/ for a home-relative path or // for a filesystem-absolute path. Compound commands are checked as separate commands, so allowing an npm test command does not quietly approve an unrelated command after &&. See the official rule syntax.
Read deny rules are a Claude Code tool boundary, not an operating-system sandbox for shell commands. Protect secrets at the operating-system, repository, and service layers too; a tool rule should never be the only control around a credential.
Do not widen a rule just to stop prompts. A prompt is a signal that the task may need a narrower environment, a smaller outcome, or a human decision.
Use modes deliberately
In Manual (default) mode, file reads within allowed directories and a built-in set of read-only shell commands do not require approval; file modifications and other commands generally do unless a rule allows them. acceptEdits accepts file edits and common filesystem commands such as mkdir, touch, mv, and cp in the working directory or additional directories. plan reads files and runs read-only shell commands but does not edit source files; when Auto is available, classifier-approved commands also run. dontAsk denies unapproved tools and some tools that require user interaction even when allowed. auto uses background safety checks when available. Check the current mode details before changing modes.
bypassPermissions skips most permission prompts, including for protected paths; documented cross-session safeguards and actions that no mode auto-approves still apply. Do not use it for ordinary work. Isolation must actually limit access to host files, credentials, and services; a container name alone does not establish that. Organizations can set permissions.disableAutoMode or permissions.disableBypassPermissionsMode to "disable", especially in managed settings where users cannot override them.
When a rule surprises you, open /permissions. It shows each rule and its settings-file source. Claude Code also reports invalid or unknown permission rules at startup and through claude doctor; fix those diagnostics instead of assuming an allow, ask, or deny pattern took effect.
A less restrictive mode is not a substitute for a narrower task.
Separate coding-agent permissions from support-action approval
A Claude Code allow rule might let a coding agent run a terminal command. It does not give an eesel teammate permission to disclose account information, modify a ticket, or take another business action.
The eesel CLI lets a human, script, or coding agent inspect the same teammate and workspace that a support lead sees in the dashboard. It returns JSON, which makes a defined review easier to record and check.
Review a sensitive-account-data request
Suppose someone asks for a copy of an invoice to be sent to an email address other than the one on the account. Do not make a slash command decide whether to disclose the invoice. Use it to assemble evidence for the people who own that policy.
The support lead can inspect standing instructions and held actions in the dashboard. A developer or coding agent can run the same review in the terminal. The CLI needs Node.js 18.17 or newer. Authenticate and confirm the account and workspace first:
npx @eesel/cli login
npx @eesel/cli whoami
Stop if the workspace is wrong. Environment credentials can override a saved login, so verify the effective workspace rather than assuming login selected it. Then list teammates and assign the chosen real ID to the quoted variable below:
npx @eesel/cli agents
REVIEW_AGENT_ID="replace-with-selected-review-agent-id"
npx @eesel/cli status --agent "$REVIEW_AGENT_ID"
npx @eesel/cli instructions --agent "$REVIEW_AGENT_ID"
npx @eesel/cli approvals --agent "$REVIEW_AGENT_ID"
npx @eesel/cli activity --agent "$REVIEW_AGENT_ID"
Use --agent "$REVIEW_AGENT_ID" on every command in a multi-agent workspace. It takes precedence over a saved default for that invocation. For an unattended script, EESEL_API_URL and EESEL_API_TOKEN take precedence over stored browser login, and EESEL_AGENT_ID can select the teammate. Keep credentials out of source control and logs. CLI output is JSON by default: status reports sources and download state, instructions reads standing rules, approvals lists held actions, and activity shows recent work.
Put this bounded request in the skill:
Inspect the explicitly selected teammate for the support team's invoice-copy review. Read status, instructions, approvals, and activity. Compare standing instructions with the owner's required identity check; if an action is held, report its ID and reason without reproducing private account details. Separate missing evidence from contradictions. Do not send chat, approve an action, edit instructions, or disclose data. Return the questions the policy owner must decide.
That is deliberately modest. Claude Code gathers evidence and names questions; the support owner decides the policy and whether a held action should be approved. The owner should state the required identity check, who can approve an exception, where the decision is recorded, and what information may appear in the invoice copy. An empty approvals list means there is no held action at that moment; it does not mean sending an invoice is safe. Those are team policy choices, not facts for a coding agent to invent.
Test a proposed boundary without customer data
Use an owner-approved non-production teammate with consequential actions disabled for a test. Confirm that it is the intended test workspace before an evaluation or write, and never paste real account data into a terminal prompt. The coding agent can compare standing instructions with the support lead’s proposed boundary, but it should propose a change rather than make one.
If the owner chooses to add an approved policy document to that test teammate, authenticate to the test workspace and check whoami again. Stop unless it is the approved test workspace. Use agents to select the actual test ID, and check files upload --help before previewing the write:
npx @eesel/cli login
npx @eesel/cli whoami
After confirming the workspace and target:
TEST_AGENT_ID="replace-with-approved-non-production-agent-id"
npx @eesel/cli status --agent "$TEST_AGENT_ID"
npx @eesel/cli files upload ./owner-approved-invoice-disclosure-policy.pdf --agent "$TEST_AGENT_ID" --dry-run
whoami confirms account/workspace identity; status reports setup and download state. --dry-run prints the server call without sending it, not a prediction of policy compliance. With owner approval, the operator can remove the flag, then read files ls --agent "$TEST_AGENT_ID". An upload adds knowledge; it does not approve disclosure or replace action permissions. Any instruction change also needs approval and readback.
Get approval for billed chat before a fictional test. Start a fresh named conversation, keep consequential actions Disabled, and compare the reply with the owner's approved identity-check requirements. Inspect activity and held approvals using the same test target; do not approve a held action as part of evaluation. One answer is not proof that a policy works for every case, and a policy supplied directly in the question tests supplied context rather than persistent ingestion.
npx @eesel/cli new --name "invoice-disclosure-fictional-case" --agent "$TEST_AGENT_ID"
npx @eesel/cli chat "A requester wants an invoice sent to a different email address. What information is required before any disclosure?" --agent "$TEST_AGENT_ID"
A reviewable permission checklist
- Does the rule grant only the tool and scope needed?
- Is a deny or ask rule needed for an exception?
- Can a reviewer tell whether a rule governs Claude Code, the support teammate, or both?
- For sensitive data, is there an explicit owner and recorded approval boundary?
- Can the team inspect the result in the dashboard or structured CLI output?
The goal is not maximum autonomy. It is a workflow where the next action has a clear owner and evidence.
Try eesel CLI for support reviews
For a support teammate your team can inspect from both the dashboard and a terminal, Try eesel. Start with a read-only review of instructions, held approvals, and activity before the owner expands any workflow.

Frequently asked questions
What are Claude Code permissions?
They decide whether Claude Code can use a tool without a prompt, must ask first, or cannot use it. They are enforced by Claude Code, not by a prompt or CLAUDE.md.
Which Claude Code permission rule wins?
Rules are evaluated in this order: deny, ask, then allow. A matching deny blocks a call even when a narrower allow also matches; a matching ask still prompts when an allow matches.
Where should a team store Claude Code permission rules?
Use project settings for a shared policy, user settings for a personal default, and managed settings for organization policy. Review project allow rules through the workspace-trust flow before accepting them.
Does allow-listing Bash make every shell command safe?
No. Scope each rule to the command family you intend to permit and keep explicit deny or ask rules for exceptions. Tool access does not decide the business meaning of a command.
Should I use bypassPermissions for normal development?
No. It skips prompts, including for protected paths. Use it only in an isolated container or VM where the session cannot damage your system.







