API Key Rotation Guide
Safely rotate API keys with zero downtime using best practices and automation.
Why Rotate Keys
- Reduce risk window — Shorter key lifespan limits exposure if compromised
- Compliance requirements — Many security frameworks require periodic credential rotation
- Personnel changes — Rotate when team members with key access leave
- Principle of least privilege — Opportunity to review and tighten permissions
Rotation Process (5 Steps)
- Create new key with same permissions — Developer Portal → API Keys → Create. Match the permission set of the existing key.
- Update integration config — Deploy the new key to your application's environment variables or secrets manager.
- Verify new key works — Test with
GET /api/enterprise/v1/pingto confirm authentication succeeds. - Monitor for errors on old key — Wait 1-24 hours, check audit logs for requests still using the old key.
- Revoke old key — Once no traffic uses the old key, revoke it permanently.
Zero-Downtime Rotation
For systems that cannot tolerate any downtime during rotation:
- Create the new key (both keys are now active simultaneously)
- Configure your app to support both keys (try new key, fall back to old)
- Deploy the update — traffic seamlessly shifts to the new key
- Remove fallback logic after confirming new key is working
- Revoke the old key
Note: Both keys remain valid until the old one is explicitly revoked. There is no automatic expiration on API keys.
Automated Rotation (Python Example)
import os, requests, time
PORTAL_API = "https://api.genuinein.com/api/enterprise/v1"
ADMIN_KEY = os.environ["GENUINEIN_ADMIN_KEY"]
def rotate_key(old_key_id):
headers = {"X-API-Key": ADMIN_KEY}
# 1. Create new key with same permissions
resp = requests.post(f"{PORTAL_API}/developer/keys", headers=headers, json={
"name": f"production-key-{int(time.time())}",
"permissions": {"talent": {"search": True, "read": True, "pool": True}}
})
new_key = resp.json()["data"]["api_key"] # Only shown once!
new_key_id = resp.json()["data"]["key_id"]
# 2. Update config (e.g., AWS Secrets Manager)
update_secrets_manager("GENUINEIN_API_KEY", new_key)
# 3. Verify new key works
verify = requests.get(f"{PORTAL_API}/ping",
headers={"X-API-Key": new_key})
assert verify.status_code == 200
# 4. Wait for traffic to shift
time.sleep(300) # 5 minutes
# 5. Revoke old key
requests.delete(f"{PORTAL_API}/developer/keys/{old_key_id}",
headers={"X-API-Key": ADMIN_KEY})
print(f"Rotation complete. New key ID: {new_key_id}")
Rotation Schedule
| Trigger | Action |
|---|---|
| Every 90 days | Recommended routine rotation |
| Personnel change | Mandatory rotation within 24 hours |
| Suspected compromise | Emergency rotation (see below) |
| Security audit finding | Rotation within remediation window |
Emergency Rotation
If a key is suspected or confirmed compromised:
- Revoke immediately — Don't wait for a replacement. Revoke the compromised key now.
- Create new key — Generate a fresh key with appropriate permissions.
- Deploy new key — Update all integrations using the compromised key.
- Review audit logs — Check for unauthorized access during the exposure window.
- Report incident — Document the compromise timeline and actions taken.