API Keys and Webhook Security – Best Practices
API keys and webhooks sit on the critical path of most modern integrations. If key storage is weak or signature verification is skipped, a small implementation shortcut can become a real security incident. This guide focuses on the operational details that matter: key generation, secret handling, rotation, and request verification.
1. Generating API Keys
API keys should be cryptographically random. Avoid predictable patterns or sequential IDs. Common formats include:
- Hex: 32 or 64 character strings for internal systems.
- Base64 (URL-safe): Compact encoding for tokens and JWTs.
- Bearer / sk_ prefix: Used by OpenAI, Stripe, and many SaaS platforms.
Use our API Key Generator to create keys in various formats — all processing happens in your browser, so keys never leave your device.
2. Storing API Keys Safely
Never commit API keys to version control. Use environment variables, secret managers (AWS Secrets Manager, HashiCorp Vault), or platform-specific solutions like Vercel Environment Variables.
Rotate keys periodically and revoke compromised keys immediately. For production, prefer short-lived tokens (OAuth) over long-lived API keys when possible.
3. Webhook Signature Verification
Webhooks from GitHub, Stripe, Slack, and similar services include an HMAC signature in the request header (e.g., X-Hub-Signature-256). This proves the payload was not tampered with and originated from the expected service.
Always verify the signature before processing a webhook. Use the raw request body (not parsed JSON) when computing the HMAC, as parsing can alter the payload.
Use the Webhook Tester to verify HMAC-SHA256 signatures locally and build replay requests for endpoint testing.
4. Implementation: Key Generation & HMAC Verification
Generate API keys with crypto.getRandomValues:
// Hex API key (32 bytes = 64 hex chars)
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
const hexKey = Array.from(bytes).map(b => b.toString(16).padStart(2,'0')).join('');
// Base64 URL-safe (for tokens)
const b64 = btoa(String.fromCharCode(...bytes)).replace(/\+/g,'-').replace(/\//g,'_');Verify webhook HMAC-SHA256 (use raw body, not parsed JSON):
async function verifyWebhook(rawBody, signature, secret) {
const key = await crypto.subtle.importKey(
'raw', new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
);
const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(rawBody));
const expected = 'sha256=' + Array.from(new Uint8Array(sig))
.map(b => b.toString(16).padStart(2,'0')).join('');
// Use constant-time comparison (e.g. Node crypto.timingSafeEqual) in production
return signature === expected;
}5. Conclusion
API keys and webhooks require careful handling. Generate keys with cryptographically secure randomness, store them in secret managers, and always verify webhook signatures before processing. These practices protect your application and your users' data.
6. Key rotation strategy
Rotation should be planned, not reactive. The safest approach is overlapping keys: issue a new key, update clients, monitor usage, then revoke the old key after a grace period.
- Create a new key and mark it as active.
- Notify or migrate clients to the new key.
- Log remaining traffic on the old key.
- Revoke old key after adoption threshold is met.
7. Webhook hardening beyond signature checks
- Timestamp verification: reject stale requests to reduce replay windows.
- Event idempotency: store processed event IDs and ignore duplicates.
- Source controls: where supported, combine signature checks with IP allowlists.
- Fail-safe responses: return clear non-2xx codes for invalid signatures.
8. Incident readiness checklist
When secrets leak, response speed matters more than perfect forensics. Keep a simple playbook so teams can rotate keys and restore trust quickly.
- Revoke exposed keys immediately and issue replacements.
- Invalidate cached credentials in workers and edge nodes.
- Audit suspicious webhook traffic by signature status and source.
- Publish internal timeline and follow-up remediation tasks.