Every tool guide on this site ends the same way: put your key into some configuration. This piece is about the key itself. Leaks are a matter of when, not if, so the goal of API key security best practices is not to never leak; it is to contain the damage when something leaks. Two moves decide how that goes: keep every key inside a boundary you can revoke, and stay always-ready to rotate. Everything below either builds toward those two properties or handles the day they get tested.
API key security best practices: containment, not just prevention
The one rule most teams remember is "do not hard-code keys," and it is nowhere near enough. Keys leak from places the rule never mentions. Local developer tools write credentials into plaintext files: the official warning about treating a certain CLI's local credential file like a password exists for a reason, and we covered that storage picture in the Codex credentials guide. CI logs carry whatever a shell echoes. Error reporting systems collect request context indiscriminately. Tickets, chats, and screenshots collect whatever a teammate pasted while debugging. The official production guidance starts with the same instinct you should: avoid exposing keys in code or public repositories, and provide them to applications through environment variables or a secret management service rather than a codebase. But read the next sentence with the leak surfaces above in mind, and the design goal becomes obvious: assume one of them will fail someday, and engineer so that the failure is boring.
The six places keys leak
Work the list once for your own system; each entry is a check and a fix.
- Client-side code and distributed apps. Anything shipped to users, from a web front end to a desktop or mobile build, is public by definition. The rule is absolute: never expose an API key client-side. Route model calls through your own server-side boundary, or, for local developer tools, have users bring their own credentials. The official guidance points the same way: expose keys to your application through environment variables or a secret manager, which presumes the "application" is a place you control. A key inside a distributed binary is not a configuration detail; it is a published secret.
- Repositories and commit history. The current file is the easy check; the history is the one that matters. Changing a file does not remediate anything, because the old commit still contains the key and clones still hold it. Treat any key that ever appeared in a repository, even historically, as already leaked, and remember that only revocation ends the exposure.
- CI and build artifacts. Pipeline logs that print environment blocks, shell tracing that echoes variables, and build artifacts that bundle an environment file all move secrets into systems with broader readership than production. Keep keys injected as CI secrets, keep logs masked, and keep artifacts free of credential files; the non-interactive patterns in the CI guide apply here, and the same hygiene generalizes to every pipeline that touches a key.
- Logs and error reporting. This is the most common leak surface because logging is otherwise a virtue. The rule from the logging field guide carries over unchanged: keys and tokens never enter a log line, and anything that looks like a credential gets filtered before it is written, plus an alert for when the filter fires.
- Collaboration and support channels. Tickets, chat threads, shared documents, and screenshots are where keys go to live forever with the widest possible audience. Make the policy explicit and boring: credentials are never pasted into any channel, and a key that was pasted anywhere is treated as leaked and rotated.
- Third-party and public exposure surfaces. Debug snippets shared outside the team, third-party dashboards, and anything else outside your boundary. This article deliberately does not cover how to go looking for exposed keys anywhere; the operational stance is what matters. If exposure is plausible, even unconfirmed, run the incident response in order below and treat the key as burned.
Secret management for LLM apps: make leaks survivable
Four design rules turn an eventual leak from an emergency into a chore:
- Set expiry, and rotate on a schedule. The official recommendation is to set an expiration date when creating a project API key and to establish a regular key rotation process. Hygiene is not remembering to act; it is a calendar that acts. Administrators can enforce a maximum lifetime at the organization or project level, so new keys must expire within the configured limit instead of remaining valid indefinitely, and project limits cannot exceed the organization limit. If your platform offers that control, turning it on converts policy into physics.
- One key, one job. Give each service and each environment its own key. When a key leaks, the blast radius is exactly the applications that used it, not everything you run. This is the same instinct as least privilege in permission scope, applied to credentials themselves.
- Prefer short-lived credentials over long-lived keys. Anthropic's API documentation shows the pattern in its auth header: the token in
Authorization: Bearer <token>can be an API key, or a short-lived access token obtained through Workload Identity Federation. Anything with an expiry measured in minutes is dramatically harder to leak usefully than a key that lives for years. Where the platform offers short-lived token exchange, prefer it for automated workloads. - Keep keys inside a boundary you control. Server-side only, no exceptions. A key should exist only where you can revoke it; if it is anywhere you cannot reach, it is already lost. How and where you store it matters as much as where you send it: use the strongest credential store the environment offers rather than the most convenient file, the same ordering logic the corporate network guide applies to credential stores for CLI tools.
Rotating an API key without an outage
The safe way to rotate an API key is as a procedure, and the official version is precise: before a key expires, create a replacement, update your applications to use it, and revoke the old key only once you have verified that the replacement works. The ordering is deliberate. Creating the replacement first gives you a dual-active window, during which both keys exist and the new one has proven itself in production before the old one dies. Revoking first, by contrast, is a self-inflicted outage, and rotating by editing an environment file and hoping is a self-inflicted incident waiting for a restart. If you have ever switched providers or keys by hand, the operational checklist in the key change guide is the practical companion to this ordering.
Revoke a compromised API key first
When compromise is suspected, the order inverts. The official safety guidance is blunt: if you believe a key has been exposed, misused, or otherwise compromised, revoke it promptly and replace it with a new key, with your platform's Security settings as the place to view keys and revoke the affected ones. From there, the engineering sequence runs:
- Revoke first. Stop the bleed before you understand it. Do not leave a suspect key alive to gather evidence; revocation is the evidence-gathering window's prerequisite, not its casualty.
- Replace and deploy. Create the new key, put it in place through your normal secret path, and verify the application works.
- Check usage and call locations. Look at where the key was used, from where, and for what, and reconcile against your own usage records.
- Find the leak surface. Which of the six above produced this, and what check would have caught it earlier? Add that check.
- Write it down. The incident, the decision, the fix, and the new check go into the repository documentation, so the next rotation inherits the lesson instead of relearning it.
The contrast with the previous section is the whole lesson: planned rotation is replacement-first, incident response is revocation-first. Mixing the two up is how teams either prolong a compromise or cause an outage.
One more baseline: test adversarially
The safety guidance adds a recommendation that belongs beside key hygiene, though it is a separate control and not a key-protection measure: red-team your application against adversarial input. Test both a representative set of inputs and inputs from someone actively trying to break the product, prompt-injection attempts included. The reason to mention it here is scope discipline: adversarial testing hardens the application layer, while the practices above contain the credential layer. Do both, and do not confuse one for the other.
The key hygiene checklist
- Can every key you hold be revoked, by you, today?
- Can you rotate it with a dual-active window instead of a hard cutover?
- Does every key have an expiration date, with rotation on a schedule?
- Does each key serve exactly one application and one environment?
- Does client-side code ship zero platform keys?
- Have leaked repository history entries been treated as compromised, on the assumption that revocation, not deletion, is the remedy?
- Are CI and build logs masked, and artifacts free of credential files?
- Are logs and error reports filtered for credential-shaped content, with an alert when the filter fires?
- Is there an explicit no-credentials rule for tickets, chats, and screenshots?
- When did you last rehearse a rotation, end to end, including the revoke step?
Ten questions, two properties: everything revocable, everything rotatable. The day a key leaks, those two properties are the entire difference between a checkbox exercise and an incident. When your keys authenticate to a compatible endpoint, the endpoint-level specifics live in the platform's own documentation.