API Key Management
Created: Tue 29 Jul 2025 10:45:00 CEST
Updated: Thu 11 Jun 2026 15:46:06 CEST - Key rotation performed (director-prod-v1 → gateway-prod-v2); canonical env var renamed DIRECTOR_API_KEY → GATEWAY_API_KEY (old name accepted as fallback during transition); auth module renamed director_auth.py → gateway_auth.py; new key prefix gw_
Document Version: 1.1 - Gateway key rotation and naming update
Security Classification: Internal Security Documentation
Target Audience: DevOps Engineers, Security Team, System Administrators
Author: Paul Wisén
Overview
This document describes the secure generation and management of API keys for the Plings ecosystem, specifically for service-to-service authentication between the Gateway (s.plings.io) and Backend API (api.plings.io).
Security Principles
- Never generate API keys in chat systems (Claude, ChatGPT, etc.)
- Never commit API keys to version control
- Rotate keys regularly (recommended: every 90 days)
- Use different keys for each environment (dev, staging, production)
- Monitor key usage for anomalies
Generating Secure API Keys
Method 1: Using OpenSSL (Recommended)
# Generate a 64-character hex string
openssl rand -hex 32
# Add the gw_ prefix for Gateway keys
echo "gw_$(openssl rand -hex 32)"
Method 2: Using Python
import secrets
api_key = f"gw_{secrets.token_hex(32)}"
print(api_key)
Method 3: Using Node.js
const crypto = require('crypto');
const apiKey = `gw_${crypto.randomBytes(32).toString('hex')}`;
console.log(apiKey);
Key Format Standards
Gateway API Keys
- Format:
gw_<64-character-hex-string>(keys issued before the June 2026 rotation used thedir_prefix) - Example:
gw_a1b2c3d4e5f6...(64 hex characters) - Purpose: Identifies Gateway service to Backend API
Future Key Types
- User API Keys:
usr_<64-character-hex-string> - Service Keys:
svc_<64-character-hex-string> - Webhook Keys:
whk_<64-character-hex-string>
Configuration Locations
Gateway Service (s.plings.io)
- Vercel Dashboard: Plings-Gateway project → Settings → Environment Variables
- Variable Name:
GATEWAY_API_KEY(canonical).DIRECTOR_API_KEYis still read as a fallback by the Gateway code during the rename transition. - Environments: Set for Production, Preview, and Development separately
Backend API (api.plings.io)
- Vercel Dashboard: Plings-API project → Settings → Environment Variables
- Variable Name:
GATEWAY_API_KEY(canonical;DIRECTOR_API_KEYaccepted as fallback) - Default: the built-in development key applies only outside Vercel (local dev). In production, validation relies on the env var or the hashed key registry in
app/gateway_auth.py.
Key Storage in Backend
The backend stores only the first 12 characters of the SHA256 hash of API keys:
import hashlib
def hash_api_key(api_key: str) -> str:
"""Hash an API key for storage/comparison."""
return hashlib.sha256(api_key.encode()).hexdigest()[:12]
This ensures that even if the backend database is compromised, the actual API keys cannot be recovered.
Key Rotation Process
1. Generate New Key
NEW_KEY="gw_$(openssl rand -hex 32)"
echo "New API Key: $NEW_KEY"
echo "Hash for backend: $(echo -n $NEW_KEY | shasum -a 256 | cut -c1-12)"
2. Update Backend First
Add the new key hash to app/gateway_auth.py:
GATEWAY_API_KEYS = {
"new_hash_here": {
"name": "gateway-prod-vN",
"created": "YYYY-MM-DD",
"active": True
},
# Keep old key active during transition
"old_hash_here": {
"name": "gateway-prod-vN-1",
"created": "YYYY-MM-DD",
"active": True
}
}
3. Deploy Backend
Deploy the backend with both keys active.
4. Update Gateway
Update the GATEWAY_API_KEY environment variable in Vercel (Plings-Gateway project) with the new key value.
5. Verify New Key
Test the Gateway service with the new key.
6. Deactivate Old Key
After verification, set the old key’s active to False in the backend.
Security Monitoring
What to Monitor
- Failed authentication attempts - Multiple failures may indicate attempted breach
- Unusual request patterns - Spike in requests or unusual times
- Geographic anomalies - Requests from unexpected locations
- Rate limit violations - May indicate abuse
Logging Requirements
All API key usage should be logged with:
- Timestamp
- Key identifier (name, not the actual key)
- Source IP (hashed)
- Success/failure status
- Request path
Emergency Procedures
If a Key is Compromised
- Immediately deactivate the key in the backend
- Generate a new key using the secure methods above
- Update all services using the compromised key
- Review logs for unauthorized usage
- Notify security team and stakeholders
Backend Emergency Override
If all keys are compromised, the backend can be temporarily configured to reject all Gateway requests:
# In gateway_auth.py
EMERGENCY_LOCKDOWN = True # Set via environment variable
Best Practices
- Environment-Specific Keys: Never use production keys in development
- Least Privilege: Each service should have only the permissions it needs
- Regular Audits: Review active keys quarterly
- Documentation: Keep a secure record of which keys are used where
- No Hardcoding: Always use environment variables
Compliance Notes
- API keys are considered sensitive data under GDPR
- Key generation and rotation should be logged for audit trails
- Access to production keys should be restricted to authorized personnel only