Chapter 05 · Section IV · 12 min read
5.4 Security: enforcement, exclusion patterns, audit logs
The three security surfaces that matter at company scale — enforced permissions, file-exclusion patterns for sensitive paths, and audit logging so someone else can review what Claude did.
Individual security is “do not run destructive commands by accident.” Company security adds two more things: enforce policies developers cannot bypass, and record what happened so security teams can audit later. Both live in the managed settings + audit log surfaces.
Permission enforcement
Section 1.5 covered how the deny/allow lists work. At company scale, the additional lever is the managed settings file — sat above every other layer in the hierarchy, so nothing in user or project settings can override it.
/etc/claude-code/managed-settings.json (Linux; equivalent paths on macOS/Windows):
{
"permissions": {
"deny": [
"Bash(rm -rf /*)",
"Bash(git push --force*)",
"Bash(curl * | bash)",
"WebFetch"
],
"allow": []
},
"modelAllowlist": [
"claude-sonnet-4-6",
"claude-opus-4-7"
],
"disableSlashCommand": ["dangerously-skip-permissions"]
}
Deploy via your fleet-management tool (MDM, Ansible, whatever). Developers cannot override these no matter what they put in their own settings.
File exclusion patterns
Sensitive paths — secrets directories, customer data caches, credentials — should be invisible to Claude Code. Use permissions.additionalDirectories inversely, plus explicit denies:
{
"permissions": {
"deny": [
"Read(**/secrets/**)",
"Read(**/.env*)",
"Read(**/*.pem)",
"Read(**/credentials*)"
]
}
}
Deny beats allow, so even if a project’s allowlist includes Read, these paths are refused. The deny list is where you draw the “never see this” perimeter.
Audit logging
For compliance you want a record of every tool call, prompt, and reply. Two channels:
Hook-based logging.
A PreToolUse hook that appends to a log file:
{
"hooks": {
"PreToolUse": [{
"matcher": "*",
"hooks": [{ "type": "command", "command": "echo \"$(date -Iseconds) $CLAUDE_USER $CLAUDE_TOOL_NAME $CLAUDE_TOOL_INPUT\" >> /var/log/claude/audit.log" }]
}]
}
}
Simple, portable, but requires each machine to be configured.
Central telemetry (managed).
Managed settings can point Claude Code at a central OTLP endpoint. Every session emits structured events — tool calls, permission decisions, cost — to your observability stack. This is what security teams actually want: one place to query “what did user X ask Claude yesterday.”
{
"telemetry": {
"otel_endpoint": "https://otel.corp.local:4317",
"include_prompts": true
}
}
The disable list
For destructive-by-design commands you never want to be possible:
{
"disableSlashCommand": ["dangerously-skip-permissions"],
"disableTool": ["WebSearch"]
}
Better than relying on developers to not type them.
Check your understanding
Quick check
—