Complete OpenClaw Security Configuration Guide
Target keywords: OpenClaw security, AI agent security, self-hosted security, OpenClaw hardening
Introduction
Self-hosted AI systems face unique security challenges. This guide covers complete OpenClaw security configuration, from baseline setup to enterprise-grade protection.
What you will learn:
- Secure API key management
- Network security configuration
- Access control
- Audit logging
- Compliance requirements
Estimated time: 60 minutes
Difficulty: Intermediate to advanced
Security Threat Model
Main Risks
| Risk | Severity | Impact |
|---|---|---|
| API key leakage | 🔴 Critical | Financial loss, data exposure |
| Unauthorized access | 🔴 Critical | System control, data theft |
| Prompt injection | 🟡 Medium | Information leakage, behavior manipulation |
| Model abuse | 🟡 Medium | Resource exhaustion, rising costs |
| Data leakage | 🔴 Critical | Privacy violations, compliance issues |
Attack Scenarios
External attackers
- Scan exposed OpenClaw ports
- Try default credentials
- Inject malicious prompts
Internal threats
- Employees misuse the system
- Excessive privileged access
- Data exfiltration
Supply chain attacks
- Malicious skill plugins
- Dependency vulnerabilities
- Configuration drift
Step 1: API Key Security
1.1 Environment Variable Management
❌ Incorrect approach:
# config.yaml - do not do this!
models:
openai:
api_key: "sk-abc123..." # Hardcoded key
✅ Correct approach:
# config.yaml
models:
openai:
api_key: "${OPENAI_API_KEY}" # Environment variable
# `.env` file (add it to `.gitignore`!)
OPENAI_API_KEY=sk-abc123...
WHATSAPP_TOKEN=EAAxyz...
# Load environment variables
source .env
1.2 Key Rotation
#!/bin/bash
# rotate-keys.sh - key rotation script
# 1. Generate a new key
NEW_KEY=$(openai api-key create --name "openclaw-$(date +%Y%m%d)")
# 2. Update the environment variable
echo "OPENAI_API_KEY=$NEW_KEY" > .env.new
# 3. Restart the service gracefully
openclaw reload
# 4. Verify the new key
curl -H "Authorization: Bearer $NEW_KEY" https://api.openai.com/v1/models
# 5. Delete the old key after 30 days
# (Add this to a cron job)
1.3 Key Separation by Environment
# Use different keys for different environments
models:
openai-production:
api_key: "${OPENAI_API_KEY_PROD}"
openai-staging:
api_key: "${OPENAI_API_KEY_STAGING}"
openai-development:
api_key: "${OPENAI_API_KEY_DEV}"
Step 2: Access Control
2.1 Authentication
# ~/.openclaw/config.yaml
security:
authentication:
enabled: true
type: jwt # Or `api_key`, `oauth`
jwt:
secret: "${JWT_SECRET}" # Strong random string
expiry: 24h
api_key:
header: "X-API-Key"
keys:
- key: "${API_KEY_ADMIN}"
role: admin
rate_limit: 1000/hour
- key: "${API_KEY_USER}"
role: user
rate_limit: 100/hour
2.2 Authorization (RBAC)
security:
authorization:
enabled: true
roles:
admin:
permissions:
- "*" # All permissions
user:
permissions:
- "agent:chat"
- "agent:list"
denied:
- "config:edit"
- "agent:delete"
readonly:
permissions:
- "agent:list"
- "agent:read"
2.3 IP Allowlist
security:
network:
allowed_ips:
- "192.168.1.0/24" # Internal network
- "10.0.0.0/8" # VPN
- "203.0.113.50" # Specific IP
blocked_ips:
- "192.168.1.100" # Former employee
Step 3: Network Security
3.1 TLS/SSL Configuration
server:
tls:
enabled: true
cert_file: "/etc/ssl/certs/openclaw.crt"
key_file: "/etc/ssl/private/openclaw.key"
min_version: "1.2" # Disable TLS 1.0/1.1
# Force HTTPS
redirect_http: true
3.2 Reverse Proxy (Nginx)
# /etc/nginx/sites-available/openclaw
server {
listen 443 ssl http2;
server_name openclaw.yourdomain.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req zone=api burst=20 nodelay;
# Proxy to OpenClaw
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name openclaw.yourdomain.com;
return 301 https://$server_name$request_uri;
}
3.3 Firewall Rules
# UFW (Ubuntu)
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH
sudo ufw allow 22/tcp
# Allow HTTPS (through Nginx)
sudo ufw allow 443/tcp
# Allow internal network access to OpenClaw (if not using Nginx)
sudo ufw allow from 192.168.1.0/24 to any port 8080
# Enable the firewall
sudo ufw enable
Step 4: Input Validation and Filtering
4.1 Prompt Injection Protection
security:
input_validation:
enabled: true
# Prompt injection detection
prompt_injection:
enabled: true
action: block # Or `log`, `sanitize`
# Detection patterns
patterns:
- "ignore previous instructions"
- "disregard all prior"
- "system prompt:"
- "you are now"
- "DAN" # Do Anything Now
# Input length limit
max_length: 4000
# Forbidden characters
forbidden_chars:
- "\x00" # null byte
- "<script>"
4.2 Output Filtering
security:
output_filter:
# Sensitive information detection
pii_detection:
enabled: true
patterns:
- type: credit_card
action: redact
- type: ssn
action: block
- type: api_key
action: redact
# Content moderation
content_moderation:
enabled: true
categories:
- hate
- harassment
- self-harm
4.3 Custom Filters
# ~/.openclaw/skills/security_filters.py
from openclaw import filter
import re
@filter
def block_internal_ips(text: str) -> str:
"""Block internal IP addresses in output"""
# Match internal network IPs
pattern = r'\b(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})\b'
return re.sub(pattern, '[REDACTED]', text)
@filter
def mask_email_addresses(text: str) -> str:
"""Mask email addresses"""
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.sub(pattern, '[EMAIL REDACTED]', text)
Step 5: Audit and Monitoring
5.1 Logging Configuration
logging:
level: info
# Audit logs
audit:
enabled: true
file: "/var/log/openclaw/audit.log"
# Record events
events:
- authentication_success
- authentication_failure
- authorization_denied
- config_change
- agent_created
- agent_deleted
- api_key_used
# Access logs
access:
file: "/var/log/openclaw/access.log"
format: json
# Security logs
security:
file: "/var/log/openclaw/security.log"
level: warn
5.2 Log Analysis
#!/bin/bash
# security-check.sh - daily security check
# 1. Check failed logins
echo "=== Failed Authentication ==="
grep "authentication_failure" /var/log/openclaw/audit.log | tail -20
# 2. Check for abnormal access patterns
echo "=== High Frequency Requests ==="
awk '{print $1}' /var/log/openclaw/access.log | sort | uniq -c | sort -rn | head -10
# 3. Check for prompt injection attempts
echo "=== Prompt Injection Attempts ==="
grep "PROMPT_INJECTION_DETECTED" /var/log/openclaw/security.log
# 4. Send the report
# mail -s "OpenClaw Security Report" admin@yourdomain.com < report.txt
5.3 Real-Time Monitoring
monitoring:
enabled: true
# Anomaly detection
anomaly_detection:
enabled: true
rules:
- name: "high_error_rate"
condition: "error_rate > 10%"
action: alert
- name: "unusual_traffic"
condition: "requests_per_minute > 1000"
action: alert
- name: "suspicious_ips"
condition: "ip_reputation < 0.5"
action: block
Step 6: Data Protection
6.1 Data Encryption
security:
encryption:
# Encryption at rest
at_rest:
enabled: true
algorithm: aes-256-gcm
key_file: "/etc/openclaw/encryption.key"
# Encryption in transit (already covered by TLS)
in_transit:
enabled: true
# Backup encryption
backup:
enabled: true
encrypt: true
6.2 Data Retention Policy
security:
data_retention:
# Conversation history
conversations:
retention: 30d
anonymize_after: 90d
# Logs
logs:
retention: 1y
archive: s3://secure-backup/openclaw-logs/
# Audit records
audit:
retention: 7y # Compliance requirement
6.3 Privacy Protection
agent:
privacy:
# Data minimization
collect_only_necessary: true
# User consent
require_consent: true
# Data portability
allow_export: true
# Right to be forgotten
allow_deletion: true
Step 7: Security Hardening Checklist
Pre-Deployment Checks
# security-audit.sh
echo "=== OpenClaw Security Audit ==="
# 1. Check configuration file permissions
echo "[ ] Config files permissions"
ls -la ~/.openclaw/config.yaml
# It should show: `-rw-------` (owner read/write only)
# 2. Check environment variables
echo "[ ] No hardcoded secrets"
grep -r "sk-" ~/.openclaw/ || echo "✓ No hardcoded API keys"
# 3. Check TLS
echo "[ ] TLS enabled"
curl -v https://localhost:8080 2>&1 | grep "TLS"
# 4. Check authentication
echo "[ ] Authentication enabled"
curl http://localhost:8080/agents -w "%{http_code}" | grep 401 || echo "✗ No auth!"
# 5. Check logs
echo "[ ] Audit logging enabled"
test -f /var/log/openclaw/audit.log && echo "✓ Audit log exists" || echo "✗ No audit log"
# 6. Check the firewall
echo "[ ] Firewall active"
sudo ufw status | grep "Status: active" && echo "✓ Firewall active" || echo "✗ Firewall disabled"
echo "=== Audit Complete ==="
Compliance Requirements
GDPR Compliance
security:
gdpr:
enabled: true
# Data processing records
processing_records: true
# Data protection impact assessment
dpia_required: true
# Data breach notification
breach_notification:
enabled: true
timeframe: 72h
authority: "dpo@yourcompany.com"
SOC 2 Compliance
- ✅ Access control (CC6.1)
- ✅ System monitoring (CC7.2)
- ✅ Data encryption (CC6.7)
- ✅ Audit logs (CC7.1)
- ✅ Change management (CC8.1)
Incident Response
Security Incident Response Plan
1. Detection phase
# Isolate immediately
openclaw stop
# Preserve evidence
cp -r /var/log/openclaw /secure/incident-$(date +%Y%m%d)/
2. Containment phase
# Revoke all API keys
openclaw keys revoke --all
# Enable maintenance mode
openclaw maintenance enable
3. Eradication phase
# Update all passwords/keys
./rotate-keys.sh
# Apply security patches
openclaw update --security-only
4. Recovery phase
# Verify the configuration
./security-audit.sh
# Restore services gradually
openclaw start --restricted-mode
Next Steps
Resources
Get more security guides for free:
[Email subscription form]
Last updated: March 2026