Best API Key Management Practices for Dev Teams
Good API key management comes down to five things: keys are never stored in plaintext or committed to source control, each key is scoped to the minimum access it needs, keys can be rotated or revoked without downtime, usage is visible per key, and someone other than "whoever set it up two years ago" can answer who has access to what. Most security incidents involving API keys aren't sophisticated attacks — they're a key sitting in a public GitHub repo, a .env file shared over Slack, or a key that outlived the contractor who created it.
The rest of this article covers the practical setup that gets you there, whether you're managing your own service's keys, third-party API keys your team depends on, or both.
Storage: get keys out of your codebase
The single highest-impact change most teams can make is removing keys from application code entirely.
- Use environment variables loaded from a secrets manager (AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, or even your CI/CD provider's built-in secrets store) rather than
.envfiles committed anywhere. - Add a pre-commit hook or CI check that scans for common key patterns (
sk_,AKIA,sub_live_, etc.) before code merges. - Never log full API keys. Log a truncated prefix (
sub_live_9f2a...) so you can identify a key in an incident without exposing it.
If a key does leak, the only real mitigation is revoking it fast — which means you need infrastructure for revocation that doesn't require redeploying your app.
Scoping: one key, one job
Flat, all-access keys are the biggest source of blast radius in a breach. Best practice is to scope keys as narrowly as the platform allows:
- Per-environment keys. Separate keys for development, staging, and production. A leaked dev key should never touch production data.
- Per-service or per-team keys. If three internal services call the same API, give each one its own key. When something misbehaves, you know exactly which service to look at.
- Read vs. write separation, where the provider supports it. A reporting dashboard should never hold a key that can also delete records.
This is also where usage attribution pays off — if every consuming service has its own key, a spike in error rate or cost points you straight at the source instead of triggering a wider investigation.
Rotation and revocation
Keys should have an expected lifetime, not live forever. A workable policy for most teams:
- Rotate keys on a fixed schedule (quarterly is common for internal services, shorter for anything customer-facing).
- Rotate immediately on personnel changes — anyone with key access leaving the team is a trigger, not an optional step.
- Support overlapping validity during rotation: issue the new key, update consumers, confirm traffic has shifted, then revoke the old one. Hard cutovers cause outages and push teams toward "we'll rotate it later," which becomes never.
- Keep an audit log of key creation, rotation, and revocation events, with who did it and when.
If your provider doesn't support instant revocation or shows you no creation/revocation history, that's a real limitation worth weighing before you standardize on it.
Visibility: know what's actually happening
Key management isn't just storage and rotation — it's also knowing how keys are being used after they're issued. At minimum you want:
- Per-key request volume and error rates
- Alerts on unusual spikes (a sign of either a bug or a leaked key being abused)
- A dashboard, not a spreadsheet, that shows every active key, who created it, and when it was last used
Dead keys with zero recent usage are low-hanging fruit for revocation — they're pure attack surface with no upside.
Where SubToAPI fits into this
If you're using Claude through a personal or team subscription and exposing it internally as an API — for a script, an internal tool, or a product feature — you inherit all of the same key management problems, and SubToAPI is built specifically around handling them well.
Instead of one shared credential passed around a team, SubToAPI issues scoped sub_live_... application keys per project or environment, each independently revocable from the dashboard. You get per-key usage metadata (requests, tokens, errors) so you can see exactly which integration is driving traffic or costs, without digging through raw logs. Team and Scale plans add seats, so individual team members work under their own access rather than a key copy-pasted into three different .env files.
A minimal setup looks like this:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this changelog."}]
}'
Store SUBTOAPI_KEY as an environment variable, generate a separate key per environment, and rotate it from the dashboard when a project ends or a team member offboards — no code changes required on your side. The quickstart walks through initial setup, and the messages and streaming docs cover request formats if you're integrating into an existing app. Plans and seat pricing are on the pricing page, and you can start on the free trial from signup.
A short checklist
- [ ] No keys in source control or committed config files
- [ ] Keys loaded from environment variables or a secrets manager
- [ ] Separate keys per environment and per consuming service
- [ ] Rotation schedule defined and followed
- [ ] Revocation path that doesn't require a deploy
- [ ] Per-key usage visibility and alerting on anomalies
- [ ] Audit trail of who created, rotated, or revoked each key
None of these individually is complicated. The failure mode is almost always that teams do two or three of them and skip the rest, usually storage and scoping, because they feel like overhead until the day a key leaks.
questions
What's the single most important API key management practice? Scoping. A narrowly scoped key limits damage even if it leaks or is misused, while a flat, all-access key turns any single leak into a full compromise.
How often should API keys be rotated? Quarterly is a reasonable default for internal services; shorter cycles make sense for customer-facing or high-privilege keys. Rotate immediately, regardless of schedule, when someone with access leaves the team.
Is a secrets manager necessary for small teams? Yes, even at small scale. A basic secrets manager or your CI/CD provider's built-in secrets store costs little to set up and eliminates the most common leak vector: keys committed to a repository or shared in chat.