API Key Management and Rotation on EXAIV: Creating, Storing, and Replacing Keys Without Downtime
API Key Management and Rotation on EXAIV: Creating, Storing, and Replacing Keys Without Downtime
An API key is a bearer credential: whoever holds it can spend your credits and read the responses your application gets back. That makes key handling one of the few places where a small operational mistake turns into a real incident, and one of the few places where a deliberate process removes almost all of the risk.
The mechanics are simple — create a key, put it in an environment variable, send it in an Authorization: Bearer header. The parts that require thought are the ones that happen under pressure: rotating a key on a running service, and responding in the first minutes after a key leaks. This guide covers both, along with the storage rules that keep a leaked key from being worse than it has to be.
The short version
Treat every key as disposable. Keep it in an environment variable or a secret manager, never in the repository. When you need to replace one, create a second key, deploy it, confirm traffic moved, then revoke the first. That sequence has no window in which requests fail.
Live catalog and pricing
Model IDs follow the live /models catalog, and pricing follows /pricing — both change with upstream updates. Verify before hard-coding an ID.
Where keys belong
The single most useful rule is that a key should never exist in a place that a human can casually read, copy, or commit.
| Location | Acceptable? | Why |
|---|---|---|
| Environment variable in the deployment platform | Yes | Injected at runtime, not stored with the code |
| Secret manager, referenced by the app at boot | Yes | Rotation is possible without a rebuild |
.env file that is git-ignored | Acceptable in development | Fine locally, unsafe if it ever reaches a shared repo |
| Source file or committed config | No | Permanent exposure once pushed |
| Container image layer | No | Layers are cacheable and inspectable |
| Log line, error message, screenshot | No | Ends up in places you cannot audit |
| Shared settings file committed to a project | No | Every collaborator and every clone has it |
Two details catch people out. First, a .gitignore entry added after a key was committed does not remove it from history — the key must be rotated, not just deleted. Second, a key pasted into a chat message, a support ticket, or an issue tracker should be treated as exposed even if you delete the message afterwards.
Redaction is a habit, not a step
When you paste a request, a curl command, or a config snippet into an issue, a doc, or a screenshot, redact the Authorization header in the same action that pastes it. Redacting afterward means remembering, and memory fails exactly when the incident is busiest.
Creating a key for a specific purpose
Create one key per environment and, where practical, per service. The cost of an extra key is a line of configuration; the benefit is that a rotation, a revocation, or an investigation touches only the traffic that needs to be affected.
A workable layout:
| Key | Used by | Rotation cadence |
|---|---|---|
exaiv-local-dev | Developer machines | On request; low value |
exaiv-staging | Staging and preview deployments | Monthly |
exaiv-prod-api | The production API service | Monthly, and immediately on any suspicion |
exaiv-prod-worker | Background jobs and cron tasks | Monthly, separately from the API key |
Keeping the API service and the background worker on different keys means a leaked worker key does not hand an attacker your interactive traffic as well.
Rotating a key without downtime
The rotation is a four-step sequence. The order matters: reversing any two steps creates either a failed request or a window where an old key is still live but no longer monitored.
- Create the replacement. Do not change the existing key yet — a key that is overwritten in place stops working immediately.
- Deploy the new value. Update the secret in the deployment platform and trigger a restart or redeploy so the running instances pick it up. Confirm the new key is live by checking that traffic is succeeding with it.
- Verify the move. Watch request success rates and error volumes for a short window. A key that was accepted by the platform but not by the service still produces failures — this is the step that catches the common mistake of updating the secret in one environment but not the other.
- Revoke the old key. Only after the new key is confirmed working. Revocation is the point at which the old credential stops being usable; before that, it is a live duplicate.
The window between step 2 and step 4 is short, usually minutes. During that window both keys are valid, which is exactly what you want: any instance that has not yet restarted still works.
Why not rotate in place
Overwriting a key in place is faster, and it fails in the worst way: instances restart at different times, so part of your fleet is using a value that no longer exists. Requests fail during a rotation that was supposed to be invisible, and the rollback is just as disruptive. Overlapping keys cost one extra key and remove the whole class of problem.
A rotation checklist
- The replacement key was created and its value stored in the secret manager.
- The old key was not modified or overwritten in place.
- The deployment was restarted, and the new value is confirmed in the running environment.
- Request success rate and error volume were checked after the deploy.
- The old key was revoked only after the verification step.
- Any place that had the old value hard-coded — local
.env, CI variables, a colleague's shell — was updated.
What a leaked key looks like
If a key might have been exposed, the response is the same regardless of how the exposure happened: revoke it, then investigate. A key that still works during an investigation is a key that is still being used.
Treat it as exposed if any of these happened:
- it was committed to a repository, even one that was later reverted;
- it appeared in a screenshot, a log file, a shared document, or a chat message;
- it was pasted into a third-party tool, a web form, or an issue tracker;
- a machine that stored it was lost, shared, or compromised;
- it was passed through a proxy or service you do not control.
The first step is to create a replacement, deploy it, and revoke the exposed key — the same four-step sequence, done quickly. Then look at what happened during the exposure window:
- Usage records. Which models were called, how many tokens, and at what times. An unexpected model or a volume spike is the clearest signal of abuse.
- Request logs. If your application logs request metadata, check for unfamiliar callers or odd request shapes during the window.
- Account activity. Compare consumption against what your normal traffic looks like. An unexplained jump is worth escalating to the platform's support channel.
Rotate before you finish the investigation. The order is deliberate: revoking first is cheap and immediate, and no investigation result justifies leaving a live credential in place.
Do not paste the exposed key into a support request
When you contact the platform about a compromised key, describe the problem and the time window. Do not include the key value itself, even in a private ticket — a key in a support system is a key in a support system. The platform can identify and revoke it from their side without you restating it.
Practical habits that prevent incidents
- Keep keys out of command lines that get recorded. Export the key into the environment first, then reference
"${EXAIV_API_KEY}"in the command. A literal key in a curl invocation ends up in shell history, in process listings, and in any terminal transcript you paste. - Rotate on a schedule, not only on suspicion. A scheduled rotation turns a security decision into a calendar entry, which is how it actually gets done.
- Use a different key per environment. Staging should never be able to spend production credits, and a staging leak should never force a production rotation.
- Revoke keys for people and systems that no longer exist. Offboarding that leaves a key alive is a common and avoidable exposure.
- Give every key an owner. When an alert says a key is unusual, someone needs to know which service it belongs to and what it is allowed to do.
- Test the failure path. Deliberately use a revoked key once and confirm your application fails in a way you can recognize, rather than discovering it during a real incident.
Handling keys in different environments
| Environment | Recommended approach |
|---|---|
| Local development | .env file that is git-ignored; a development key with no production value |
| CI/CD | Platform secret store, injected as an environment variable at run time |
| Containers | Secret or environment injection at start-up; never baked into a layer |
| Serverless | Platform secret binding, referenced by the runtime |
| Shared staging | One key for the whole staging environment, separate from production |
Whichever mechanism you use, the application should read the key from the environment at start-up and fail fast with a clear message when it is missing. An application that starts without a key and only fails on the first request produces a much noisier incident than one that refuses to start.
Key handling checklist
- Every key lives in an environment variable or a secret manager.
- No key exists in source code, committed configuration, container layers, logs, or screenshots.
- Keys are separated by environment and, where practical, by service.
- The rotation sequence is create → deploy → verify → revoke, and never in-place overwrite.
- A replacement key is deployed and confirmed before the previous key is revoked.
- Any suspected exposure triggers immediate revocation, with the investigation afterwards.
- Revocation is tested once so the failure mode is familiar.
- Offboarding revokes the departing person's and service's keys.
Further reading
- OpenAI SDK Migration Guide — the two configuration values you change when moving an application onto EXAIV.
- Production Readiness Checklist — the full pre-launch checklist, including credential handling.
- Error Handling and Retry Guide — how failures surface once a credential or route is rejected.
FAQ
How often should API keys be rotated?
Should I use one key per service?
Can I use environment variables in CI?
Related reading
Terminology and pre-flight checklist
Total parameters, active parameters and the KV cache are three different quantities. Total parameters are all the weights that must be loaded into memory; active parameters are the subset that computes a single token. KV cache is temporary memory that grows linearly with context length, so a 1M window is a ceiling rather than a free default. Quantization lowers the precision of stored weights to shrink files; it does not reduce the parameter count. A vision_config in a config.json describes architecture, not a wire format you may safely invent.
Before shipping anything built on these notes, run six checks. Re-read the numbers from the live source on the day you publish, because download counters move weekly. Open the live /models catalog and confirm the model ID you plan to call is still there. Open /pricing rather than copying a price into your application. Never hard-code a request body you have not validated against the official reference. Record the model ID, input and output token counts, and latency for a representative set of prompts, then keep that set unchanged so a later model swap produces a comparable reading. Read the licence on the model card before commercial use, since vendor-specific terms are not a permissive default. Add exponential backoff for retryable requests, set a timeout, and log the error class so that a 401, a 404 and a 429 never get the same treatment.