LLM API Key Management Best Practices for Teams
LLM API Key Management Best Practices
Managing LLM API keys well comes down to five things: never hardcode them, scope them per application or environment, rotate them on a schedule, monitor usage so leaks get caught fast, and give each team member their own key instead of sharing one. Get those five right and you eliminate most of the security and billing incidents that hit teams building on Claude, GPT, or any other LLM provider.
The reason this matters more for LLM keys than for typical API keys is cost exposure. A leaked key to a low-cost API might get you a few hundred spam requests. A leaked LLM key can rack up thousands of dollars in a weekend because inference is expensive and attackers run it at scale with automated scripts. Key management for LLMs needs to be treated as a billing control problem as much as a security problem.
Never Hardcode Keys in Source Code
This is the most common mistake and the easiest to fix. Keys end up in:
- Client-side JavaScript bundles (visible to anyone who opens dev tools)
- Git history, even after being removed from the current commit
- Jupyter notebooks shared internally or on GitHub
- Config files committed "temporarily" and never cleaned up
The fix is always the same: load keys from environment variables or a secrets manager, never from a literal string in code.
// Bad
const apiKey = "sub_live_abc123...";
// Good
const apiKey = process.env.SUBTOAPI_KEY;
Add a pre-commit hook or CI check (git-secrets, truffleHog, gitleaks) that scans for key-shaped strings before they ever hit a remote branch.
Keep LLM Calls Server-Side
LLM API keys should never touch the browser. If your frontend needs to call a model, route the request through your own backend, which holds the key and forwards the request. This is non-negotiable even for internal tools — a key embedded in client-side code is public the moment it ships.
// Your backend, not the browser
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-opus-4",
messages: [{ role: "user", content: userInput }],
}),
});
Scope Keys by Environment and Application
One shared key across dev, staging, and production makes it impossible to tell where unexpected usage is coming from, and a compromised dev key becomes a production incident. Best practice is one key per environment, and ideally one key per application if you run several services against the same LLM provider.
This also makes revocation safe. If your staging key leaks, you kill it without touching anything in production. SubToAPI issues separate sub_live_... application keys per app from the dashboard, so you can isolate a compromised key to exactly the service it belongs to without rotating credentials across your whole stack.
Rotate Keys on a Schedule, Not Just After Incidents
Rotation shouldn't be a reaction to a breach — it should be routine. A practical cadence:
- Every 90 days for production keys as a default policy
- Immediately when a team member with access leaves
- Immediately after any suspected exposure (pasted into a support ticket, shared in Slack, etc.)
To rotate without downtime, generate the new key first, deploy it to your app, confirm traffic is flowing on the new key, then revoke the old one. Never revoke before the replacement is live.
Give Each Team Member Their Own Key
Shared credentials make it impossible to answer basic questions: who made this call, why did usage spike on Tuesday, who do we talk to about this cost. Per-user keys under a shared billing plan solve this without each person needing their own subscription.
This is the core of what seat-based access solves. On SubToAPI, Team and Scale plans let you add teammates as seats, each with their own key, while usage and costs roll up to one dashboard owned by the account admin. You get individual accountability without individual billing relationships. See /pricing for how seats are structured across Solo, Team, and Scale.
Monitor Usage and Set Alerts
A key management policy without monitoring only catches problems after the invoice arrives. At minimum, track:
- Request volume per key, per day
- Token usage per key (input and output separately — output is usually the expensive part)
- Error rates, especially spikes in 401s which can indicate a key being probed
- Geographic or time-of-day anomalies if your usage pattern is normally predictable
Review this weekly if you're a small team, daily if you're running customer-facing production traffic. The SubToAPI dashboard surfaces per-key usage so you can see which application or team member is driving cost without building your own logging pipeline. Full request/response handling details are in /docs/messages and /docs/streaming.
Limit Key Permissions to What's Needed
Not every integration needs every capability. If a key is only used for a summarization feature, it shouldn't also have access to tool-calling endpoints that can trigger external actions. Where your provider supports scoped keys, use the narrowest scope that gets the job done — it limits the blast radius if that specific key leaks. Tool-use scoping specifics are covered in /docs/tools.
Build a Revocation Checklist
When a key needs to die, you want a one-step process, not a scramble. Keep a short runbook:
- Identify every service/environment using the key
- Generate replacement key(s)
- Deploy replacement, confirm live traffic
- Revoke old key from the dashboard
- Confirm old key returns 401 on test request
Having this written down before an incident saves real time during one.
Getting Started
If you're switching from managing raw provider keys to a managed layer, the setup is quick: sign up at /signup, create an application key from the dashboard, and swap it into your existing request code — the request/response shape stays close to the native Claude API, so migration is usually a one-line change per endpoint. The /docs/quickstart guide walks through the first call end to end.
Questions
How often should I rotate LLM API keys? Every 90 days as a default, plus immediately whenever a team member with access leaves or a key exposure is suspected. Treat rotation as routine maintenance, not an incident response.
Should I use one key for my whole team? No. Shared keys make it impossible to trace who made which call or caused a cost spike. Use per-member keys under one billing account instead, which is how seat-based plans like SubToAPI's Team and Scale tiers are structured.
Is it safe to call an LLM API directly from frontend JavaScript? No. Any key in client-side code is visible to anyone who opens developer tools. Always route LLM calls through your own backend, which holds the key and forwards requests.