Claude Code runs shell commands, edits files and calls MCP tools with the developer's own credentials, so a misread task or an injected instruction acts with everything that developer can reach. Anthropic ships a deep set of controls for this: six permission modes including a classifier-reviewed auto mode, deny-first permission rules, OS-level sandboxing, workspace trust, managed settings that users cannot override, managed MCP allowlists, OpenTelemetry export and isolated cloud sessions. This guide explains how those controls fit together, which settings an enterprise should enforce, how to monitor usage, and where the controls stop. It is for platform, endpoint and security engineering teams rolling Claude Code out to developers. All product details come from Anthropic's Claude Code documentation as checked on 27 October 2026; the product changes often, so confirm version-specific behaviour against the docs. For the category view across coding agents, see the AI IDE and Coding Agent Security Guide.
Key takeaways
- Permission prompts are not a security boundary on their own. The working directory limit is a prompt, so an approved Bash command can write anywhere the user can; OS-level sandboxing is what enforces filesystem and network limits.
- Auto mode changes the default. Auto mode is now the built-in starting mode for terminal and VS Code sessions on recent versions: a classifier, not the developer, approves most actions. Decide deliberately whether to keep it, tune it or disable it with
permissions.disableAutoMode. - Enforce through managed settings. Managed settings sit above user, project and command line settings. Lock bypass mode, permission rules, hooks, MCP servers and telemetry there, not in repository files.
- The developer's credentials are the blast radius. The sandbox leaves
~/.sshand~/.aws/credentialsreadable by default; deny reads to credential paths and keep long-lived cloud keys off developer machines. - MCP servers are unaudited code. Anthropic states it does not security-audit MCP servers. Use
managed-mcp.jsonor a URL and command allowlist withallowManagedMcpServersOnly.
How identity and access work in Claude Code
Two identities matter: the account Claude Code uses to reach the model, and the local user account whose permissions every tool call inherits.
Model access credentials
Developers sign in with a Claude for Teams or Enterprise account (SSO through claude.ai), a Claude Console account, a cloud provider (Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry) or a self-hosted Claude apps gateway that signs users in with the corporate identity provider. When several credentials are present, Claude Code uses them in this order:
| Order | Credential | Security note |
|---|---|---|
| 1 | Cloud provider credentials (CLAUDE_CODE_USE_BEDROCK, _VERTEX, _FOUNDRY) | Governed by the cloud provider's IAM policies |
| 2 | ANTHROPIC_AUTH_TOKEN | Bearer token, typically for an LLM gateway |
| 3 | ANTHROPIC_API_KEY | Static key; in -p (non-interactive) mode it is always used when present |
| 4 | apiKeyHelper script output | Preferred for short-lived keys fetched from a vault |
| 5 | CLAUDE_CODE_OAUTH_TOKEN | One-year token from claude setup-token for CI; treat as a secret |
| 6 | Anthropic profile and Workload Identity Federation credentials | Federation avoids static secrets in pipelines |
| 7 | Subscription OAuth from /login | Default for Pro, Max, Team and Enterprise |
A signed-in Claude apps gateway session sits outside this list and outranks the providers. Locally stored credentials go to the macOS Keychain, or to ~/.claude/.credentials.json with mode 0600 on Linux. To stop developers using personal accounts, set forceLoginMethod and forceLoginOrgUUID in managed settings, and allowedProviders to limit which inference services a machine may reach. Under these keys, sessions that rely on ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN or apiKeyHelper are blocked at startup. Note that claude setup-token and /install-github-app enforce only forceLoginMethod, so they can mint a token in a different organisation. Enterprise identity controls are covered in the Claude for Enterprise Security Guide.
Local permissions: modes and rules
| Mode | Behaviour | Use it for |
|---|---|---|
default (Manual) | Prompts on first use of each tool; read-only commands such as ls and git status run without asking | Sensitive repositories, new users |
acceptEdits | Auto-accepts file edits and common filesystem commands (mkdir, mv, cp) inside the working directories | Trusted repositories with review before commit |
plan | Reads and explores; does not edit source files | Analysis and design work |
auto | A background classifier checks shell commands, network requests and similar actions against the user's request; blocked actions are reported back | Day-to-day work where prompt fatigue is the bigger risk |
dontAsk | Auto-denies anything that would prompt; only pre-approved tools run | Locked-down automation |
bypassPermissions | Skips prompts, including writes to protected paths such as .git and .claude | Only isolated containers or VMs, per Anthropic's own warning |
Permission rules use allow, ask and deny lists with specifiers such as Bash(git push *), Read(./.env), WebFetch(domain:github.com) and mcp__github__create_issue. Rules are evaluated deny, then ask, then allow, and a deny at any settings level cannot be overridden by any other level, including --allowedTools. A bare tool name in deny (for example WebFetch) removes the tool from Claude's context entirely. Allow rules in a project's .claude/settings.json only apply after the user accepts the workspace trust dialog; deny and ask rules apply immediately because they only restrict.
How the auto mode classifier decides
- Rules first: explicit allow, ask and deny rules resolve before the classifier, except that writes to protected paths still go to the classifier and recognised critical-path
rmremovals are never auto-approved. - Approved outright: read-only actions and file edits in the working directory.
- Broad rules dropped: on entering auto mode, allow rules that grant arbitrary code execution, such as
Bash(*), wildcarded interpreters likeBash(python*)andAgentrules, are suspended. - Blocked by default: download and execute (
curl | bash), sending sensitive data to external endpoints, production deploys and migrations, granting IAM or repository permissions, force push,terraform destroy, merging an unreviewed pull request and printing a live credential into the transcript. - Allowed by default, worth reviewing: reading
.envand sending credentials to their matching API, and pushing to any non-deploy branch of the working repository. - Back-off: after 3 consecutive or 20 total blocks in a session, auto mode pauses and prompting resumes.
Instructions given in conversation ("don't push") are treated as signals the classifier re-reads, but they can be lost when context is compacted. A deny rule is the hard guarantee. The autoMode.environment setting lets administrators describe trusted infrastructure so routine actions are not blocked.
Admin roles and privileged access
Administrative control lives in managed settings, delivered four ways and ranked highest first:
- Server-managed settings from the claude.ai admin console (or a Claude apps gateway), fetched at startup and polled hourly. These reach only accounts already signed in to the organisation, so they cannot redirect a first login.
- MDM or OS policy: macOS configuration profile in the
com.anthropic.claudecodedomain, or a WindowsSettingsvalue underHKLM\SOFTWARE\Policies\ClaudeCode, checked every 30 minutes. - Managed settings files:
managed-settings.jsonplusmanaged-settings.d/*.jsonin/Library/Application Support/ClaudeCode/(macOS),/etc/claude-code/(Linux and WSL) orC:\Program Files\ClaudeCode\(Windows). - HKCU registry on Windows, used only when no admin source is present. It is user-writable, so it is not an enforcement point.
Keys that only a managed source can set include allowManagedPermissionRulesOnly (managed settings become the only source of permission rules), allowManagedHooksOnly, allowManagedMcpServersOnly, strictKnownMarketplaces (which plugin marketplaces users can install from) and sandbox.network.allowManagedDomainsOnly. Invalid values for single-value lock keys fail closed. Anthropic notes that a developer with local administrator rights can edit the managed source itself, so redeploy policy on a schedule through MDM and treat local admin rights as a privileged exception. In the Claude Console, assign the Claude Code role (can only create Claude Code API keys) rather than Developer (any API key) to people who only need the CLI.
Integrations, API tokens and service accounts
MCP servers
| Pattern | Configuration | When to choose it |
|---|---|---|
| Disable MCP | managed-mcp.json with {"mcpServers": {}} | Regulated environments before an MCP review process exists |
| Fixed deployment | managed-mcp.json listing approved servers | Small, stable set of internal and vetted servers |
| Approved catalogue | allowedMcpServers plus allowManagedMcpServersOnly: true | Larger organisations that let teams choose from a reviewed list |
| Provided servers | managedMcpServers in managed settings (HTTPS remote servers only) | Give everyone a standard set while keeping user choice |
| Denylist only | deniedMcpServers | Minimum control; blocks known-bad servers |
Match servers by serverUrl or exact serverCommand. Anthropic warns that serverName entries are not a security control because users choose the label. A denylist match always wins. Do not put API keys in managed-mcp.json env blocks, because any user on the machine can read the file; use OAuth, per-user ${VAR} expansion or headersHelper. Project .mcp.json servers need their own approval prompt in interactive sessions, but a claude -p run shows neither the trust dialog nor that prompt. Compare the Amazon Q MCP configuration vulnerability, where repository MCP definitions ran without consent and inherited the developer's AWS credentials. See the MCP Gateway and MCP Server Governance Guide.
CI and automation identities
- Pipelines: prefer Workload Identity Federation or cloud provider roles over
CLAUDE_CODE_OAUTH_TOKENor a staticANTHROPIC_API_KEY; if a token is unavoidable, store it in the CI secret store and rotate it before its one-year expiry. - Repository tokens: the GitHub or GitLab token a pipeline gives Claude Code should be scoped to one repository with branch protection in force.
- Tokens in the codebase: agents search the repository when stuck. The PocketOS database deletion happened when a coding agent found an account-scoped platform token and used it against production. Keep tokens out of repositories and use Read deny rules for files that hold them.
Cloud sessions
Anthropic-hosted cloud sessions run in an isolated VM per session, with network access limited by default and configurable to none or an allowlist of domains. GitHub credentials stay encrypted on Anthropic's servers: the VM holds a short-lived, session-scoped credential and a proxy attaches the real credential server-side. The proxy rejects branch deletions and pushes of anything other than a branch, and GitHub applies your branch protection rules and rulesets, so a rule your connected access can bypass will not block a push. Self-hosted environments move isolation, egress and git credentials to your own deployment.
Sandboxing
The sandbox restricts Bash, PowerShell and Monitor commands and their child processes at the operating system level: Seatbelt on macOS, bubblewrap with a separate network namespace on Linux and WSL2. Native Windows is not sandboxed, so Windows users need WSL2. It is off by default (sandbox.enabled).
| Setting | Recommended value | Why |
|---|---|---|
sandbox.enabled | true | OS enforcement survives a prompt injection that fools the model |
sandbox.failIfUnavailable | true | Exit instead of silently running unsandboxed |
sandbox.allowUnsandboxedCommands | false | Stops the dangerouslyDisableSandbox retry path |
sandbox.filesystem.denyRead | Credential paths such as ~/.ssh, ~/.aws, ~/.config/gcloud | By default the sandbox can read most of the machine, including these |
sandbox.network.allowedDomains | Package registries and source hosts you use | Starts empty; the proxy also blocks link-local addresses such as 169.254.169.254 |
sandbox.network.allowManagedDomainsOnly | true in managed settings | Users cannot widen egress |
sandbox.excludedCommands | Narrow, specific patterns only | Excluded commands run with full access; docker * lets Claude run a compose file outside the sandbox |
The default proxy filters by hostname and does not inspect TLS, so an allowlisted domain that hosts user content is an exfiltration path. For stronger isolation, run the whole process in a dev container or VM. See the AI Agent Sandboxing and Code Execution Guide.
Logging and detection
Telemetry is off until CLAUDE_CODE_ENABLE_TELEMETRY=1. Set it with the OTLP exporter variables in the managed settings env block so repositories cannot redirect it; repository settings cannot set exporter variables, and a managed endpoint or credential removes developer-set ones.
| Signal | What it gives the SOC |
|---|---|
claude_code.tool_decision event | Each accept or reject with source (config, hook, user_permanent, user_temporary, user_reject), permission_mode and classifier_verdict |
claude_code.tool_result event | Tool name, success, duration; with OTEL_LOG_TOOL_DETAILS=1 also Bash commands and MCP server and tool names |
claude_code.api_request and api_error | Model, cost and token counts per request, for spend anomalies |
claude_code.safety_event | Safety events (v2.1.307 and later) |
| Standard attributes | user.email, user.account_uuid, organization.id, session.id on every event |
Prompt text and tool details are redacted by default (OTEL_LOG_USER_PROMPTS, OTEL_LOG_TOOL_DETAILS). Enabling them improves investigations but sends source and secrets-adjacent content to your collector, so decide with your privacy team. ConfigChange hooks can audit or block settings changes during a session, and PreToolUse hooks can add checks but cannot bypass deny or ask rules.
Metrics that show the controls work
- Managed coverage: percentage of active Claude Code users whose
/statusshows a managed source (plist, HKLM or file). - Bypass usage: sessions in
bypassPermissionsoutside approved containers, target zero. - Classifier blocks: auto mode rejections per 1,000 tool calls, investigated by category (for example data exfiltration).
- Unapproved MCP attempts: policy-blocked MCP server adds per week.
- Credential exposure: developer machines with long-lived cloud keys in
~/.aws/credentials, trending down.
Hardening baseline
A starting managed policy for most organisations, rolled out in phases:
- Pilot (weeks 1 to 2): deploy
managed-settings.jsonto a pilot group withforceLoginMethod,forceLoginOrgUUID,permissions.disableBypassPermissionsMode: "disable", telemetry export and a deny list for credential files (Read(~/.ssh/**),Read(./.env),Read(./secrets/**)). - Sandbox (weeks 3 to 4): enable the sandbox with
failIfUnavailable, credentialdenyReadpaths and a domain allowlist; collect blocked domains from the pilot and add only what is needed. - MCP (weeks 4 to 6): move to an approved catalogue with
allowManagedMcpServersOnly, ormanaged-mcp.jsonfor a fixed set. - Auto mode decision: keep auto mode with
autoMode.environmenttuned for trusted infrastructure, or setpermissions.disableAutoMode: "disable"for regulated repositories. Add deny rules for actions that must never happen (Bash(git push --force *), production deploy commands). - Lock and expand: set
allowManagedPermissionRulesOnlyandallowManagedHooksOnlyonce the rule set is stable, then roll out to all developers. - Rollback: because managed settings are central, rollback is a policy change: revert the file or console setting, confirm with
/statusandclaude doctor, and record the exception.
Small teams can do most of this with server-managed settings from the admin console. Large organisations should deliver through MDM, because only device-delivered keys govern first login and some keys (such as allowClaudeInChromeWithManagedMcp) are read only from device sources.
Framework mapping
| Control area | Claude Code feature | NIST SP 800-53 Rev. 5 | Threat (ATLAS / OWASP) |
|---|---|---|---|
| Least privilege for agent actions | Permission rules, modes, disableBypassPermissionsMode | AC-6 Least Privilege; CM-7 Least Functionality | OWASP LLM06 Excessive Agency |
| Configuration enforcement | Managed settings and lock keys | CM-6 Configuration Settings | AML.T0051.001 Indirect prompt injection |
| Egress and isolation | Sandbox network allowlist, cloud session VMs | SC-7 Boundary Protection | AML.T0098 AI Agent Tool Credential Harvesting |
| Credential handling | apiKeyHelper, federation, Read deny rules | IA-5 Authenticator Management | AML.T0098 |
| Tool supply chain | Managed MCP, strictKnownMarketplaces | SR-3 Supply Chain Controls and Processes | AML.T0010.005 AI Agent Tool |
| Monitoring | OpenTelemetry events and metrics | AU-2 Event Logging | All of the above |
In NIST CSF 2.0 terms these sit in PR.AA (identity and access), PR.PS (platform security) and DE.CM (continuous monitoring).
Common misconfigurations
- Policy in the repository, not in managed settings. Project
defaultModevalues ofautoorbypassPermissionsare ignored, but allow rules and MCP servers in a trusted repository still load. Enforcement belongs in managed settings. - Treating the working directory as a boundary. It is a prompt in Manual mode, not an OS control; without the sandbox, an approved command can write anywhere.
- Sandbox on, credentials readable. Leaving
~/.sshand cloud credential files readable lets an injected command collect them, as the Sentry MCP agentjacking research showed for coding agents generally. - MCP allowlist by name.
serverNameentries can be spoofed by relabelling a server; useserverUrlandserverCommand. - Headless runs with no trust checks.
claude -pon an untrusted clone shows no trust dialog or MCP approval; run it only on reviewed code, inside a container. - Accounts outside the organisation. Without
forceLoginOrgUUID, a developer can use a personal subscription and your logging and data terms do not apply. Anthropic's GTG-1002 report also shows attackers running Claude Code with MCP tools themselves, so egress controls and EDR still matter on developer endpoints.
Practitioner checklist
- Deliver managed settings through MDM or system files, and confirm the source in
/statuson sample machines. - Set
forceLoginMethod,forceLoginOrgUUIDandallowedProviders. - Disable
bypassPermissionseverywhere except approved containers. - Decide on auto mode per repository class and add deny rules for irreversible actions.
- Enable the sandbox with
failIfUnavailable, credentialdenyReadpaths and a managed domain allowlist. - Restrict MCP with
managed-mcp.jsonor a URL and command allowlist locked byallowManagedMcpServersOnly. - Restrict plugin sources with
strictKnownMarketplacesand lock hooks withallowManagedHooksOnly. - Export OpenTelemetry to the SIEM and alert on rejected tool decisions, bypass mode and new MCP servers.
- Replace static API keys and setup tokens in CI with federation or cloud roles.
- Remove long-lived tokens from repositories and developer home directories.
Standards and references
- Anthropic: Claude Code Security
- Anthropic: Configure permissions
- Anthropic: Permission modes
- Anthropic: Sandboxing
- Anthropic: Deploy managed settings
- Anthropic: Control MCP server access for your organization
- Anthropic: Monitoring usage with OpenTelemetry
- OWASP: Top 10 for LLM Applications 2025
Related NHI Mgmt Group resources: AI IDE and Coding Agent Security Guide · AI Coding Agents Security Guide · Claude for Enterprise Security Guide · MCP Security Guide · Coding Agent Configuration File Attacks