API Key Security Best Practices That Actually Hold Up
API key security best practices come down to five things: never hardcode keys, store them in environment variables or a secrets manager, scope them to the minimum permissions needed, rotate them regularly, and monitor usage so you notice anomalies before they become incidents. Everything else — vaults, rate limits, IP allowlists — is a refinement of those five basics.
Most breaches involving API keys aren't sophisticated. A key gets committed to a public repo, pasted into a Slack channel, or left in a client-side bundle where anyone with dev tools can read it. Fixing the fundamentals eliminates the vast majority of real-world exposure. The rest of this article walks through what to actually implement, not just what to avoid.
Never Hardcode Keys in Source Code
This is the single most common mistake. A key written directly into a file will end up in git history, in a Docker image layer, or in a deploy artifact — even if you delete it in a later commit.
Do this instead:
# .env (never committed)
CLAUDE_API_KEY=sub_live_xxxxxxxxxxxxxxxx
const apiKey = process.env.CLAUDE_API_KEY;
if (!apiKey) throw new Error("Missing CLAUDE_API_KEY");
Add .env to .gitignore before you add the key, not after. If you've already committed a key, rotate it — removing it from the latest commit doesn't remove it from history.
Use a Secrets Manager in Production
Environment variables are fine for local development, but production systems benefit from a real secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler, or your platform's built-in equivalent). These give you:
- Access logging — who read the secret and when
- Automatic rotation without redeploying
- Encryption at rest with proper key management
- Fine-grained IAM permissions on who can even view the secret
If you're running a small team without the budget for a dedicated vault, at minimum use your CI/CD platform's encrypted secrets feature (GitHub Actions secrets, Vercel environment variables, etc.) rather than plaintext config files.
Scope Keys to the Minimum Necessary
A key that can do everything is a key that can break everything if it leaks. Whenever the provider supports it, create separate keys for:
- Different environments — dev, staging, and production should never share a key
- Different services — your billing service and your chatbot don't need the same credentials
- Different team members or apps — one leaked key should compromise one integration, not your entire account
This is exactly why SubToAPI issues application-level keys (sub_live_...) instead of one shared credential for your whole team. Each application gets its own key, so if one leaks, you revoke that key from the dashboard without touching anything else. See /docs/quickstart for how keys map to applications.
Never Expose Keys Client-Side
If your API key appears in JavaScript that runs in a browser, in a mobile app binary, or in a public GET request, it is not secret anymore. Anyone can extract it with browser dev tools or a decompiler.
The fix is a backend proxy: your frontend calls your own server, and your server holds the real key and calls the third-party API.
// Your backend — the key never reaches the browser
app.post("/api/chat", async (req, res) => {
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-3-5-sonnet",
messages: req.body.messages
})
});
const data = await response.json();
res.json(data);
});
This pattern also lets you add your own rate limiting, logging, and validation before requests hit the upstream API. Full request and response formats are in /docs/messages.
Rotate Keys on a Schedule, Not Just After Incidents
Rotation shouldn't only happen when something goes wrong. Set a calendar reminder — every 90 days is a reasonable default for most teams — and rotate keys as routine maintenance. This limits the blast radius of a leak you haven't discovered yet.
A practical rotation process:
- Generate a new key alongside the old one (most APIs support multiple active keys)
- Deploy the new key to all consumers
- Confirm the new key is working in logs or metrics
- Revoke the old key
- Document the rotation date
If your provider doesn't support having two active keys simultaneously, you'll need a maintenance window — plan for that rather than discovering it during an emergency.
Monitor Usage and Set Alerts
A leaked key often shows up as unusual activity before it shows up as a support ticket: a spike in request volume, calls from an unexpected region, or usage at 3 AM when your app has no users awake. Watching request counts, tokens, and costs per key lets you catch this early instead of after the invoice arrives.
If you're already routing model traffic through SubToAPI, the dashboard shows per-key usage and cost breakdowns automatically, which makes anomalies easy to spot without building custom monitoring. Check /docs for the metadata each response includes if you want to build your own alerting on top of it.
Restrict by IP or Origin When Possible
If your key is only ever used from a known set of servers, restrict it. Many providers support IP allowlisting or origin restrictions at the key level. This turns a stolen key into a useless string of characters for anyone outside your infrastructure — even if it leaks, it can't be used from elsewhere.
Treat Keys Like Passwords in Your Workflow
- Never send keys over email, Slack DMs, or unencrypted channels
- Never log full keys — mask all but the last 4 characters
- Never include keys in error messages or stack traces sent to logging services
- Require a password manager or secrets vault for sharing keys within a team, never a shared document
Building With Multiple Keys, Correctly
If you're integrating Claude into a product, structure your setup so that each application or environment gets a dedicated key, streaming and tool use are handled through your backend proxy, and you can revoke a single application's access without breaking others. See /docs/streaming and /docs/tools for the request patterns, and /signup if you want per-application keys with usage tracking already built in. Plans and seat pricing are on /pricing.
Questions
What should I do immediately if an API key leaks? Revoke it first, then investigate. Don't wait to understand the scope of exposure — a live key is a live risk every minute it stays active. Rotate to a new key and check usage logs for unauthorized activity during the exposure window.
Is it safe to store API keys in a .env file? Yes for local development, as long as .env is in .gitignore and never committed. For production, prefer a secrets manager or your platform's encrypted environment variable feature over plain .env files on a server.
How often should API keys be rotated? Every 90 days is a common baseline for most applications, though high-sensitivity keys (payment processing, admin access) warrant shorter cycles. Rotate immediately after any suspected leak, regardless of schedule.