Claude Code Security Settings: Permissions, Secrets, and Production Safety
Set up Claude Code permissions, secret handling, sandboxing, and production guards with current, copy-ready examples.
You ask Claude Code to diagnose a failed API request and accidentally expose the real token in .env. You ask it to remove generated files and discover that a useful directory disappeared too. Neither outcome requires malicious intent. An ambiguous task plus broad access is enough.
I found the same kind of problem in an earlier version of this article: its copy-ready settings contained path rules that current Claude Code does not match. Security guidance with a broken boundary is worse than no example at all, so I rechecked every rule against the official documentation and executable tests on July 21, 2026.
This guide gives a beginner one secure starting point. The core idea is defense in depth: permissions decide what Claude Code may request, Git keeps secrets out of history, the sandbox restricts Bash subprocesses, and application code guards production writes.
What to take away
- Start in
defaultmode and review edits and non-read-only shell commands. - Deny both
ReadandEditaccess to.envandsecrets/. - Use
Read(path)andEdit(path)for path rules, notGlob(path)orWrite(path). - Do not rely on one compound pattern such as
curl * | bash; denycurlandwgetseparately. - Treat permission rules and the OS sandbox as complementary controls.
- Enforce production-write conditions in code, then test both the denied and allowed paths.
What Claude Code can do, and what a human must decide
Delegate work that can be reviewed and reversed. Claude Code can inspect non-sensitive files, propose a patch, run local tests, and summarize the diff. A human should decide whether to reveal credentials, install a package, grant IAM access, push a branch, deploy, or modify production data.
| Work | Claude Code’s role | Human decision |
|---|---|---|
| Source and log investigation | Inspect redacted inputs | Define what data is safe to expose |
| Code edits and tests | Implement and report results | Review the diff and evidence |
| Dependency changes | Propose a package and explain why | Verify the package, maintainer, and permissions |
| Push and deployment | Show the target, commands, and diff | Approve the target and release |
| Production data changes | Do not execute by default | Confirm backup, scope, and rollback |
The security boundary should not depend on the model deciding that an operation “looks safe.” Operations that require judgment should stop for judgment.
1. Start with default permission mode
In default mode, reads within the working directory are generally available without a prompt. File modifications and normal shell commands require approval. A beginner does not need a broad allow list to make Claude Code useful.
{
"permissions": {
"defaultMode": "default"
}
}
When multiple rules match, Claude Code evaluates deny, then ask, then allow. A deny rule therefore remains effective even if a broader allow rule also exists. See the official permission reference for the current pattern syntax.
Auto mode uses a separate classifier, but the official documentation describes it as a research preview rather than a safety guarantee. Do not replace review with auto mode for customer data, shared infrastructure, or production. bypassPermissions skips the permission layer entirely and belongs only in a disposable, isolated container or VM.
2. Keep secrets away from Git and file tools
Keep API keys outside source code and load them from environment variables. First stop Git from recording them.
.env
.env.*
!.env.example
*.pem
*.key
*-service-account.json
secrets/
Then block Claude Code’s built-in file tools. Current file permission checks match path-qualified Read(path) and Edit(path) rules. Path-qualified Glob(path), Write(path), and NotebookEdit(path) rules are accepted by the settings parser but do not enforce the intended path boundary.
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(secrets/**)",
"Edit(.env)",
"Edit(.env.*)",
"Edit(secrets/**)"
]
This is not an operating-system boundary. Read and Edit rules cover built-in file tools and recognized file commands, but they cannot stop an arbitrary Node.js or Python subprocess from opening the same file. Use the sandbox in section 4 when a secret must be unreachable from Bash child processes too.
Do not print secret values into logs or prompts:
const token = process.env.QIITA_TOKEN;
if (!token) {
throw new Error("QIITA_TOKEN is missing. Check your local environment file.");
}
// Bad: console.error(`Authentication failed: token=${token}`);
console.error("Authentication failed. Check the QIITA_TOKEN configuration.");
Redact API keys, cookies, customer records, and production database URLs before pasting logs into a session. Claude Code normally needs the error type, request shape, file name, and reproduction steps, not the live credential.
3. Deny dangerous operations one command at a time
An earlier version of this guide used Bash(curl * | bash) to block downloaded scripts from being piped into a shell. That is not a reliable boundary. Claude Code parses compound commands into subcommands, and Bash argument patterns are fragile around variables, options, and alternate spellings.
For a conservative starting point, deny network download commands themselves. Route approved HTTP reads through domain-scoped WebFetch rules instead.
"deny": [
"Bash(rm *)",
"Bash(rmdir *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(curl *)",
"Bash(wget *)",
"PowerShell(Remove-Item *)",
"PowerShell(git push --force *)",
"PowerShell(git reset --hard *)"
]
Blocking every rm is restrictive. That is intentional for a first setup. Relax a rule for a specific project only after you understand the operation it enables. For stronger URL control, combine WebFetch(domain:example.com), a PreToolUse hook, and the sandbox network allowlist.
Document the intent in CLAUDE.md as well, but do not mistake instructions for enforcement:
## Safety rules
- Do not read .env or secrets/. Ask a human when a value is required.
- Do not delete files, force-push, or update production data.
- Do not execute a downloaded script before its source and contents are reviewed.
The prose shapes behavior. The deny rule or hook supplies the hard stop.
4. Isolate Bash child processes with the sandbox
Permissions control which tools Claude Code can invoke. Sandboxing controls which files and network destinations a Bash process and its children can reach. The two layers solve different problems.
On macOS, Linux, and WSL2, run /sandbox inside Claude Code and choose the appropriate mode. Native Windows sandboxing is not supported as of July 21, 2026, so Windows users need WSL2 or an isolated container.
An organization that requires the sandbox as a hard gate can use managed settings like these:
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"autoAllowBashIfSandboxed": false,
"allowUnsandboxedCommands": false
}
failIfUnavailable prevents Claude Code from starting when the sandbox cannot initialize. allowUnsandboxedCommands: false disables the escape hatch that can retry a failed command outside the sandbox. Do not paste this block into a native Windows configuration: it will fail because the platform cannot provide the sandbox. The official sandbox documentation is the source of truth for supported platforms and current keys.
5. Review dependencies and validate external input
A generated package name may be one character away from the real dependency. Put package installation and repository publication behind confirmation:
"ask": [
"Bash(npm install *)",
"Bash(npm uninstall *)",
"Bash(git commit *)",
"Bash(git push *)"
]
Commit the lockfile and verify known vulnerabilities mechanically:
npm ci
npm audit --audit-level=high
Generated application code must also distrust user input and API responses. Validate at the boundary before the value reaches a database or shell:
import { z } from "zod";
const Payload = z.object({
email: z.string().email(),
amount: z.number().int().positive().max(100000),
});
const safe = Payload.parse(await req.json());
Only safe moves into later processing. Invalid types and out-of-range values stop before they become a query or command.
6. Guard production writes in application code
A confirmation message is not a guard. The code must evaluate the approval flag. This example exits only when all three conditions are true: the environment is production, the command requests a write, and explicit production approval is missing.
// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
const args = new Set(process.argv.slice(2));
const wantsWrite = args.has("--write");
const forceProduction = args.has("--force-production");
if (env === "production" && wantsWrite && !forceProduction) {
console.error("Production writes require --force-production.");
process.exit(1);
}
console.log("guard passed");
The flag is a final confirmation, not authorization by itself. Use separate production credentials, make a backup, display the exact target, and test rollback before applying a destructive change.
Three real workflows
Debugging a customer-facing SaaS integration
A Stripe or Google Workspace log can include customer email addresses and tokens. Give Claude Code redacted logs and reproduction steps. Keep credentials in environment variables, and require approval for any API mutation.
Changing AWS, GCP, or Azure infrastructure
Delegate Terraform edits and plan. Keep apply and IAM grants under human review. Separate development and production identities, and put production changes behind a CI approval step.
Publishing articles or product pages automatically
Automate drafts, link checks, and builds. Publish only after the changed-file list, build result, and destination URL are known. Keep bulk deletion and large redirect changes outside the unattended path.
Copy-ready starter settings
Use this .claude/settings.json on an individual workstation, including native Windows. Add the sandbox block separately only on a supported operating system.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"ask": [
"Bash(npm install *)",
"Bash(npm uninstall *)",
"Bash(git commit *)",
"Bash(git push *)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(secrets/**)",
"Edit(.env)",
"Edit(.env.*)",
"Edit(secrets/**)",
"Bash(rm *)",
"Bash(rmdir *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(curl *)",
"Bash(wget *)",
"PowerShell(Remove-Item *)",
"PowerShell(git push --force *)",
"PowerShell(git reset --hard *)"
]
}
}
Claude Code changes frequently. The path-rule behavior described here requires v2.1.208 or later. Run claude --version and update an older installation before relying on this configuration.
Pitfalls and corrections
| Pitfall | Why it fails | Correction |
|---|---|---|
Allowing Glob(**) | Path-qualified Glob rules do not enforce the current file permission boundary | Use Read(path) |
Asking for Write(**) | Path-qualified Write rules do not match file permission checks | Use Edit(path) or the default edit prompt |
Denying only Bash(curl * | bash) | A compound string is a fragile command boundary | Deny Bash(curl *) and Bash(wget *) |
Treating .env deny as complete isolation | Arbitrary Node/Python subprocesses are outside that file-tool boundary | Add the OS sandbox on a supported platform |
| Printing a required production flag without checking it | The implementation may always block or always pass | Test denied, approved, and development paths |
Running bypassPermissions on a workstation | It skips permission prompts and safety checks | Restrict it to disposable isolated environments |
Preflight checklist
-
.envand key files are ignored by Git. - Both
ReadandEditdeny secret paths. - Deletion, force-push, and network download commands are denied.
- Package installation, commit, and push require human review.
- Development and production identities are separate.
- Sandboxing is enabled on a supported platform when the threat model requires it.
- The production guard passes denied, approved, and development tests.
- Logs and prompts contain no live credentials or customer data.
For a structured next step, use the Claude Code learning materials as the single starting point. They connect individual setup guidance to team rollout and consultation when the boundary design affects production work.
What I tested
On July 21, 2026, I parsed the JSON example and executed the production guard in three conditions. Production with --write returned exit code 1; production with --write --force-production returned 0; development with --write returned 0. I also added an automated content check that rejects the obsolete Glob(**), Write(**), and Bash(curl * | bash) examples before deployment. Native Windows cannot provide Claude Code’s OS sandbox, so the operational recommendation there remains WSL2 or an isolated container.
Related Posts
7 Claude Code Security Failure Cases: Causes, Recovery, Prevention
Prevent Claude Code .env leaks, production DB damage, CI cost spikes, and prompt injection with practical guardrails.
Avoid Dangerous Claude Code Prompts: Stop Auto Pushes, Skipped Tests, and Vague Fixes
Turn risky Claude Code requests into safer prompts with permission boundaries, review steps, and copy-paste checklists.
Where to Draw the Line: Claude Code Approvals and Sandbox in Daily Work
Split allow/ask/deny, pick the right permission mode, avoid dangerously-skip-permissions, and learn when a sandbox actually helps.
Free PDF: Claude Code Cheatsheet
Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.
We handle your data with care and never send spam.
Level up your Claude Code workflow
Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.
About the Author
Masa
Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.
Related Products
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.