Claude API Key Management for Multiple Environments
Managing Claude API keys across development, staging, and production is mostly a discipline problem, not a technical one. The API itself doesn't enforce environment separation for you — if you only have one key, it's trivially easy to accidentally burn production quota from a local test script, or worse, leak a production-capable key into a client-side bundle. The fix is to treat keys as environment-scoped credentials from day one, with clear naming, separate storage, and independent rotation schedules per environment.
This matters more as teams grow. A solo developer can get away with one key and a .env file. A team shipping to staging and production, with multiple engineers and maybe a CI pipeline, needs a structure that prevents cross-contamination — where a bug in staging can't silently rack up production costs, and where revoking a compromised key doesn't take down every environment at once.
Why one key for everything breaks down
A single shared key across environments creates three concrete problems:
- No blast radius containment. If the key leaks (committed to git, logged in an error tracker, exposed in a client bundle), every environment is compromised simultaneously.
- No usage attribution. You can't tell from billing or logs whether traffic came from a developer's laptop, a staging deploy, or real production users.
- No safe rotation. Rotating the key means coordinating a deploy across every environment at once, which is exactly the kind of high-stakes, all-or-nothing change you want to avoid.
The standard fix is one key per environment, minimum. Many teams go further and issue one key per service or per developer within non-production environments, which gives even finer-grained attribution and makes it trivial to revoke a single person's access without affecting anyone else.
A practical naming and storage scheme
Keep the naming convention boring and predictable. Something like:
myapp-dev-<name>
myapp-staging
myapp-prod
Store each key in the secret manager appropriate to where it runs:
- Local development:
.env.local, excluded from git via.gitignore. Never share a.envfile over Slack or email — use a password manager's shared vault instead. - CI/CD: your CI provider's encrypted secrets (GitHub Actions secrets, GitLab CI variables, etc.), scoped to the specific pipeline that needs them.
- Staging/production: a proper secret manager (AWS Secrets Manager, Vault, or your platform's built-in environment variable encryption) with access restricted to deploy roles, not individual developers.
A simple environment-based loader pattern keeps the code identical across environments while the key itself changes per deployment:
const apiKey = process.env.CLAUDE_API_KEY;
if (!apiKey) {
throw new Error("CLAUDE_API_KEY is not set for this environment");
}
const client = createClaudeClient({ apiKey });
The code never hardcodes which environment it's in — it just trusts whatever key is injected at runtime. That's the core principle: environment identity lives in infrastructure, not in application logic.
Rotation without downtime
Rotation should be routine, not a fire drill triggered only after a leak. A reasonable baseline:
- Rotate production keys on a fixed schedule (quarterly is common) and immediately on any suspected exposure.
- Generate the new key before revoking the old one, and run both in parallel for a short overlap window.
- Deploy the new key to all instances, confirm requests are succeeding with it, then revoke the old key.
- Log the rotation event somewhere auditable — who rotated it and why.
Because each environment has its own key under this scheme, rotating staging never touches production, and a compromised dev key can be killed without any coordination with the ops team.
Adding a layer of application-level keys
Anthropic's own API keys are account-level credentials — they don't distinguish between "this request came from the iOS app" versus "this request came from the admin dashboard." If you're building a product on top of Claude and want to issue separate, revocable credentials per application, per customer, or per internal service — without creating a new Anthropic account for each — a proxy layer that sits in front of your actual Claude access is the practical answer.
This is the problem SubToAPI solves: it turns your existing Claude access into an HTTPS API and lets you generate scoped application keys (sub_live_...) from one dashboard. You can issue a distinct key per environment or per service, track usage per key, and revoke one without touching the others — the same separation principles described above, but applied at the application layer instead of the account layer. The underlying request format mirrors the standard Messages API, so switching a client over is usually a one-line change in how the key is loaded, not a rewrite:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this changelog."}]
}'
Teams on the Team or Scale plans can give each engineer or environment its own seat and key set, so usage and billing stay attributable per environment rather than lumped into one account-wide total. See /pricing for plan details, or /docs/quickstart to get a key generated in a few minutes.
Checklist for a clean setup
- One key minimum per environment: dev, staging, production.
- Keys never committed to version control — use
.gitignoreand verify with a pre-commit hook or secret scanner. - Secrets stored in a dedicated manager per environment, not shared spreadsheets or chat messages.
- A documented rotation schedule, with overlap windows to avoid downtime.
- Usage and spend reviewed per key, not just per account, so anomalies are traceable to a specific environment or service.
None of this is exotic — it's the same credential hygiene you'd apply to database passwords or cloud provider access keys. Claude API keys deserve the same treatment because the cost of a leak (unexpected usage charges, data exposure) is just as real.
Questions
Do I need a separate Claude API key for every microservice, or just per environment? Per environment is the minimum bar. Per-service keys add useful attribution (you can see exactly which service is generating usage) but add management overhead — start with per-environment and split further only if you need the granularity.
What's the fastest way to detect a leaked Claude API key? Monitor usage dashboards for unexpected spikes, and run automated secret scanning (e.g., GitHub secret scanning, truffleHog) on every commit and CI build. Catching a leak in minutes rather than days limits the damage significantly.
Can I restrict a Claude API key to specific models or request types? Anthropic's native keys don't support fine-grained scoping by model or endpoint. If you need that level of control, a proxy layer like SubToAPI that issues its own application keys with usage tracking per key is the more practical route — see /docs/tools for how tool use and other request types are handled through it.