API Key Management and Secret Rotation for Openclaw
A single leaked API key can cost you thousands of dollars in hours. In January 2025, a developer accidentally committed an Anthropic API key to a public GitHub repository. Automated scrapers picked it up within minutes, and the resulting unauthorized usage generated over $12,000 in charges before the key was revoked. This is not an edge case. Secret scanning services report that thousands of API keys are exposed on public repositories every week, and AI platform keys are among the most valuable targets because they translate directly into compute spend.
Openclaw (formerly Clawdbot) deployments are especially sensitive because a single installation typically holds credentials for multiple services simultaneously: your Anthropic API key for the AI engine, messaging platform tokens for WhatsApp or Telegram, OAuth credentials for Gmail or Google Calendar, and potentially access tokens for GitHub, Slack, or other integrations. A breach of your Openclaw server is not a single-key compromise; it is a multi-service compromise. This article is part of our complete deployment security guide and covers everything you need to lock down the credential layer of your installation.
What Secrets Does Openclaw Need?
Before you can secure your secrets, you need to understand exactly what you are protecting and what happens if each credential is exposed. A typical Openclaw deployment holds between four and ten secrets depending on how many integrations you enable. Each one has a different blast radius and a different recommended rotation frequency.
| Secret | Blast Radius if Leaked | Recommended Rotation |
|---|---|---|
| Anthropic API Key | Unlimited spend until revoked. Attacker can run any model at your expense. $1,000s in minutes. | Every 90 days |
| WhatsApp Business API Token | Send messages as your business. Spam, phishing, account ban risk. | Every 90 days |
| Telegram Bot Token | Full control of your bot. Read all messages, send as the bot. | Every 90 days |
| Discord Bot Token | Full bot access in all servers. Message reading, sending, moderation actions. | Every 90 days |
| Slack Bot Token | Access to workspace channels, message history, and file uploads. | Every 90 days |
| Gmail OAuth Refresh Token | Read and send email on your behalf. Data exfiltration, phishing. | Revoke and reauthorize every 180 days |
| GitHub Personal Access Token | Repository access (read/write), depending on scope. Source code theft. | Every 60 days |
| Webhook Signing Secret | Forge incoming webhooks. Inject commands into your agent. | Every 90 days |
The Anthropic API key is the highest-priority secret. Unlike most platform tokens that have rate limits or require additional authentication, an Anthropic key with no spending cap is a direct line to unbounded compute charges. Protect it accordingly.
Environment Variable Best Practices
The most common way to pass secrets to Openclaw is through a .env file. This works, but you need to follow strict hygiene to prevent accidental exposure. The number one rule: never commit your .env file to version control.
Start by ensuring your .gitignore blocks all environment files:
# .gitignore - environment and secret files
.env
.env.*
!.env.example
*.pem
*.key
docker-compose.override.yml
Set restrictive file permissions so only the owner can read the file. No group access, no world access:
# Lock down .env permissions (owner read/write only)
chmod 600 .env
# Verify permissions
ls -la .env
# Expected: -rw------- 1 deploy deploy 482 Feb 10 14:22 .env
Provide a .env.example file that documents every required variable without exposing real values. This serves as onboarding documentation and a configuration checklist:
# .env.example - Openclaw configuration template
# Copy to .env and fill in real values: cp .env.example .env
# === Anthropic (required) ===
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx
ANTHROPIC_MODEL=claude-sonnet-4-20250514
ANTHROPIC_MAX_TOKENS_PER_REQUEST=4096
# === Messaging Platform (enable one or more) ===
WHATSAPP_API_TOKEN=your-whatsapp-token
WHATSAPP_PHONE_NUMBER_ID=123456789
WHATSAPP_VERIFY_TOKEN=your-webhook-verify-string
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
DISCORD_BOT_TOKEN=your-discord-bot-token
DISCORD_GUILD_ID=your-server-id
SLACK_BOT_TOKEN=xoxb-your-slack-bot-token
SLACK_SIGNING_SECRET=your-signing-secret
# === Integrations (optional) ===
GMAIL_CLIENT_ID=your-client-id.apps.googleusercontent.com
GMAIL_CLIENT_SECRET=your-client-secret
GMAIL_REFRESH_TOKEN=your-refresh-token
GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# === Budget Guardrails ===
MONTHLY_SPEND_LIMIT_USD=100
ALERT_THRESHOLD_PERCENT=75
If you are running Openclaw on a shared server, consider encrypting the .env file at rest using gpg or a similar tool, decrypting it only when the service starts. For anything beyond a single-server hobby deployment, move to Docker secrets or a dedicated vault.
Docker Secrets for Simple Deployments
Docker secrets provide a meaningful upgrade over plain .env files. Secrets are stored encrypted in Docker's internal Raft log, mounted as in-memory files inside the container (never written to disk), and accessible only to containers that are explicitly granted access. This eliminates the risk of a .env file being accidentally copied, backed up unencrypted, or read by another process on the host.
First, create each secret:
# Create secrets from literal values
echo "sk-ant-your-real-anthropic-key" | docker secret create anthropic_api_key -
echo "123456:ABC-your-telegram-token" | docker secret create telegram_bot_token -
echo "your-webhook-signing-secret" | docker secret create webhook_secret -
# Or create from a file
docker secret create gmail_oauth_credentials ./gmail-credentials.json
Then reference the secrets in your docker-compose.yml:
version: "3.8"
services:
openclaw:
image: openclaw/openclaw:latest
secrets:
- anthropic_api_key
- telegram_bot_token
- webhook_secret
environment:
# Non-sensitive config can remain as env vars
ANTHROPIC_MODEL: claude-sonnet-4-20250514
ANTHROPIC_MAX_TOKENS_PER_REQUEST: "4096"
MONTHLY_SPEND_LIMIT_USD: "100"
# Tell Openclaw where to find secret files
ANTHROPIC_API_KEY_FILE: /run/secrets/anthropic_api_key
TELEGRAM_BOT_TOKEN_FILE: /run/secrets/telegram_bot_token
WEBHOOK_SECRET_FILE: /run/secrets/webhook_secret
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
security_opt:
- no-new-privileges:true
read_only: true
secrets:
anthropic_api_key:
external: true
telegram_bot_token:
external: true
webhook_secret:
external: true
Inside the container, each secret is available as a file at /run/secrets/<secret_name>. The file is mounted in a tmpfs filesystem, so it exists only in memory and never touches the container's disk layer. If the container is compromised and the attacker gains filesystem access, they cannot extract secrets from the image layers or volume mounts.
We handle API key security so you don't have to.
Our Business plan includes Docker secrets configuration, automatic rotation, and least-privilege scoping for every integration. Deployed and hardened in under 24 hours.
View PlansAutomatic Secret Rotation
Even with perfect storage, keys should be rotated regularly. Rotation limits the blast radius of a compromised secret: if an attacker obtains a key that is rotated every 90 days, their window of access is bounded. Without rotation, a stolen key works forever (or until you notice, which can take months).
Here is a recommended rotation schedule based on risk level:
- Every 60 days: GitHub PATs, any token with write access to source code
- Every 90 days: Anthropic API key, messaging platform tokens, webhook secrets
- Every 180 days: OAuth refresh tokens (Gmail, Google Calendar)
- Immediately: Any key you suspect has been exposed
You can automate Anthropic key rotation with a script that generates a new key via the Anthropic console API, updates your deployment, and revokes the old key. Here is an outline:
#!/bin/bash
# rotate-anthropic-key.sh
# Rotates the Anthropic API key for an Openclaw deployment
# Run via cron: 0 3 1 */3 * /opt/openclaw/scripts/rotate-anthropic-key.sh
set -euo pipefail
LOG_FILE="/var/log/openclaw/key-rotation.log"
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
log() { echo "[$TIMESTAMP] $1" >> "$LOG_FILE"; }
log "Starting Anthropic API key rotation"
# Step 1: Generate a new key via the Anthropic Admin API
NEW_KEY=$(curl -s -X POST https://api.anthropic.com/v1/organizations/keys \
-H "Authorization: Bearer $ANTHROPIC_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "openclaw-prod-'"$TIMESTAMP"'", "workspace_id": "'"$WORKSPACE_ID"'"}' \
| jq -r '.api_key')
if [ -z "$NEW_KEY" ] || [ "$NEW_KEY" = "null" ]; then
log "ERROR: Failed to generate new API key"
exit 1
fi
log "New key generated successfully"
# Step 2: Update Docker secret
echo "$NEW_KEY" | docker secret create "anthropic_api_key_${TIMESTAMP}" -
# Step 3: Update the service to use the new secret
docker service update \
--secret-rm anthropic_api_key \
--secret-add "source=anthropic_api_key_${TIMESTAMP},target=anthropic_api_key" \
openclaw_openclaw
log "Service updated with new key"
# Step 4: Verify the deployment is healthy
sleep 10
HEALTH=$(docker inspect --format='{{.State.Health.Status}}' \
$(docker ps -q -f name=openclaw_openclaw))
if [ "$HEALTH" != "healthy" ]; then
log "ERROR: Service unhealthy after rotation. Rolling back."
docker service rollback openclaw_openclaw
exit 1
fi
# Step 5: Revoke the old key (after confirming new key works)
OLD_KEY_ID=$(cat /opt/openclaw/state/current-key-id)
curl -s -X DELETE "https://api.anthropic.com/v1/organizations/keys/$OLD_KEY_ID" \
-H "Authorization: Bearer $ANTHROPIC_ADMIN_TOKEN"
echo "$NEW_KEY_ID" > /opt/openclaw/state/current-key-id
log "Old key revoked. Rotation complete."
Schedule this with cron to run quarterly at 3 AM UTC on the first of the month:
# /etc/cron.d/openclaw-key-rotation
0 3 1 */3 * deploy /opt/openclaw/scripts/rotate-anthropic-key.sh 2>&1 | logger -t openclaw-rotation
For messaging platform tokens, the process is similar but platform-specific. Telegram tokens are rotated via @BotFather, WhatsApp tokens through the Meta Business API, and Discord tokens through the Developer Portal. Document each rotation procedure for your deployment.
Least-Privilege Scoping
Rotation limits how long a compromised key is useful. Least-privilege scoping limits what the key can do in the first place. The principle is straightforward: every integration gets only the permissions it needs and nothing more.
Anthropic API keys: Use workspace-level keys rather than organization-level keys. A workspace key can only access models and resources within that workspace, so a compromised key cannot affect billing or resources in other workspaces. If the Anthropic Admin API supports it, create a key scoped specifically to the models Openclaw uses (e.g., Claude Sonnet only, not Opus).
GitHub Personal Access Tokens: Always use fine-grained PATs instead of classic tokens. Classic tokens grant broad access to every repository in your account. Fine-grained PATs let you specify exactly which repositories the token can access and what operations it can perform:
# Fine-grained PAT scope example:
# Repository access: Only select repositories (e.g., "my-org/my-project")
# Permissions:
# Contents: Read-only
# Issues: Read and write
# Pull requests: Read and write
# Metadata: Read-only
#
# This is vastly safer than a classic token with "repo" scope,
# which grants full read/write access to ALL repositories.
Messaging bot permissions: Telegram bots should disable "Group Privacy" mode off (so they only see commands directed at them, not all group messages) unless Openclaw explicitly needs full message access. Discord bots should request only the intents they need: if Openclaw only responds to direct messages, do not enable the "Message Content" privileged intent for servers. Slack apps should use granular OAuth scopes like chat:write and channels:read instead of the legacy admin scope.
Gmail OAuth: Request only the scopes Openclaw needs. If the agent only reads email, do not request the gmail.send scope. Use gmail.readonly instead. If it needs to send, scope it to gmail.send without gmail.modify.
Detecting Compromised Keys
Even with strong storage, rotation, and scoping, you need to detect when something goes wrong. Monitoring is your last line of defense.
Monitor API usage patterns: Set up alerts in the Anthropic console for unusual activity. A sudden spike in token usage outside your normal hours, requests from unfamiliar IP addresses, or model usage that does not match your Openclaw configuration (e.g., Opus calls when your agent only uses Sonnet) are all red flags.
Configure billing alerts: In the Anthropic console, set budget alerts at 50%, 75%, and 90% of your monthly spending cap. If you receive a 50% alert on the third day of the month, something is wrong. Act immediately.
Enable GitHub secret scanning: If your Openclaw configuration lives in a GitHub repository (even a private one), enable secret scanning in the repository settings. GitHub will alert you if any known secret patterns (including Anthropic API keys) appear in your commit history. Enable push protection to block commits that contain secrets before they reach the remote.
If a key is compromised, follow this sequence:
- Revoke immediately. Do not investigate first. Revoke the key in the provider's console. Every second it remains active is a second the attacker can use it.
- Generate a new key and update your deployment using the rotation procedure above.
- Audit usage logs. Check Anthropic's usage dashboard, messaging platform delivery reports, and any integration audit logs for unauthorized activity during the exposure window.
- Determine the source. How was the key exposed? Committed to a repo? Server compromise? Insider access? Fix the root cause.
- Rotate adjacent secrets. If the attacker had access to one secret, assume they had access to all secrets stored in the same location. Rotate everything in that
.envfile or secret store.
Skip the Security Guesswork
Get Openclaw professionally installed and hardened on your infrastructure in under 24 hours. Every plan includes proper secret management. Plans from $2,449 (one-time).
Dive deeper into Openclaw security: