Skip to content

SOP-005: Authentication & Security

Document Control

FieldValue
Document IDSOP-005
Version1.0
StatusActive
OwnerClaude AI Operations
Last Updated2024-12-01
Review Date2025-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-key

1.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/*/credentials

Step 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"]
EOF

2.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-keys

Step 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
EOF

3.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-check

Step 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-auth

4.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-secrets

Step 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.sh

5.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-status

Verification

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/*/credentials

Authentication 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
done

Troubleshooting

Common Issues

IssueSymptomsResolution
Authentication failure401/403 errorsVerify API key validity and permissions
Certificate errorsSSL/TLS handshake failuresCheck certificate chain and expiry
Permission deniedFile access errorsVerify file permissions (600)
Rate limit exceeded429 errorsImplement proper rate limiting
Secrets not loadingMissing environment variablesCheck 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

See Also

Claude Code Documentation Hub