API key management
How to issue, store, scope, and rotate Bastion API keys without leaking them.
API keys (qbt_...) are the only credential the Bastion API accepts. Treat them like passwords — leakage is a billing and data-access risk.
Issue one key per environment and per service
Use a distinct key for each combination of (environment, service). Keys are cheap to create and they give you a clean audit and revocation surface.
| Environment | Service | Example key label |
|---|---|---|
dev | local laptop | dev-laptop-<initials> |
staging | api worker | staging-api-worker |
prod | api worker | prod-api-worker |
prod | batch job | prod-batch-nightly |
Mixing environments (one key powering both staging and prod) defeats audit logs and means revoking a leak takes down everything.
Store keys in a secrets manager — never in client code
A key in client-side JavaScript, a mobile app binary, or a public Git history is compromised the moment it ships. Acceptable homes:
- AWS Secrets Manager / SSM Parameter Store
- HashiCorp Vault
- GCP Secret Manager
- GitHub Actions / GitLab CI encrypted secrets
- 1Password / Doppler (for developer machines)
Inject the secret as an environment variable at runtime — code should only ever read it via process.env.QUBITTRON_API_KEY (or your platform's equivalent).
Rotate on a schedule and on suspected exposure
The dashboard supports rolling rotation: create a new key, deploy services to use it, then revoke the old one. Old and new keys coexist until you revoke, so there's no downtime.
Trigger an immediate rotation when:
- A key appears in a log, an error report, a stack trace, or a screenshot.
- A laptop with developer keys is lost or sold.
- An employee with key access leaves the company.
- A
git log -pshows a key was ever committed (even if reverted — assume Git history is forever).
Test that a key works
A small smoke test is useful right after issuing or rotating a key. It costs nothing and confirms the key is live before you depend on it in code:
curl https://api.qubittron.ai/v1/models \
-H "Authorization: Bearer $QUBITTRON_API_KEY" \
-o /dev/null -w "%{http_code}\n"A 200 means the key is live. A 401 means it's missing, malformed, or revoked.
Never log or echo the raw key
Redact secrets at the logging boundary. Most logging libraries support a redactor or a structured-logging pattern that drops known-secret fields:
const safeHeaders = {
...headers,
authorization: headers.authorization ? "Bearer qbt_***" : undefined,
};
logger.info({ url, headers: safeHeaders }, "outbound request");Treat error reporters (Sentry, Datadog, etc.) the same way — accidentally shipping headers in an error payload is a common leak path.