SOP-005: Authentication & Security
Document Control
| Field | Value |
|---|---|
| Document ID | SOP-005 |
| Version | 1.0 |
| Status | Active |
| Owner | Claude AI Operations |
| Last Updated | 2024-12-01 |
| Review Date | 2025-03-01 |
Overview
This SOP establishes procedures for configuring authentication and implementing security measures for Claude AI deployments. It covers API key management, access controls, encryption, and security best practices.
Security Architecture
┌─────────────────────────────────────────────────────────────┐
│ Security Layers │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ User │ │ API │ │ Transport │ │
│ │ Authentication │ │ Authorization│ │ Encryption │ │
│ │ │ │ │ │ │ │
│ │ • Identity │ │ • API Keys │ │ • TLS 1.3 │ │
│ │ • MFA │ │ • Rate Limits│ │ • Certificate│ │
│ │ • Sessions │ │ • Permissions│ │ • HSTS │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Security Controls │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Secrets │ │ Audit │ │ Monitor │ │
│ │ Management │ │ Logging │ │ Alerts │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘Prerequisites
- Administrative access to target systems
- Access to Anthropic Console
- Secret management system (e.g., HashiCorp Vault, AWS Secrets Manager)
- Certificate management infrastructure
Procedure
Step 1: API Key Management
1.1 Obtain API Keys
bash
# Navigate to Anthropic Console
# https://console.anthropic.com/dashboard
# Create new API key
echo "1. Log into Anthropic Console"
echo "2. Navigate to API Keys section"
echo "3. Click 'Create Key'"
echo "4. Set appropriate permissions and restrictions"
echo "5. Copy key immediately (won't be shown again)"1.2 Secure API Key Storage
bash
# Create secure credential storage
sudo mkdir -p /etc/claude/secrets
sudo chmod 700 /etc/claude/secrets
# Store API key securely
sudo tee /etc/claude/secrets/api-key << 'EOF'
# Never commit this file to version control
CLAUDE_API_KEY=your_api_key_here
EOF
sudo chmod 600 /etc/claude/secrets/api-key
sudo chown root:root /etc/claude/secrets/api-key1.3 Environment-Specific Key Management
bash
# Development environment
cat > ~/.config/claude/dev/credentials << 'EOF'
# Development API Key
CLAUDE_API_KEY_DEV=sk-ant-dev-xxx
CLAUDE_PROJECT_ID_DEV=proj-dev-xxx
EOF
# Staging environment
cat > ~/.config/claude/staging/credentials << 'EOF'
# Staging API Key
CLAUDE_API_KEY_STAGING=sk-ant-stg-xxx
CLAUDE_PROJECT_ID_STAGING=proj-stg-xxx
EOF
# Production environment (use secrets management)
cat > ~/.config/claude/prod/credentials << 'EOF'
# Production uses external secrets management
CLAUDE_API_KEY_SOURCE=vault
CLAUDE_VAULT_PATH=secret/claude/production
CLAUDE_PROJECT_ID_PROD=proj-prod-xxx
EOF
# Secure all credential files
chmod 600 ~/.config/claude/*/credentialsStep 2: Access Control Implementation
2.1 Role-Based Access Control
bash
# Create RBAC configuration
cat > ~/.config/claude/rbac.yaml << 'EOF'
roles:
admin:
permissions:
- api:full_access
- config:read_write
- secrets:manage
- monitoring:full_access
users:
- admin@company.com
developer:
permissions:
- api:read_write
- config:read
- monitoring:read
users:
- dev@company.com
restrictions:
- environment: development
- model: claude-3-sonnet-20240229
readonly:
permissions:
- api:read
- config:read
- monitoring:read
users:
- viewer@company.com
restrictions:
rate_limits:
admin: 1000/hour
developer: 100/hour
readonly: 50/hour
allowed_models:
admin: ["*"]
developer: ["claude-3-sonnet-20240229"]
readonly: ["claude-3-haiku-20240307"]
EOF2.2 API Key Rotation
bash
cat > ~/.local/bin/claude-rotate-keys << 'EOF'
#!/bin/bash
# Claude API Key Rotation Script
set -euo pipefail
ENVIRONMENT=${1:-staging}
BACKUP_DIR="$HOME/.config/claude/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
rotate_key() {
local env=$1
local old_key_file="$HOME/.config/claude/$env/credentials"
local backup_file="$BACKUP_DIR/credentials_${env}_${TIMESTAMP}"
echo "🔄 Rotating API key for $env environment..."
# Backup current credentials
mkdir -p "$BACKUP_DIR"
cp "$old_key_file" "$backup_file"
echo "📝 Please update the API key in Anthropic Console"
echo "📁 Old credentials backed up to: $backup_file"
echo "✏️ Update $old_key_file with new key"
# Verify new key works
echo "🔍 Testing new API key..."
if claude --test-connection --environment "$env"; then
echo "✅ Key rotation successful"
# Optionally remove backup after successful verification
read -p "Remove backup file? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm "$backup_file"
echo "🗑️ Backup removed"
fi
else
echo "❌ Key rotation failed - restoring backup"
cp "$backup_file" "$old_key_file"
exit 1
fi
}
case "$ENVIRONMENT" in
dev|development)
rotate_key "dev"
;;
staging)
rotate_key "staging"
;;
prod|production)
echo "❌ Production key rotation requires manual approval"
echo "📞 Contact security team for production key rotation"
exit 1
;;
*)
echo "❌ Invalid environment: $ENVIRONMENT"
echo "Valid options: dev, staging, prod"
exit 1
;;
esac
EOF
chmod +x ~/.local/bin/claude-rotate-keysStep 3: Transport Security
3.1 TLS Configuration
bash
# Create TLS configuration
cat > ~/.config/claude/tls.conf << 'EOF'
# TLS Security Configuration
TLS_MIN_VERSION=1.3
TLS_CIPHER_SUITES=TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256
CERTIFICATE_VERIFICATION=strict
CERTIFICATE_PINNING=enabled
HSTS_ENABLED=true
HSTS_MAX_AGE=31536000
EOF3.2 Certificate Management
bash
# Certificate validation script
cat > ~/.local/bin/claude-cert-check << 'EOF'
#!/bin/bash
# Certificate Validation for Claude API
API_HOST="api.anthropic.com"
PORT=443
echo "🔍 Checking SSL certificate for $API_HOST..."
# Check certificate expiry
cert_info=$(echo | openssl s_client -servername "$API_HOST" -connect "$API_HOST:$PORT" 2>/dev/null | openssl x509 -noout -dates)
if [ $? -eq 0 ]; then
echo "✅ Certificate information:"
echo "$cert_info"
# Extract expiry date and check if it's within 30 days
expiry=$(echo "$cert_info" | grep "notAfter" | cut -d= -f2)
expiry_epoch=$(date -d "$expiry" +%s)
current_epoch=$(date +%s)
days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
if [ "$days_until_expiry" -lt 30 ]; then
echo "⚠️ Certificate expires in $days_until_expiry days"
else
echo "✅ Certificate valid for $days_until_expiry days"
fi
else
echo "❌ Failed to retrieve certificate information"
exit 1
fi
# Check TLS version
echo "🔐 Checking TLS version support..."
tls_check=$(echo | openssl s_client -tls1_3 -connect "$API_HOST:$PORT" 2>/dev/null | grep "Protocol")
if echo "$tls_check" | grep -q "TLSv1.3"; then
echo "✅ TLS 1.3 supported"
else
echo "⚠️ TLS 1.3 not available"
fi
EOF
chmod +x ~/.local/bin/claude-cert-checkStep 4: Secrets Management Integration
4.1 HashiCorp Vault Integration
bash
# Vault secrets retrieval
cat > ~/.local/bin/claude-vault-auth << 'EOF'
#!/bin/bash
# Claude Vault Authentication
VAULT_ADDR="${VAULT_ADDR:-https://vault.company.com}"
VAULT_NAMESPACE="${VAULT_NAMESPACE:-claude}"
authenticate_vault() {
echo "🔐 Authenticating with Vault..."
# Use appropriate auth method
case "${VAULT_AUTH_METHOD:-userpass}" in
"userpass")
vault auth -method=userpass username="$USER"
;;
"ldap")
vault auth -method=ldap username="$USER"
;;
"aws")
vault auth -method=aws
;;
*)
echo "❌ Unsupported auth method: $VAULT_AUTH_METHOD"
exit 1
;;
esac
}
get_claude_secrets() {
local env=${1:-development}
echo "📝 Retrieving Claude secrets for $env..."
# Get secrets from Vault
vault kv get -format=json "secret/claude/$env" | jq -r '.data.data | to_entries[] | "\(.key)=\(.value)"' > "/tmp/claude-secrets-$env"
# Source the secrets
set -a
source "/tmp/claude-secrets-$env"
set +a
# Clean up temp file
shred -u "/tmp/claude-secrets-$env"
echo "✅ Secrets loaded for $env environment"
}
# Main execution
authenticate_vault
get_claude_secrets "${1:-development}"
EOF
chmod +x ~/.local/bin/claude-vault-auth4.2 AWS Secrets Manager Integration
bash
# AWS Secrets Manager integration
cat > ~/.local/bin/claude-aws-secrets << 'EOF'
#!/bin/bash
# Claude AWS Secrets Manager Integration
AWS_REGION="${AWS_REGION:-us-west-2}"
get_aws_secret() {
local secret_name="$1"
local environment="$2"
echo "🔍 Retrieving secret: $secret_name for $environment..."
# Get secret value
secret_value=$(aws secretsmanager get-secret-value \
--region "$AWS_REGION" \
--secret-id "$secret_name" \
--query 'SecretString' \
--output text)
if [ $? -eq 0 ]; then
# Parse JSON and export variables
echo "$secret_value" | jq -r 'to_entries[] | "\(.key)=\(.value)"' | while IFS='=' read -r key value; do
export "$key=$value"
done
echo "✅ AWS secrets loaded successfully"
else
echo "❌ Failed to retrieve AWS secret: $secret_name"
exit 1
fi
}
# Usage examples
case "${1:-development}" in
"development")
get_aws_secret "claude/dev/credentials" "development"
;;
"staging")
get_aws_secret "claude/staging/credentials" "staging"
;;
"production")
get_aws_secret "claude/prod/credentials" "production"
;;
*)
echo "Usage: $0 [development|staging|production]"
exit 1
;;
esac
EOF
chmod +x ~/.local/bin/claude-aws-secretsStep 5: Security Monitoring
5.1 Audit Logging
bash
# Security audit logging
cat > ~/.config/claude/security-audit.sh << 'EOF'
#!/bin/bash
# Claude Security Audit Logging
AUDIT_LOG="/var/log/claude/security-audit.log"
MAX_LOG_SIZE="100M"
# Ensure log directory exists
sudo mkdir -p "$(dirname "$AUDIT_LOG")"
audit_log() {
local event_type="$1"
local details="$2"
local user="${SUDO_USER:-$USER}"
local timestamp=$(date --iso-8601=seconds)
local session_id="${SSH_CLIENT:-local}"
# Create audit entry
audit_entry=$(cat << EOF
{
"timestamp": "$timestamp",
"event_type": "$event_type",
"user": "$user",
"session_id": "$session_id",
"details": "$details",
"hostname": "$(hostname)",
"pid": "$$"
}
EOF
)
# Log with rotation
echo "$audit_entry" | sudo tee -a "$AUDIT_LOG" > /dev/null
# Rotate log if too large
if [ -f "$AUDIT_LOG" ] && [ $(stat -c%s "$AUDIT_LOG") -gt $(numfmt --from=iec "$MAX_LOG_SIZE") ]; then
sudo logrotate -f /etc/logrotate.d/claude-security
fi
}
# Audit events
case "${1:-help}" in
"api_key_access")
audit_log "API_KEY_ACCESS" "API key accessed for environment: ${2:-unknown}"
;;
"configuration_change")
audit_log "CONFIG_CHANGE" "Configuration modified: ${2:-unknown}"
;;
"authentication_failure")
audit_log "AUTH_FAILURE" "Authentication failed: ${2:-unknown}"
;;
"privilege_escalation")
audit_log "PRIVILEGE_ESCALATION" "Privilege escalation attempted: ${2:-unknown}"
;;
*)
echo "Usage: $0 <event_type> <details>"
echo "Event types: api_key_access, configuration_change, authentication_failure, privilege_escalation"
;;
esac
EOF
chmod +x ~/.config/claude/security-audit.sh5.2 Security Monitoring Dashboard
bash
# Security monitoring script
cat > ~/.local/bin/claude-security-status << 'EOF'
#!/bin/bash
# Claude Security Status Dashboard
show_security_status() {
echo "🔐 Claude Security Status Dashboard"
echo "=================================="
# API Key Status
echo
echo "📋 API Key Status:"
for env in dev staging prod; do
if [ -f "$HOME/.config/claude/$env/credentials" ]; then
key_age=$(stat -c %Y "$HOME/.config/claude/$env/credentials")
current_time=$(date +%s)
days_old=$(( (current_time - key_age) / 86400 ))
if [ "$days_old" -gt 90 ]; then
status="🔴 ROTATE NEEDED"
elif [ "$days_old" -gt 60 ]; then
status="🟡 CONSIDER ROTATION"
else
status="✅ OK"
fi
echo " $env: $status ($days_old days old)"
else
echo " $env: ❌ NOT CONFIGURED"
fi
done
# Certificate Status
echo
echo "📋 Certificate Status:"
if command -v claude-cert-check >/dev/null; then
claude-cert-check 2>/dev/null | tail -2
else
echo " ❌ Certificate check not available"
fi
# Recent Security Events
echo
echo "📋 Recent Security Events:"
if [ -f "/var/log/claude/security-audit.log" ]; then
sudo tail -5 "/var/log/claude/security-audit.log" | jq -r '"\(.timestamp) - \(.event_type): \(.details)"' 2>/dev/null || echo " No recent events"
else
echo " No audit log found"
fi
# Permission Check
echo
echo "📋 Permission Check:"
for file in ~/.config/claude/*/credentials; do
if [ -f "$file" ]; then
perms=$(stat -c %a "$file")
if [ "$perms" = "600" ]; then
echo " $(basename $(dirname $file)): ✅ Secure ($perms)"
else
echo " $(basename $(dirname $file)): ❌ Insecure ($perms)"
fi
fi
done
}
show_security_status
EOF
chmod +x ~/.local/bin/claude-security-statusVerification
Security Configuration Check
bash
# Run security status check
claude-security-status
# Verify certificate status
claude-cert-check
# Test API key authentication
claude --test-auth --environment development
claude --test-auth --environment staging
# Check file permissions
ls -la ~/.config/claude/*/credentialsAuthentication Test
bash
# Test different authentication methods
export CLAUDE_API_KEY=$(cat ~/.config/claude/dev/credentials | grep CLAUDE_API_KEY_DEV | cut -d= -f2)
claude --model claude-3-sonnet-20240229 --message "test authentication"
# Verify rate limiting
for i in {1..5}; do
claude --message "test $i" --environment staging
doneTroubleshooting
Common Issues
| Issue | Symptoms | Resolution |
|---|---|---|
| Authentication failure | 401/403 errors | Verify API key validity and permissions |
| Certificate errors | SSL/TLS handshake failures | Check certificate chain and expiry |
| Permission denied | File access errors | Verify file permissions (600) |
| Rate limit exceeded | 429 errors | Implement proper rate limiting |
| Secrets not loading | Missing environment variables | Check secrets management integration |
Debug Commands
bash
# Debug authentication
export CLAUDE_DEBUG=true
claude --test-connection --verbose
# Check API key format
echo "$CLAUDE_API_KEY" | cut -c1-10 # Should show "sk-ant-api"
# Test TLS connection
openssl s_client -connect api.anthropic.com:443 -tls1_3
# Verify file permissions
find ~/.config/claude -name "credentials" -exec ls -la {} \;Recovery Procedures
bash
# Reset authentication configuration
rm -f ~/.config/claude/*/credentials
# Re-run Step 1-2 procedures
# Emergency key rotation
claude-rotate-keys staging
# Restore from backup
cp ~/.config/claude/backups/credentials_prod_latest ~/.config/claude/prod/credentials
chmod 600 ~/.config/claude/prod/credentials