enterprise-security
Enterprise Security Patterns for Claude Code
Production-grade security architecture for Claude Code deployments with compliance, audit, and policy enforcement.
Permission Hardening by Role
Developer (Restricted Privileges)
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Edit",
"Bash(npm test)",
"Bash(npm run dev)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git log)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
"Write",
"WebFetch",
"WebSearch"
]
}
}
Code Reviewer (Read-Heavy)
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(git log *)",
"Bash(git show *)",
"Bash(git diff *)"
],
"deny": [
"Write",
"Edit",
"Bash(git commit *)",
"Bash(git push *)",
"Bash(git rebase *)"
]
}
}
Administrator (Full Access with Audit)
{
"permissions": {
"allow": [
"Read",
"Write",
"Edit",
"Glob",
"Grep",
"Bash(*)",
"Agent",
"WebFetch"
]
},
"hooks": {
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash /opt/audit/admin-audit-log.sh"
}
]
}
]
}
}
Secrets Management
Preventing Credential Exposure
PreToolUse hook to block access to credential files:
#!/bin/bash
# name: block-credential-files.sh
# Prevent Claude from reading .env, .pem, .key, .secret files
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name' 2>/dev/null)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""' 2>/dev/null)
# List of blocked patterns
BLOCKED_PATTERNS=(
'\.env'
'\.env\..*'
'\.pem$'
'\.key$'
'\.secret$'
'\.jks$'
'credentials\.json'
'service-account\.json'
'firebase-key\.json'
'/vault/'
'/secrets/'
'/private/'
)
# Check each pattern
for pattern in "${BLOCKED_PATTERNS[@]}"; do
if echo "$PATH_ARG" | grep -qE "$pattern"; then
echo '{
"decision": "deny",
"reason": "Access to credential files is blocked",
"blocked_pattern": "'$pattern'"
}'
exit 0
fi
done
echo '{"decision": "approve"}'
Vault Integration Pattern
For HashiCorp Vault:
#!/bin/bash
# name: vault-credential-retrieval.sh
# Fetch credentials from Vault instead of storing locally
SECRET_NAME=$1
VAULT_ADDR=${VAULT_ADDR:-"https://vault.internal:8200"}
VAULT_TOKEN=${VAULT_TOKEN:-}
if [ -z "$VAULT_TOKEN" ]; then
echo '{"error": "VAULT_TOKEN not set"}'
exit 1
fi
curl -s \
-H "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/secret/data/$SECRET_NAME" | jq -r '.data.data'
AWS Secrets Manager Pattern
#!/bin/bash
# name: aws-secrets-retrieval.sh
SECRET_NAME=$1
REGION=${AWS_REGION:-us-east-1}
aws secretsmanager get-secret-value \
--secret-id "$SECRET_NAME" \
--region "$REGION" \
--query 'SecretString' \
--output text 2>/dev/null
Git Hook to Prevent Secret Commits
#!/bin/bash
# name: pre-commit-secret-scan.sh
# Placed in .git/hooks/pre-commit
# Patterns that suggest credentials
PATTERNS=(
'PRIVATE.*KEY'
'PASSWORD.*='
'APIKEY'
'api.key'
'secret_access_key'
'aws_secret'
'postgresql://.*:.*@'
'mongodb+srv://.*:.*@'
)
EXIT_CODE=0
for file in $(git diff --cached --name-only); do
for pattern in "${PATTERNS[@]}"; do
if git diff --cached "$file" | grep -qiE "$pattern"; then
echo "ERROR: Potential secret detected in $file (pattern: $pattern)"
EXIT_CODE=1
fi
done
done
exit $EXIT_CODE
Audit Logging
Comprehensive Audit Trail Hook
#!/bin/bash
# name: audit-trail.sh
# PostToolUse hook: log all tool usage with context
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name' 2>/dev/null)
RESULT=$(echo "$INPUT" | jq -r '.tool_result' 2>/dev/null)
USER=${CLAUDE_USER:-"unknown"}
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
AUDIT_LOG="/var/log/claude-code/audit.log"
# Truncate output for logging (first 200 chars)
RESULT_SUMMARY=$(echo "$RESULT" | head -c 200)
INPUT_SUMMARY=$(echo "$INPUT" | jq -r '.tool_input | @json' 2>/dev/null | head -c 200)
# Append to audit log with atomic write
{
flock -x 200
echo "{
\"timestamp\": \"$TIMESTAMP\",
\"user\": \"$USER\",
\"tool\": \"$TOOL\",
\"input_summary\": \"$INPUT_SUMMARY\",
\"output_length\": $(echo "$RESULT" | wc -c),
\"status\": \"success\"
}" >> "$AUDIT_LOG"
} 200>"/var/log/claude-code/audit.log.lock"
# Also log file modifications
if [[ "$TOOL" == "Write" ]] || [[ "$TOOL" == "Edit" ]]; then
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
echo "{
\"timestamp\": \"$TIMESTAMP\",
\"user\": \"$USER\",
\"action\": \"file_modified\",
\"file\": \"$FILE_PATH\",
\"tool\": \"$TOOL\"
}" >> "/var/log/claude-code/file-changes.log"
fi
Log Rotation Configuration
#!/bin/bash
# name: setup-audit-log-rotation.sh
# Configure logrotate for Claude Code audit trails
cat > /etc/logrotate.d/claude-code << 'EOF'
/var/log/claude-code/*.log {
daily
rotate 90
compress
delaycompress
missingok
notifempty
create 0600 root root
sharedscripts
postrotate
# Notify SIEM or archival system
/opt/claude-code/archive-audit-logs.sh
endscript
}
EOF
chmod 644 /etc/logrotate.d/claude-code
SOC2 Compliance Mapping
CC-6.1 Logical Access Control
Control: Restrict access to systems and data.
Implementation:
- Permission modes (plan, default, acceptEdits) limit tool access
- Allow/deny lists in settings.json prevent unauthorized tool use
- Managed settings prevent user override
- Pre-commit hooks block credential commits
Evidence Collection:
# Audit: Current permissions configuration
grep -r "permissions" ~/.claude/settings.json
# Audit: Session permission changes
grep "permission_mode" /var/log/claude-code/audit.log
# Audit: Denied tool uses
grep '"decision": "deny"' /var/log/claude-code/audit.log | wc -l
CC-7.1 System Monitoring and Anomaly Detection
Control: Monitor activity for anomalies.
Implementation:
- PostToolUse hooks capture all tool calls with timestamps
- File change tracking logs modifications with user
- Login events tracked via forceLoginMethod
- Cost tracking detects unusual API usage patterns
Evidence Collection:
# Daily activity summary
awk '$tool == "Bash(rm*)" {rm_count++} END {
print "Dangerous Bash uses: " rm_count
}' /var/log/claude-code/audit.log
# User activity timeline
grep '"user":' /var/log/claude-code/audit.log | \
jq -s 'group_by(.user) |
map({user: .[0].user, count: length})'
CC-8.1 Change Management
Control: Authorize and document changes.
Implementation:
- Git hooks require pre-commit message format
- File modification audit trail (tool, user, timestamp)
- Pre-push hooks verify branch protection
- PostToolUse hooks log all code changes
Evidence Collection:
# Git change log with user and timestamp
git log --pretty=format:"%h %an %ad %s" --date=short
# Files modified in past 30 days
find . -mtime -30 -type f | xargs ls -lt | head -20
HIPAA Compliance Template
Protected Health Information (PHI) prevention hooks:
#!/bin/bash
# name: hipaa-phi-guard.sh
# PreToolUse: Block tools that could expose PHI
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name' 2>/dev/null)
# Reject tools that could output to insecure locations
case "$TOOL" in
WebFetch|WebSearch)
echo '{"decision": "deny", "reason": "WebFetch/WebSearch blocked in HIPAA environment"}'
exit 0
;;
Bash)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command' 2>/dev/null)
# Block commands that might exfiltrate data
if echo "$CMD" | grep -qE '(curl|wget|scp|rsync|nc).*[^127\.0\.0\.1]'; then
echo '{"decision": "deny", "reason": "Network exfiltration patterns blocked"}'
exit 0
fi
;;
esac
echo '{"decision": "approve"}'
PostToolUse hook to prevent PHI in responses:
#!/bin/bash
# name: hipaa-output-sanitizer.sh
# PostToolUse: Scan outputs for PHI patterns
INPUT=$(cat)
OUTPUT=$(echo "$INPUT" | jq -r '.tool_result' 2>/dev/null)
# Common PHI patterns
PHI_PATTERNS=(
'[0-9]{3}-[0-9]{2}-[0-9]{4}' # SSN
'[0-9]{16,19}' # Credit card
'MRN[:\s]*[0-9]{6,12}' # Medical Record Number
)
for pattern in "${PHI_PATTERNS[@]}"; do
if echo "$OUTPUT" | grep -qE "$pattern"; then
echo "{
\"warning\": \"PHI pattern detected in output\",
\"pattern\": \"$pattern\",
\"action\": \"sanitize\"
}"
# Do not output the matched text
exit 1
fi
done
GDPR Data Handling
Retention Policy
{
"dataRetention": {
"auditLogs": "90 days",
"fileLogs": "30 days",
"sessionLogs": "7 days",
"backups": "365 days"
},
"zeroDataRetention": true
}
PII Detection Hook
#!/bin/bash
# name: gdpr-pii-detector.sh
# PreToolUse: Detect PII in inputs and flag for review
INPUT=$(cat)
# PII patterns
PII_PATTERNS=(
'name[:\s]*[A-Z][a-z]+ [A-Z]'
'email[:\s]*[a-z0-9._%+-]+@'
'phone[:\s]*\+?[0-9\s().-]{10,}'
'address[:\s]*[0-9]+ .{5,}'
)
for pattern in "${PII_PATTERNS[@]}"; do
if echo "$INPUT" | grep -qiE "$pattern"; then
echo "{
\"warning\": \"PII detected in input\",
\"pattern\": \"$pattern\",
\"user_confirmation_required\": true
}"
exit 1
fi
done
echo '{"decision": "approve"}'
SSO and Identity Integration
Anthropic API with Organization
{
"auth": {
"method": "apiKey",
"apiKey": "${ANTHROPIC_API_KEY}",
"organizationId": "${ANTHROPIC_ORG_ID}",
"forceLoginOrgUUID": "org-12345"
}
}
AWS Bedrock Integration
{
"auth": {
"method": "bedrock",
"region": "us-east-1",
"roleArn": "arn:aws:iam::123456789:role/claude-code-role",
"assumeRoleSessionName": "claude-code-session"
}
}
Google Cloud Vertex AI
{
"auth": {
"method": "vertexAI",
"projectId": "my-gcp-project",
"location": "us-central1",
"serviceAccountPath": "/etc/gcloud/service-account.json"
}
}
Network Security
Proxy Configuration for Egress Control
export GLOBAL_AGENT_HTTP_PROXY="http://proxy.internal:3128"
export GLOBAL_AGENT_HTTPS_PROXY="https://proxy.internal:3128"
export NO_PROXY="localhost,127.0.0.1,*.internal,.local"
Air-Gapped Setup (Bedrock)
For deployments without internet access:
{
"auth": {
"method": "bedrock",
"vpcEndpoint": "vpce-12345678",
"region": "us-east-1"
},
"network": {
"allowedDomains": [
"bedrock.us-east-1.amazonaws.com"
],
"blockPublicInternet": true
}
}
MCP Server Domain Allowlist
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["mcp-filesystem-server.js"],
"allowedPaths": ["/app", "/data"],
"allowNetworkAccess": false
},
"web": {
"allowedDomains": [
"api.internal",
"docs.internal"
]
}
}
}
Managed Settings Enforcement
Organization-Level Settings (macOS)
Place at /Library/Application Support/ClaudeCode/CLAUDE.md and settings.json:
{
"managedSettings": {
"version": "1.0",
"enforced": true,
"permissions": {
"deny": [
"Bash(curl * | bash)",
"Bash(wget * | bash)",
"Bash(sudo *)",
"Bash(chmod 777 *)"
]
},
"model": "claude-sonnet-4-6",
"hooks": {
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "/opt/audit/enterprise-audit.sh"
}
]
}
]
},
"network": {
"proxy": "https://proxy.corp:3128"
}
}
}
Linux System-Wide Settings
Place at /etc/claude-code/CLAUDE.md and /etc/claude-code/settings.json.
Windows Group Policy
Store at HKEY_LOCAL_MACHINE\Software\Policies\ClaudeCode\:
New-Item -Path "HKLM:\Software\Policies\ClaudeCode" -Force
New-ItemProperty -Path "HKLM:\Software\Policies\ClaudeCode" `
-Name "PermissionMode" -Value "plan" -PropertyType String
Incident Response Playbook
If Claude Generates Credentials
- Immediate: Stop the session (
Ctrl+C) - Contain: Run credential rotation script
- Audit: Check audit logs for exposure
- Remediate: Revoke any exposed credentials
- Document: Record incident in security log
#!/bin/bash
# name: incident-response-credential-leak.sh
INCIDENT_ID=$(date +%s)
INCIDENT_LOG="/var/log/claude-code/incidents.log"
echo "{
\"incident_id\": \"$INCIDENT_ID\",
\"type\": \"credential_exposure\",
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
\"status\": \"investigating\",
\"actions_taken\": []
}" > "/tmp/incident-$INCIDENT_ID.json"
# Rotate all API keys
echo " Revoking API keys..."
# Call credential rotation service
# Archive audit logs for forensics
echo " Archiving audit logs..."
tar czf "/var/log/claude-code/incident-$INCIDENT_ID.tar.gz" \
/var/log/claude-code/*.log
echo " Incident $INCIDENT_ID logged"
If Sensitive Data Output
- Check: Grep audit logs for the data pattern
- Scope: Determine who had access
- Notify: Alert security team
- Retain: Keep logs for compliance investigation
#!/bin/bash
# name: audit-forensics.sh
DATA_PATTERN="$1"
LOG_DIR="/var/log/claude-code"
echo "=== Forensic Analysis ==="
echo "Pattern: $DATA_PATTERN"
echo ""
echo "Occurrences in audit trail:"
grep -rn "$DATA_PATTERN" "$LOG_DIR" | wc -l
echo ""
echo "Timeline:"
grep -rn "$DATA_PATTERN" "$LOG_DIR" | cut -d: -f3 | jq '.timestamp'
Enterprise Security Checklist
- Permission mode set to non-permissive (not bypassPermissions)
- Deny list covers destructive bash commands (rm, mkfs, dd, chmod 777)
- PreToolUse hook blocks .env, .pem, .key file access
- PostToolUse hook logs all tool calls with timestamp and user
- Vault or Secrets Manager integration configured
- Pre-commit hook prevents credential commits
- Audit logs persist to /var/log/claude-code/
- Log rotation configured with 90-day retention
- Managed settings prevent user override
- SSO method configured (Anthropic, Bedrock, or Vertex)
- Network proxy configured for egress control
- MCP servers vetted for security
- SOC2/HIPAA/GDPR compliance policies documented
- Incident response playbook tested
- Security team trained on audit log access
More from lobbi-docs/claude
vision-multimodal
Vision and multimodal capabilities for Claude including image analysis, PDF processing, and document understanding. Activate for image input, base64 encoding, multiple images, and visual analysis.
245design-system
Apply and manage the AI-powered design system with 50+ curated styles
126complex-reasoning
Multi-step reasoning patterns and frameworks for systematic problem solving. Activate for Chain-of-Thought, Tree-of-Thought, hypothesis-driven debugging, and structured analytical approaches that leverage extended thinking.
106gcp
Google Cloud Platform services including GKE, Cloud Run, Cloud Storage, BigQuery, and Pub/Sub. Activate for GCP infrastructure, Google Cloud deployment, and GCP integration.
73kanban
Kanban methodology including boards, WIP limits, flow metrics, and continuous delivery. Activate for Kanban boards, workflow visualization, and lean project management.
63debugging
Debugging techniques for Python, JavaScript, and distributed systems. Activate for troubleshooting, error analysis, log investigation, and performance debugging. Includes extended thinking integration for complex debugging scenarios.
59