Skip to main content

API Key Management: Generation, Rotation, and Revocation

·APIScout Team
api securityapi keyskey managementauthenticationbest practices

API Key Management: Generation, Rotation, and Revocation

API keys are the most common authentication method for APIs. They're simple, effective, and universally understood. But simplicity creates risk — a leaked key is a breached system. Secure key management covers the full lifecycle: generation, storage, distribution, rotation, and revocation.

API Key Lifecycle

Generate → Distribute → Use → Monitor → Rotate → Revoke
    ↑                                        |
    └────────────────────────────────────────┘

Key Generation

Format Matters

Good API keys are:

  • Identifiable — prefixed so you know what they are
  • Unique — cryptographically random, no collisions
  • Secure — enough entropy to resist brute force

Prefix patterns from top APIs:

APIKey FormatPurpose
Stripesk_live_..., sk_test_...Environment + type
GitHubghp_..., ghs_..., ghu_...Scope (personal, server, user-to-server)
OpenAIsk-proj-...Project-scoped
AWSAKIA... (20 chars)IAM access key
Twilio34-char hex stringAccount SID + Auth Token

Recommended format:

{provider}_{environment}_{random}

Examples:
  myapi_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
  myapi_test_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4

Generation Best Practices

✅ Use crypto.randomBytes(32) or equivalent (256 bits of entropy)
✅ Use a prefix that identifies the key type and environment
✅ Make keys long enough (40+ characters) to prevent brute force
✅ Generate server-side only — never on the client

❌ Don't use UUIDs (only 122 bits of entropy, predictable structure)
❌ Don't use sequential IDs
❌ Don't derive keys from user data (email, username)
❌ Don't use short keys (<32 characters)

Key Storage

Server-Side (Your Database)

Never store API keys in plain text. Hash them like passwords:

What you store:        SHA-256(api_key) or bcrypt(api_key)
What the user sees:    sk_live_a1b2c3d4... (shown once, never again)
What you compare:      SHA-256(incoming_key) === stored_hash

Show the full key exactly once — at creation time. After that, show only the last 4 characters: sk_live_...o5p6.

Key Metadata

Store alongside the hash:

FieldPurpose
key_hashSHA-256 hash for lookup
key_prefixFirst 8 chars for identification
key_suffixLast 4 chars for display
user_idOwner of the key
nameUser-defined label ("Production Server")
scopesPermissions (read, write, admin)
created_atWhen the key was generated
last_used_atLast successful authentication
expires_atExpiration date (null = never)
rate_limitPer-key rate limit override
ip_allowlistRestrict to specific IPs

