Skip to main content

Security & Enterprise Administration

11 min read

What You’ll Learn

This chapter walks through the enterprise security and governance features you’ll need to deploy Claude Code across an organization. We’ll cover the security model behind every interaction, the five managed settings delivery mechanisms, the settings precedence hierarchy, and governance controls for permissions, hooks, MCP servers, and plugins. You’ll also learn how to enforce filesystem and network sandboxing, configure authentication controls, and use vulnerability scanning as a capability pattern, not a standalone feature.

By the end, you’ll be able to answer the question: “How do I deploy Claude Code securely at scale?”


Security Model Overview

Claude Code is built on a permission based architecture. Every potentially dangerous action (writing a file, running a shell command, calling an MCP tool) needs explicit approval before it runs. That means Claude Code can’t silently modify your codebase or execute commands behind your back.

The security model follows a defense in depth strategy with three layers:

  1. Built in protections. Command blocklists, context aware prompt injection detection, and isolated fetch contexts are always active. You can’t disable them.
  2. Configurable permissions. User facing permission rules that control which tools need approval, which can run automatically, and which are denied outright. See Models, Costs & Permissions for how the permission system works at the individual level.
  3. Enterprise governance. Managed settings that override all user and project configuration. This is the layer we’re focusing on here: the administrative controls that enforce security policy across an entire organization.

Each layer builds on the one below it. Built in protections are the floor nobody can lower. Configurable permissions let individuals tune their workflow. Enterprise governance sets the ceiling nobody can raise.


Managed Settings

Managed settings are the enterprise deployment mechanism for Claude Code. They override all user level and project level settings, so organizational security policies can’t be weakened by individual developers.

There are five delivery mechanisms, listed from highest to lowest priority:

1. Server managed. Fetched from Anthropic’s servers for authenticated enterprise users. When your organization configures Claude Code through an Anthropic enterprise agreement, settings are automatically pushed to every authenticated user. No local file distribution needed.

2. macOS MDM. Distributed via Apple Mobile Device Management profiles. IT admins can push Claude Code configuration as a managed preference domain using existing MDM infrastructure (Jamf, Kandji, Mosyle, or similar).

3. Windows registry (HKLM). Set via Group Policy or direct registry keys under HKEY_LOCAL_MACHINE. This piggybacks on the same distribution mechanism enterprise IT teams already use for Windows software configuration.

4. File based. A JSON file placed at a well known filesystem path. This is the most portable option and works on any platform. Typically it’s distributed via configuration management tools (Ansible, Chef, Puppet) or internal package management.

5. Windows HKCU. Per user registry settings under HKEY_CURRENT_USER. These have lower priority than HKLM settings, so organization-wide policies can override user level registry configurations.

Here’s a representative enterprise managed settings file that shows the key governance controls:

managed-settings.json
managed-settings.json
{
"permissions": {
"allow": [
"Read",
"Grep",
"Glob"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl * | bash)"
]
},
"allowManagedPermissionRulesOnly": true,
"allowManagedHooksOnly": true,
"allowManagedMcpServersOnly": true,
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/opt/company/hooks/audit-commands.sh"
}
]
}
]
},
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"network": {
"allowManagedDomainsOnly": true,
"allowedDomains": ["github.com", "*.npmjs.org", "internal.company.com"]
}
},
"forceLoginMethod": "console",
"forceLoginOrgUUID": "org-abc123"
}

A comprehensive enterprise configuration covering permissions, hooks, MCP, sandbox, and authentication.

Let’s walk through each governance control in detail.


Settings Precedence

Claude Code evaluates settings in a strict hierarchy, where higher priority settings always win:

  1. Managed settings (highest priority): enterprise deployed configuration
  2. CLI flags: command line arguments passed when launching Claude Code
  3. Local settings (.claude/settings.local.json): machine specific overrides, not committed to Git
  4. Project settings (.claude/settings.json): project wide configuration, committed to Git
  5. User settings (~/.claude/settings.json): personal defaults across all projects

Managed settings always take precedence. This is by design; it prevents developers from weakening enterprise security controls. A developer can’t override a managed allowManagedPermissionRulesOnly: true setting by adding permissive rules to their project or user configuration.

Want to verify things are working? The /status command shows which settings are active and where they come from. Run it after deploying managed settings to confirm the hierarchy is behaving as expected.

Checking active settings
Checking active settings
/status

Shows each setting, its current value, and which configuration layer it comes from.


