Secret Management
Best practices for storing and managing apikee signing secrets.
Secret Management
What needs to be kept secret
| Secret | Where it lives | Who sees it |
|---|---|---|
Signing secret (secrets[0]) | Server-side only | Your app's runtime environment |
apikee.dev project key (sk_live_...) | Server-side only | Your app's runtime environment |
Customer API key (apikee_...) | Given to the customer | Your customer |
Customer API keys are not secret to your server — they're designed to be passed on every request. The security comes from the HMAC signature: the key can only be created by someone who knows the signing secret.
Storing signing secrets
Never hardcode secrets in source code. Use environment variables or a secrets manager:
# .env (local development only — never commit)
APIKEE_SECRET=sk-local-dev-secret-change-this
APIKEE_SERVER_KEY=sk_live_abc123...import os
from apikee import Apikee
apikee = Apikee(
secrets=[os.environ["APIKEE_SECRET"]],
server_key=os.environ.get("APIKEE_SERVER_KEY"),
project_env=os.environ.get("APIKEE_PROJECT_ENV", "my-api-production"),
)Secret strength
Signing secrets should be:
- At least 32 bytes (256 bits) of entropy
- Generated with a cryptographically secure random source
Generate a strong secret:
# Unix/macOS
openssl rand -hex 32
# Python
python3 -c "import secrets; print(secrets.token_hex(32))"
# Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Secrets managers
For production, use a secrets manager instead of environment variables:
# AWS Secrets Manager
import boto3, json
secret = json.loads(boto3.client("secretsmanager")
.get_secret_value(SecretId="apikee/signing-secret")["SecretString"])
apikee = Apikee(secrets=[secret["current"], secret.get("previous", "")])// HashiCorp Vault
const { data } = await vault.read('secret/apikee')
const apikee = new Apikee({ secrets: [data.current, data.previous].filter(Boolean) })What the customer key contains
Customer keys (apikee_...) embed their own claims. They are not random tokens — they contain:
- Tenant ID
- Scopes
- Expiry timestamp
- Metadata
This is by design. The embedded data is authenticated (HMAC signature prevents modification) but not encrypted (the base62 payload can be decoded by anyone who has the key). Do not embed sensitive data (passwords, SSNs, credit card numbers) in the meta field.
Never embed secrets, passwords, or PII in key metadata. The metadata is visible to anyone who holds the key.
GitHub secret scanning
The apikee_ prefix is designed to be picked up by secret scanners. If you accidentally commit a key:
- Revoke it immediately via the apikee.dev dashboard or the API
- Rotate the signing secret if you committed the signing secret itself
- Use
git filter-repoorgit-secretsto clean the commit history
Add apikee patterns to your scanner config:
# .github/secret_scanning.yml
patterns:
- pattern: 'apikee_[0-9A-Za-z]+\.[0-9A-Za-z]+'
name: apikee customer key
- pattern: 'sk_live_[0-9A-Za-z]+'
name: apikee platform key
