What does securing Claude Code in the enterprise involve?
To secure Claude Code in the enterprise, deploy hooks through Claude Code's managed settings so that every session sends each tool call, prompt, and model switch to a policy service before it runs. Managed settings take precedence over anything a developer configures. Lockdown keys stop developers adding their own hooks or permission modes that work around yours. Then record sessions through OpenTelemetry or the Claude Compliance API to find the ones your hooks missed.
Claude Code runs shell commands, edits files, fetches URLs, and calls Model Context Protocol (MCP) servers on a developer's machine or in a cloud environment, using that developer's credentials. It fires hooks, configuration entries that run at set points in its lifecycle, including before a tool call, before a prompt reaches the model, and before a model switch. A hook can be an HTTP endpoint, and Arcjet is that endpoint. Arcjet decides each tool call, prompt, and model switch against your policies before Claude Code acts, with no agent process, proxy, or SDK to install. The same policy covers GitHub Copilot, Cursor, and OpenAI Codex, so you don't maintain Claude Code rules separately. Arcjet evaluates at the edge in over 300 data centers, so the added latency stays small, and every session and decision appears in the Arcjet Console. For the model that all four supported agents share, see How do you secure AI coding agents?.
Where do Claude Code hooks go: managed settings, MDM, or the repository?
Managed settings are configuration that an administrator deploys and that sits in the top precedence tier, above every setting a developer can write. Claude Code has two channels for them. IT deploys endpoint-managed settings to a device, and Claude Code fetches server-managed settings from the claude.ai console. A committed repository file is a third option, suitable for a pilot.
| Mechanism | Where the JSON goes | Reaches | Removable by a developer |
|---|---|---|---|
| Managed settings file | /etc/claude-code/managed-settings.json (Linux, WSL), /Library/Application Support/ClaudeCode/managed-settings.json (macOS), or C:\Program Files\ClaudeCode\managed-settings.json (Windows) | That device: the terminal, IDE extensions, the desktop Code tab, and Agent SDK sessions | Local administrator only |
| MDM or OS policy | macOS com.anthropic.claudecode managed preferences, or Windows HKLM\SOFTWARE\Policies\ClaudeCode, value Settings | The same surfaces, redeployable on a schedule | Local administrator only |
| Server-managed settings | claude.ai console, Admin settings > Claude Code > Managed settings | Every session that authenticates with an eligible credential | Only by switching provider |
| Repository settings | .claude/settings.json, committed | Sessions in that repository | Yes |
The file is JSON in every case, and the Arcjet template works in each of them. Deploy the managed settings file or the macOS or Windows policy through the mobile device management (MDM) tooling you already run. Use server-managed settings to reach sessions on devices you don't manage, as long as they authenticate with an eligible credential.
What does a Claude Code hook entry look like?
Each hook entry is an HTTP request to Arcjet with the event name in the URL. The following excerpt shows the PreToolUse entry from the Arcjet template. The full template installs every enforcement point plus the activity hooks, so Arcjet records the whole session.
{ "hooks": { "PreToolUse": [ { "hooks": [ { "type": "http", "url": "https://decide.arcjet.com/v1/agent-hooks/claude-code?event=pre-tool-use", "headers": { "Authorization": "Bearer $ARCJET_KEY", "X-Arcjet-Principal": "$USER" }, "allowedEnvVars": ["ARCJET_KEY", "USER"], "timeout": 5 } ] } ] }}The template has no matcher, so every tool call reaches the policy. A matcher that lists some tools leaves the rest outside it. The hook file never names a policy. You attach policies to events in the Arcjet Console, and a change there takes effect in real time without touching the file on any device.
X-Arcjet-Principal attributes a session to a developer. It's untrusted metadata, because no hook payload carries an authenticated identity. $USER is unset on Windows, so use $USERNAME there and add it to both allowedEnvVars lists.
You can put the Arcjet key in an env block in the same settings file, or as a literal header value. Claude Code applies env to every subprocess it starts, so any command the agent runs can read the key. A literal header value never enters the agent's environment, so prefer it in a root-owned managed settings file.
Can a developer or local administrator bypass Claude Code hooks?
A developer without administrator rights can't remove a managed hook. The following lockdown keys also stop them adding hooks or modes that work around yours:
{ "allowManagedHooksOnly": true, "permissions": { "disableBypassPermissionsMode": "disable" }, "allowedHttpHookUrls": ["https://decide.arcjet.com/*"]}Hook entries merge across settings levels, so without allowManagedHooksOnly a developer's own hooks run alongside yours. disableBypassPermissionsMode keeps Claude Code's own permission flow in place.
A local administrator can edit or delete a device-level managed settings file or MDM profile. Server-managed settings don't depend on the device, but Claude Code skips the server-managed settings fetch in the following cases:
- The session exports a
CLAUDE_CODE_USE_*provider variable, such asCLAUDE_CODE_USE_BEDROCK,CLAUDE_CODE_USE_VERTEX, orCLAUDE_CODE_USE_FOUNDRY. - The session points
ANTHROPIC_BASE_URLsomewhere other than the Anthropic API.
Use endpoint-managed settings for configuration that must apply regardless of those variables. For how to cover a local administrator, see What do you pair with Arcjet on Claude Code?.
Do hooks apply to Claude Code on the web?
Yes. A cloud session, on Claude Code on the web or from claude --cloud, runs on a fresh clone of the repository in a cloud environment. It reads a committed .claude/settings.json and your organization's server-managed settings.
Cloud environments block Arcjet by default. Give the environment Custom network access and add decide.arcjet.com to Allowed domains, keeping the default list if your sessions install packages. The allowlist of domains is per environment. An Owner can create a shared environment with the right access level and make it the organization's default. A developer who runs a session in an environment of their own still has to allow the domain there.
What can a policy enforce on Claude Code?
Arcjet enforces policies on all three Execute on options in the Arcjet Console, because Claude Code honors a denial on each of them:
- Tool call:
PreToolUseandPermissionRequest. Policies here read the command, its tokens, file paths, URL hosts, and the MCP server and tool. - Prompt:
UserPromptSubmitandUserPromptExpansion. Policies here read the prompt text, including what a slash command expanded into, and can run prompt injection and sensitive information detection over it. - Model switch:
PreModelSwitch. A denial keeps the current model.
A denial names the rule ID, such as destructive-command. Start from the starter policies in the Arcjet Console, and run each in dry run to see what it would deny before it goes live. For the starter policies, see how to stop a coding agent running destructive commands, how to stop a coding agent reading .env files and credentials, and how to restrict which MCP servers a coding agent can use.
Arcjet answers from the edge, typically in a few tens of milliseconds, well inside the 5-second timeout. That matters because Claude Code built its HTTP hooks to fail open, as described in What do you pair with Arcjet on Claude Code?.
How do you restrict which models developers use in Claude Code?
An allowed-models policy is a normal Rego policy with a list of model IDs, attached to Model switch. On Claude Code, Arcjet denies a switch onto a model that isn't in the list, and the session keeps its current model. Claude Code sends the model only on PreModelSwitch, not on prompt or tool events, so pair the policy with Claude Code's own organization default or banned-model setting to cover a session that opens on a disallowed model. For the policy and its coverage on other agents, see how to restrict which models coding agents can use.
What do you pair with Arcjet on Claude Code?
Arcjet decides everything that reaches the hooks. Anthropic sets where the hooks reach, so pair Arcjet with the following controls:
- An observe-only backstop, for fail-open hooks. Claude Code built its HTTP hooks to let an action through on a timeout, a network error, or a non-2xx response, except on
PreModelSwitch, where a timeout blocks the switch. Arcjet keeps decisions inside the timeout by answering from the edge, and the backstop shows any session that ran without a decision. For more information, see Do coding agent hooks fail open?. - Claude Code's own model settings, for the opening model. An allowed-models policy decides each switch, and Claude Code's organization default or banned-model setting covers a session that starts on a disallowed model.
- Endpoint-managed settings, for third-party providers. Claude Code skips server-managed settings when a session uses a
CLAUDE_CODE_USE_*provider variable or a differentANTHROPIC_BASE_URL, and a device file still applies. - Network controls, for personal accounts. Personal Claude accounts on a corporate laptop reach neither the hooks nor the Claude Compliance API. For more information, see how to block personal AI accounts on work laptops.
OpenTelemetry and the Claude Compliance API are the backstop. Both record what Claude Code did, and Arcjet shows them in the same Arcjet Console views as hook decisions. Use them for discovery before you deploy hooks, and to confirm coverage afterward.
Claude Code exports its own OpenTelemetry logs to Arcjet through the env block of managed settings. With the Claude Compliance API, Arcjet polls Anthropic for your organization's activity and, with a Compliance Access Key, session transcripts, with no client configuration. The Compliance API covers your Anthropic organization's sessions except the following:
- Personal accounts.
- Claude Code authenticated with a Console API key.
- Claude Code run through Amazon Bedrock, Google Vertex AI, or Microsoft Foundry.
- Claude Code on the web.
Send the backstop to a separate Arcjet site from the hooks, so each session isn't ingested twice. A session that appears in the backstop with no hook decision is one your hooks didn't reach, such as a device where a local administrator changed the managed file. For setup, see Observe agent activity.
How do you check the hooks are installed?
Use Claude Code's own diagnostics, then confirm the session in Arcjet:
- Run
/statusin Claude Code. Setting sources names the managed source Claude Code selected, and Skipped sources names what it skipped. - Run
/hooksto list every configured hook with its source and URL. - Run
claude doctorfor the server-managed fetch outcome and any dropped entry. - In the Arcjet Console, open the site's Activity and confirm the session appears.
Where does Arcjet fit for Claude Code?
With Arcjet, every Claude Code tool call, prompt, and model switch is decided against your policy before it runs, on every device and cloud session your managed settings reach. Arcjet gives you the following capabilities:
- One policy across agents: the same Rego policies apply to Claude Code, GitHub Copilot, Cursor, and OpenAI Codex.
- Enforcement developers can't remove: you install Arcjet through managed settings or MDM, and lockdown keys stop developers working around it.
- Real-time policy changes: you edit policies in the Arcjet Console without touching any device, and dry run shows what a rule would deny before it goes live.
- Visibility and export: hook decisions, OpenTelemetry, and Claude Compliance API activity appear in the Arcjet Console, and decisions export to Datadog, Splunk, SentinelOne, Panther, and Amazon S3 (Enterprise plan).
To start, install the Arcjet Claude Code template on one device and confirm the session in Activity. Then publish the coding-agent.destructive-command starter policy in dry run and review what it would deny before you set it live.
Frequently asked questions
How do you secure Claude Code in the enterprise?
Deploy hooks through Claude Code's managed settings so every session sends each tool call, prompt, and model switch to a policy service before it runs. Set allowManagedHooksOnly and disableBypassPermissionsMode so developers can't work around them, and record sessions through OpenTelemetry or the Claude Compliance API to find any the hooks missed. Arcjet answers the hooks with one policy that also covers GitHub Copilot, Cursor, and OpenAI Codex, and you change it in the Arcjet Console in real time without touching any device.
Where does the Claude Code managed settings file live?
/etc/claude-code/managed-settings.json on Linux and WSL, /Library/Application Support/ClaudeCode/managed-settings.json on macOS, and C:\Program Files\ClaudeCode\managed-settings.json on Windows. MDM can deliver the same JSON through com.anthropic.claudecode managed preferences or the HKLM\SOFTWARE\Policies\ClaudeCode registry key.
Can a developer turn off Claude Code hooks deployed through managed settings?
Not without local administrator rights. Set allowManagedHooksOnly so a developer's own hooks don't run beside yours, and disableBypassPermissionsMode so Claude Code's permission flow stays in place. A local administrator can still edit the device file.
Do Claude Code hooks work in Claude Code on the web?
Yes. A Claude Code cloud session reads a committed .claude/settings.json and your server-managed settings. Give each cloud environment Custom network access and add decide.arcjet.com to its allowed domains.
How do I restrict which models developers use in Claude Code?
In the Arcjet Console, attach an allowed-models policy to the Model switch option. Claude Code denies a switch onto a model outside the list on PreModelSwitch. A session that starts on a disallowed model and never switches isn't stopped, so also use Claude Code's own organization default or banned-model setting.
AI runtime security in your code
Protect your AI agent workflows with Arcjet
Deploy the Arcjet hook template through Claude Code managed settings and see every session in the Arcjet Console.