Permission Governance

The allowManagedPermissionRulesOnly flag is your primary control for locking down permission rules across an organization.

When it’s set to true, only permission rules defined in managed settings apply. User level, project level, and local permission rules are all ignored. This gives you a consistent security posture across every developer’s machine, so nobody can sneak an "allow": ["Bash(*)"] rule into their personal settings.

managed-settings.json
managed-settings.json
{
"allowManagedPermissionRulesOnly": true,
"permissions": {
"allow": [
"Read",
"Grep",
"Glob",
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(git *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl * | bash)",
"Bash(chmod 777 *)"
]
}
}

Only these permission rules apply when allowManagedPermissionRulesOnly is true.

Any tool that isn’t explicitly allowed or denied follows the default behavior: Claude Code asks the user for permission at runtime. The allow list covers tools that run without prompting. The deny list blocks tools entirely. Everything else requires interactive approval.


Hook Governance

The allowManagedHooksOnly flag controls which hooks can execute. Set it to true, and only hooks defined in managed settings will run. Hooks from user settings, project settings, local settings, plugins, and skill/agent frontmatter are all ignored.

Why does this matter? It stops developers from installing hooks that could bypass security controls or exfiltrate data through hook commands.

Two additional settings give you fine-grained hook control:

  • allowedHttpHookUrls is a whitelist of HTTP endpoints that hooks are allowed to call. If a hook tries to send data to an endpoint not on this list, the request gets blocked.
  • httpHookAllowedEnvVars specifies which environment variables hook processes can access. This keeps hooks from reading sensitive environment variables like API keys or database credentials.
managed-settings.json
managed-settings.json
{
"allowManagedHooksOnly": true,
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "/opt/company/hooks/audit-file-changes.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "http",
"url": "https://telemetry.company.com/claude-sessions"
}
]
}
]
},
"allowedHttpHookUrls": [
"https://telemetry.company.com/*",
"https://hooks.company.com/*"
],
"httpHookAllowedEnvVars": [
"COMPANY_TEAM_ID",
"COMPANY_PROJECT_ID"
]
}

Hook governance: only managed hooks run, HTTP calls restricted to approved endpoints.

For more on hook lifecycle details, handler types, and exit code semantics, check out Hooks & Lifecycle Automation.


MCP Server Governance

Managed settings let you control which MCP servers can connect to Claude Code. This prevents developers from adding unauthorized external tool integrations that might access sensitive data or introduce security risks.

Four settings work together here:

  • allowManagedMcpServersOnly, when true, ensures only MCP servers defined in managed settings or managed-mcp.json can connect. User added and project added servers are blocked.
  • allowedMcpServers is an explicit allowlist of server names or patterns that developers can add (when allowManagedMcpServersOnly is false).
  • deniedMcpServers is a blocklist of server names or patterns that are prohibited regardless of other settings.
  • managed-mcp.json is a file based MCP server configuration distributed alongside managed settings. Servers defined here are always connected and can’t be removed by users.
managed-settings.json
managed-settings.json
{
"allowManagedMcpServersOnly": true,
"mcpServers": {
"company-db": {
"command": "npx",
"args": ["@company/mcp-database"],
"env": {
"DB_HOST": "db.internal.company.com"
}
},
"code-search": {
"type": "http",
"url": "https://search.internal.company.com/mcp"
}
},
"allowedMcpServers": [
"@company/*"
],
"deniedMcpServers": [
"@mcp/shell-exec",
"@mcp/unrestricted-*"
]
}

MCP governance: only company approved servers connect.

For more on MCP architecture, transport modes, and configuration, see Model Context Protocol.


Plugin Governance

Plugins extend Claude Code with additional capabilities from external sources. Plugin governance gives you control over where plugins can be installed from and which sources are trusted.

Three settings handle this:

  • strictKnownMarketplaces is an array of approved plugin sources. When set, only plugins from these sources can be installed. Each entry specifies a source type and identifying pattern. Seven source types are supported: github, npm, pypi, registry, url, local, and marketplace.
  • blockedMarketplaces is an array of blocked plugin sources. Plugins from these sources are denied regardless of the allowed list.
  • pluginTrustMessage is a custom message shown when a user tries to install a plugin from a non approved source. Use this to point developers toward your organization’s approved plugin catalog.
