API Security
API key rotation, signature verification, and rate limiting
API Security Enhancements
Overview
This document describes the API security enhancements implemented for the telegram-bot and github-bot applications. These enhancements provide:
- API Key Rotation Mechanism - Automatic and manual API key rotation with grace periods
- Enhanced Webhook Signature Verification - Timestamp validation to prevent replay attacks
- Per-API-Key Rate Limiting - Durable rate limiting using D1 storage
- Request Throttling - Concurrency limits and delays for expensive operations
Architecture
The security features are implemented in a shared package @duyetbot/api-security that can be used across all applications.
Features
1. API Key Management
API Key Format
API keys follow the format: sk_{version}_{random}_{checksum}
sk_- Prefix for security identificationversion- Key version number (starts at 1)random- 32 cryptographically random bytes (64 hex chars)checksum- CRC-32 checksum for validation (8 hex chars)
Example: sk_1_a1b2c3d4e5f6..._12345678
Key Rotation
Automatic Rotation
- Keys older than 90 days should be rotated
- Old keys remain valid for a configurable grace period (default: 7 days)
- New keys increment the version number
Manual Rotation
Storage Schema
2. Enhanced Webhook Signature Verification
GitHub Webhooks
The signature verification middleware now:
- Extracts timestamp from
x-github-deliveryheader - Validates HMAC-SHA256 signature
- Checks timestamp age (default: 5 minutes)
- Uses timing-safe comparison to prevent timing attacks
Replay Attack Prevention
- Timestamps older than 5 minutes are rejected
- Clock skew tolerance: 30 seconds
- Future timestamps beyond skew are rejected
3. Per-API-Key Rate Limiting
Rate limiting is now enforced per API key using D1 storage:
Default Configuration
- Requests per minute: 60
- Burst limit: 10 requests
- Burst window: 10 seconds
- Throttle duration: 60 seconds
Storage Schema
Usage
4. Request Throttling
In-memory throttling for expensive operations:
Default Configuration
- Max concurrent operations: 3
- Delay between operations: 1000ms
- Window: 60 seconds
Usage
Hono Middleware
Migration Guide
Step 1: Initialize D1 Storage
Step 2: Create Initial API Key
Step 3: Update Application Code
GitHub Bot - Already updated:
Telegram Bot - Add API key authentication:
Step 4: Configure Environment Variables
Best Practices
API Key Management
- Store keys securely - Never commit API keys to git
- Use descriptive names - Help identify key purpose
- Rotate regularly - Every 90 days for production keys
- Monitor usage - Check audit logs for suspicious activity
- Revoke unused keys - Clean up old or compromised keys
Rate Limiting
- Set appropriate limits - Based on your usage patterns
- Monitor throttling - Track rate limit events
- Use priority queuing - For important operations
- Provide clear feedback - Include retry-after headers
Webhook Security
- Always verify signatures - Never skip signature verification
- Use short TTLs - 5 minutes or less for timestamp validation
- Log failures - Track failed verification attempts
- Monitor replay attacks - Alert on repeated old timestamps
Monitoring and Auditing
Audit Log Events
The audit log tracks all API key operations:
created- New API key createdrotated- Key rotated to new versionrevoked- Key manually revokedexpired- Key expired naturallyused- Key used for authentication
Viewing Audit Logs
Checking Keys Needing Rotation
Security Checklist
- API keys are stored with SHA-256 hashing
- Webhook signatures are verified with timestamp validation
- Rate limiting is enabled per API key
- Expensive operations are throttled
- Audit logs are enabled and monitored
- API keys are rotated every 90 days
- Unused keys are revoked
- Rate limit events are monitored
- Failed signature verifications are logged
- Timestamp validation prevents replay attacks
Troubleshooting
API Key Validation Fails
Symptom: 401 errors with "KEY_NOT_FOUND" or "KEY_EXPIRED"
Solutions:
- Check if key is active:
SELECT * FROM api_keys WHERE key_id = ? - Verify expiration:
SELECT expires_at FROM api_keys WHERE key_id = ? - Check usage count and last used timestamp
- Review audit log for key events
Rate Limiting Too Aggressive
Symptom: Legitimate requests are being throttled
Solutions:
- Adjust
requestsPerMinutefor the API key - Increase
maxBurstfor bursty traffic - Check
throttle_untiltimestamp inapi_rate_limitstable - Reset rate limit:
DELETE FROM api_rate_limits WHERE key_id = ?
Webhook Signature Verification Fails
Symptom: 401 errors on valid webhooks
Solutions:
- Verify
GITHUB_WEBHOOK_SECRETmatches GitHub configuration - Check if timestamp is within acceptable range (5 minutes)
- Verify clock skew tolerance (30 seconds default)
- Check logs for specific verification failure reason