Client-Side (Developer's App)

Developers need to store API keys securely in their applications:

EnvironmentStorage MethodSecurity
Backend serverEnvironment variablesGood
Backend serverSecrets manager (AWS SM, Vault)Best
Mobile appKeychain (iOS) / Keystore (Android)Good
BrowserNever store API keys in frontend codeN/A
CI/CDPipeline secrets (GitHub Secrets, etc.)Good

Never commit API keys to source code. Use environment variables or secret managers.

Key Scoping

Permission Levels

Not all keys should have the same access:

ScopeAccessUse Case
readGET onlyPublic dashboards, read-only integrations
writeGET + POST + PUTStandard API usage
adminFull access + key managementAccount administration
billingBilling endpoints onlyFinance integrations

Resource Scoping

Limit keys to specific resources:

{
  "key": "sk_live_...",
  "scopes": ["orders:read", "orders:write", "products:read"],
  "resources": {
    "organizations": ["org_123"],
    "projects": ["proj_456", "proj_789"]
  }
}

A key scoped to orders:read can't access user data, even if the API has user endpoints.

Environment Separation

Always separate test and production keys:

Key TypePrefixAccessBilling
Testsk_test_Sandbox onlyNo charges
Livesk_live_ProductionReal charges

Test keys should never work in production. Production keys should never work in sandbox.

Key Rotation

Why Rotate

  • Reduce blast radius of leaked keys
  • Comply with security policies (SOC 2, PCI DSS)
  • Limit exposure window
  • Force key hygiene

Rotation Policy

Key TypeRotation PeriodEnforcement
Production API keysEvery 90 daysRecommended, warn at 60 days
Service-to-service keysEvery 30 daysAutomated rotation
CI/CD keysEvery 90 daysPipeline-enforced
Admin keysEvery 30 daysRequired
Test keysNo rotation neededOptional

Graceful Rotation (Overlap Period)

Never invalidate the old key immediately. Allow an overlap period:

Day 0:  Generate new key → Both old and new keys work
Day 1-7: Developer updates their applications to use new key
Day 7:  Old key is revoked

During overlap: Both keys authenticate successfully
After overlap:  Only new key works

Automated Rotation

For service-to-service keys, automate the entire process:

1. Secrets manager generates new key
2. New key is registered with the API
3. Secrets manager updates the consuming service's config
4. Service restarts or hot-reloads the new key
5. Old key is revoked after grace period
6. Audit log records the rotation

Tools: AWS Secrets Manager, HashiCorp Vault, Doppler, 1Password Connect

Key Revocation

When to Revoke

TriggerActionUrgency
Key leaked in public repoImmediate revocationEmergency
Employee leaves companyRevoke their keysSame day
Key compromisedImmediate revocationEmergency
Key unused for 90+ daysRevoke with notificationLow
Key rotation completeRevoke old keyScheduled

Revocation Process

1. Mark key as revoked in database (don't delete — keep for audit)
2. Clear key from all caches
3. Return 401 with clear error: "API key has been revoked"
4. Log the revocation event with reason
5. Notify the key owner (email, webhook, dashboard alert)
6. If emergency: check for unauthorized usage in recent logs

GitHub's Automatic Revocation

GitHub scans public repositories for leaked API keys and automatically:

  1. Notifies the API provider
  2. Provider revokes the key
  3. Notifies the developer

If you're an API provider, join GitHub's Secret Scanning Partner Program to get automatic leak notifications.

Monitoring and Alerts

What to Monitor

SignalIndicatesAlert Threshold
Key used from new IPPotential compromiseAny new IP (notify)
Sudden usage spikeAbuse or compromise5x normal volume
Key used from unexpected countryPotential compromiseAny unexpected location
Failed auth attemptsBrute force attack10+ failures in 1 minute
Key approaching expirationNeeds rotation14 days before expiry
Key unused for 60+ daysOrphaned keyNotify owner

Audit Logging

Every key event should be logged:

{
  "event": "api_key.used",
  "key_prefix": "sk_live_a1b2",
  "ip": "203.0.113.42",
  "endpoint": "POST /api/orders",
  "timestamp": "2026-03-08T14:30:00Z",
  "user_agent": "MyApp/2.1",
  "status": 200
}

Log these events: key.created, key.used, key.rotated, key.revoked, key.expired, key.auth_failed.

Patterns from Top APIs

APINotable Practice
StripeTest/live prefix, last 4 visible, scope by mode
GitHubFine-grained tokens with per-repo permissions, auto-expiry
AWSAccess key + secret key pair, IAM policy-based scoping
Google CloudService account JSON keys, workload identity federation
TwilioAccount SID + Auth Token, sub-account isolation

Common Mistakes

MistakeImpactFix
Storing keys in plain textDatabase breach = all keys compromisedHash with SHA-256
No key rotation policyLeaked keys stay valid forever90-day rotation policy
Same key for test and prodTest code accidentally hits productionSeparate keys with prefixes
No scope restrictionsEvery key has admin accessPrinciple of least privilege
Showing full key after creationKeys visible in dashboards, emailsShow once, then mask
No monitoring on key usageCan't detect compromiseAlert on anomalous patterns

Securing your API keys? Explore API security tools and best practices on APIScout — comparisons, guides, and developer resources.

Comments