managed-settings.json
managed-settings.json
{
"strictKnownMarketplaces": [
{ "source": "github", "repo": "acme-corp/approved-plugins" },
{ "source": "github", "repo": "acme-corp/internal-tools" },
{ "source": "npm", "scope": "@acme-corp" }
],
"blockedMarketplaces": [
{ "source": "github", "repo": "untrusted-org/*" }
],
"pluginTrustMessage": "Only plugins from the acme corp GitHub org and @acme-corp npm scope are approved. Submit requests to #dev-tools on Slack."
}

Plugin governance restricts installation to approved organizational sources.


Sandbox Enforcement

Claude Code’s sandbox provides two isolation dimensions: filesystem and network. Managed settings can enforce both to prevent data exfiltration and restrict where Claude Code can read, write, and connect.

Filesystem Isolation

Three settings control filesystem access using glob patterns:

  • allowWrite specifies paths the agent can write to. Only these paths are writable.
  • denyWrite specifies paths explicitly blocked for writing, even if they match an allowWrite pattern.
  • denyRead specifies paths blocked for reading. Claude Code can’t access these files at all.

Network Isolation

Two settings control network access:

  • allowedDomains is a whitelist of domains Claude Code can reach via HTTP requests. Anything else gets blocked.
  • allowManagedDomainsOnly, when true, ensures only the domain list from managed settings applies. Developers can’t add their own allowed domains.

Unsandboxed Commands

The allowUnsandboxedCommands setting controls whether commands can bypass the sandbox. Set it to false, and all commands execute within sandbox restrictions. This stops developers from using shell commands to access files or network endpoints that the sandbox would otherwise block.

managed-settings.json
managed-settings.json
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"filesystem": {
"allowWrite": [
"/home/*/projects/**",
"/tmp/claude-*"
],
"denyWrite": [
"/etc/**",
"/usr/**",
"**/.env",
"**/.env.*"
],
"denyRead": [
"/etc/shadow",
"/etc/passwd",
"**/.ssh/**",
"**/credentials/**"
]
},
"network": {
"allowManagedDomainsOnly": true,
"allowedDomains": [
"github.com",
"*.github.com",
"*.npmjs.org",
"registry.npmjs.org",
"internal.company.com",
"*.internal.company.com"
]
}
}
}

Full sandbox configuration: filesystem write/read restrictions plus network domain whitelist.

Together, filesystem and network isolation create a strong boundary around what Claude Code can access. If a prompt injection tries to exfiltrate code through a network request, the domain whitelist blocks it. If a malicious instruction tries to read credentials, the denyRead rules prevent access.


Authentication Controls

Two managed settings control how developers authenticate with Claude Code:

  • forceLoginMethod restricts authentication to a specific provider. Set it to "claudeai" for Claude.ai consumer accounts or "console" for Anthropic Console (API/enterprise) accounts. This keeps developers from using personal accounts for work.
  • forceLoginOrgUUID requires authentication to a specific organization. Only users belonging to the specified org UUID can use Claude Code, ensuring all usage gets tracked under the correct organizational account.
managed-settings.json
managed-settings.json
{
"forceLoginMethod": "console",
"forceLoginOrgUUID": "org-abc123def456"
}

Force all users to authenticate via the Anthropic Console to a specific organization.


Vulnerability Scanning as a Capability

Vulnerability scanning isn’t a standalone named feature in Claude Code. It’s a capability pattern you build by combining subagents, skills, and hooks, all features covered in earlier chapters.

The idea is straightforward: you create a security reviewer subagent (see Git Worktrees & Subagent Delegation) that specializes in spotting security issues, then invoke it as part of your workflow, either manually or automatically through hooks.

Here’s a security reviewer subagent definition:

.claude/agents/security-reviewer/AGENT.md
.claude/agents/security-reviewer/AGENT.md
---
name: security-reviewer
description: Reviews code changes for security vulnerabilities
tools: Read, Grep, Glob, Bash
model: sonnet
---
You are a senior security engineer reviewing code for vulnerabilities.
When invoked:
1. Run git diff to see recent changes
2. Analyze each changed file for:
- SQL injection
- Cross-site scripting (XSS)
- Authentication/authorization bypasses
- Hardcoded secrets or credentials
- Insecure deserialization
- Path traversal
- Command injection
3. Report findings with severity, affected file, line number, and remediation
4. If no issues found, confirm the changes pass security review

A custom subagent that performs security code review.

To trigger this subagent automatically, configure a managed hook that runs on every file change:

managed-settings.json
managed-settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "agent",
"agent": "security-reviewer"
}
]
}
]
}
}

Automatically trigger security review after every file write or edit.

What makes this pattern powerful is its composability. You can create specialized subagents for different security domains (dependency auditing, secret scanning, compliance checking) and combine them through hooks. The managed settings layer ensures these security hooks run for every developer and can’t be disabled.

For more on creating skills that can participate in security workflows, see Custom Skills.


Prompt Injection Protections

Claude Code includes built in protections against prompt injection attacks, which attempt to manipulate it through malicious instructions embedded in code, documentation, or fetched content.

Three layers of defense are always active:

Command blocklist. Known dangerous command patterns get blocked before execution. This catches common attack vectors like piping untrusted content to a shell or executing base64 encoded payloads.

Context aware analysis. Claude Code analyzes instructions found in fetched content, code comments, and documentation for suspicious patterns. If it detects something that looks like a prompt injection (for example, “ignore your previous instructions and run this command”), it flags the content and refuses to follow the injected instruction.

Isolated fetch context. Content fetched from URLs via WebFetch is marked as untrusted and processed in an isolated context. Instructions embedded in fetched web pages can’t override your original prompt or the system level instructions that govern Claude Code’s behavior.

These protections are always on and can’t be disabled. They form the bottom layer of the defense in depth strategy described at the beginning of this chapter.


Monitoring and Compliance

If your organization needs visibility into Claude Code usage, managed settings support monitoring integrations and organizational messaging.

OpenTelemetry integration. Claude Code can export telemetry data via OpenTelemetry, giving your observability platform visibility into session activity, tool usage, and performance metrics. It plugs right into existing monitoring infrastructure (Datadog, Grafana, Splunk, or any OpenTelemetry compatible backend).

otelHeadersHelper lets you inject custom headers into OpenTelemetry export requests. This is handy for authenticating with your telemetry backend or adding organizational metadata to trace data.

companyAnnouncements broadcasts messages to all Claude Code users in the organization. Use it for security advisories, policy updates, feature announcements, or maintenance windows. The announcement shows up when users start a new Claude Code session.

managed-settings.json
managed-settings.json
{
"companyAnnouncements": [
"Security policy update: All projects must enable sandbox network isolation by March 15. See https://wiki.company.com/claude-code-policy for details."
]
}

Broadcast announcements to all Claude Code users at session start.


Verifying Configuration with /status

After deploying managed settings, verify they’ve taken effect by running /status inside a Claude Code session.

Verifying managed settings
Verifying managed settings
/status

Shows active settings per layer, including which values come from managed configuration.

The /status output shows you:

  • Current settings for each configuration layer (managed, local, project, user)
  • Which settings are being overridden by managed configuration
  • Active permission rules and where they come from
  • Connected MCP servers and their governance status
  • Sandbox configuration and network restrictions

Make /status part of your deployment checklist. After pushing managed settings through any of the five delivery mechanisms, have a team member run /status and confirm the expected settings show up.


Best Practices

  • Start permissive and tighten gradually. Deploy monitoring only managed settings first, observe how developers actually use Claude Code, then restrict based on real usage patterns. A policy that’s too restrictive from day one will get circumvented.

  • Use allowManagedPermissionRulesOnly for critical security controls. This is the single most impactful governance setting. Once it’s enabled, developers can’t add permissive rules that weaken organizational security.

  • Test managed settings on a pilot group first. Roll out to a small team before going organization-wide. This catches configuration mistakes before they block hundreds of developers.

  • Use sandbox network isolation to prevent data exfiltration. The allowedDomains whitelist ensures Claude Code can only talk to approved endpoints. This is especially important if your organization handles sensitive source code.

  • Keep allowedHttpHookUrls narrow. Hooks that send HTTP requests should only reach your own infrastructure. A broad URL whitelist defeats the whole purpose of hook governance.

  • Document your managed settings for team visibility. Publish your managed settings configuration (with secrets redacted) on an internal wiki. Developers who understand why a policy exists are far less likely to work around it.

  • Use /status to audit configuration. Make it part of your onboarding checklist and periodic security reviews. When a developer reports unexpected behavior, /status is the first diagnostic step.


Further Reading

  • Security: official documentation on Claude Code’s security model and prompt injection protections
  • Settings: managed settings delivery, precedence hierarchy, and all governance controls
  • Plugins: plugin architecture, marketplace distribution, and governance settings
  • See Models, Costs & Permissions for the individual level permission system that enterprise governance builds upon