API Key Security for LLM Applications: How Keys Leak, How to Store Them, What to Do After a Leak
API key security comes down to three rules: keep the key in an environment variable or secret manager, never in code; use a separate key per environment and rotate on a schedule; and put a layer in place that technically caps spending if a leak happens. On Onysoft AI Gateway, per-key token limits and a prepaid balance ceiling bound the damage a leaked key can do from the start.
What separates LLM API keys from ordinary API keys is that they convert directly into money: every token has a published price, and a leaked key — in the hands of automated scanner bots — turns into an invoice within hours. The classic "API security" playbook of OAuth and HTTPS does not cover this risk; here the threat is unauthorized spending before it is unauthorized data access.
This guide covers where leaks actually come from, how to store keys correctly, and — data you will not find elsewhere for this query — a damage-scenario table computed from live sale prices, the gateway layers that cap spending at the architecture level, and a leak-response checklist.
Where Do API Keys Actually Leak From?
The five most common leak sources are: embedding the key in frontend code, committing it to a git repository, writing it into logs and error records, internal sharing channels, and CI/CD configurations. What all five share is a key written to a place assumed "temporarily" safe — and then forgotten there.
- Frontend embedding: A key shipped in a browser JavaScript bundle is visible to anyone who opens the DevTools Network tab. LLM calls must never be made directly from the browser; requests should always pass through your backend, with the key living only on the server.
- Repository commits: Public repositories are scanned continuously by leak-hunting bots; a committed key can be in use within minutes. Private repositories are not safe either — forks, widening access, and permanent history all count. Deleting the file is not enough; a key left in history remains valid.
- Logs and error records: A request-logging middleware writing the
Authorizationheader verbatim, or a payload sent to an error-tracking tool containing the key, is a frequent and late-discovered leak. Masking headers in logs is mandatory. - Sharing channels: A key pasted in plain text into a Slack message, an email, or a ticket lives indefinitely in that channel's archive, open to everyone with access.
- CI/CD configurations: Variables echoed into pipeline logs and
.envfiles packaged into build artifacts are the leak surface furthest from anyone's eyes.
How to Store a Key Correctly: Environment Variables and Secret Managers
Correct storage has one core rule: the key never enters source code in any form — use a .env file with environment variables in local development and a secret manager in production. Code contains only the variable's name; its value arrives from outside at runtime.
# .env — never enters the repo
ONYSOFT_API_KEY=sk-ony-YOUR_KEY
# .gitignore — added before the first commit
.envIn production, prefer your cloud provider's secret store or a Vault-style secret manager over a .env file: the key stays encrypted, access is permission-bound and audited, and the value is injected into the application as an environment variable at deploy time. Two complementary habits cut the risk further: give every application and service its own key (one key used everywhere turns a single leak into a total loss), and wire a secret scanner such as gitleaks into your pre-commit hook — the key gets caught before it ever reaches the repo.
How Much Does a Leaked Key Cost? A Damage Scenario with Real Prices
The damage from a leaked LLM key is not an abstract "security risk"; it computes directly from token prices. Let's build a concrete scenario: your key is compromised and, before you notice, the attacker generates 10 million output tokens (a realistic volume for automated abuse). Which model gets called determines the size of the invoice — the amounts below are computed from actual sale prices in the live api.onysoft.com catalog:
| Model | Output ($/1M tokens) | 10M-token damage (USD) | 10M-token damage (TRY) |
|---|---|---|---|
anthropic/claude-opus-5 | $37.50 | $375.00 | ₺17,833.13 |
anthropic/claude-sonnet-5 | $15.00 | $150.00 | ₺7,133.25 |
google/gemini-3.6-flash | $11.25 | $112.50 | ₺5,349.94 |
openai/gpt-5.6-terra | $9.00 | $90.00 | ₺4,279.95 |
openai/gpt-5.6-luna | $0.90 | $9.00 | ₺428.00 |
deepseek/deepseek-v4-flash | $0.42 | $4.20 | ₺199.73 |
Measured: August 5, 2026 — api.onysoft.com live catalog. TRY equivalents calculated at the August 5, 2026 TCMB rate (1 USD = 47.555 TRY).
Two conclusions follow. First, the damage varies roughly 90x by model choice — and an attacker naturally picks the most expensive model. Second, and more important: on a credit-card-backed, pay-as-you-go account, the ceiling on these amounts is your spending limit; on a prepaid model, the ceiling is your loaded balance. In a leak scenario your maximum loss should be set by architecture, not by contract — which is exactly what the next section covers.
How It Works on Onysoft: Limited Keys, Cost Pre-Check, and 402
On Onysoft, key security is not just storage advice — it is three technical layers built into the gateway: per-key model token limits, a cost pre-check on every request, and a prepaid balance ceiling. Code first — the key is read from an environment variable, and no secret appears in the source:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.onysoft.com/v1",
api_key=os.environ["ONYSOFT_API_KEY"], # key lives in the environment, not in code
)
response = client.chat.completions.create(
model="anthropic/claude-sonnet-5",
messages=[{"role": "user", "content": "Explain the error in this log line."}],
)
print(response.choices[0].message.content)
# Every response body includes a cost field: this request's cost in USD.
# Log it with the request ID — that is the raw data for anomaly detection.The layers work like this:
- Per-key model token limits: From the dashboard you define per-model token limits on each key. A leaked key can spend only up to the limit you granted it, not your entire balance — giving narrow limits to keys used by frontend-adjacent, higher-risk services is the right practice.
- Cost pre-check → 402: The gateway checks each request's estimated cost, multiplied by a factor of 1.2, against your balance; if it does not cover the request,
HTTP 402is returned before anything reaches the model. A leaked key cannot spend a single token beyond your balance — the surprise credit-card bill does not exist in this architecture. - Per-request
costfield and usage reports: Thecostfield in every response and the date/model-filtered usage reports in the dashboard make anomalies visible: a stream of requests to a flagship model you never use, at 3 a.m., stands out in the report at first glance.
All 739+ models in the catalog work with the same sk-ony- key; for a deeper treatment of the spending side see the cost control guide, and the API documentation for endpoint details.
Key Lifecycle: Environment Separation, Rotation, Revocation
A healthy key lifecycle consists of three habits: a separate key per environment, rotation on a schedule, and one-step revocability. If development, staging, and production share one key, a leak in the least-protected environment opens your production budget directly; with separate keys, you give the development key a narrow token limit and keep the production key only in the secret manager.
Rotation is the API equivalent of password changes: renew keys at regular intervals (for example, every 90 days) and immediately whenever a team member with key access leaves. The correct order is zero-downtime: generate the new key → distribute it via the secret manager → confirm traffic has switched using the usage report → revoke the old key. Followed in this order, rotation is invisible to your users.
The last piece is an inventory: without a current list of which key is used by which service, in which environment, and with which limit, you can neither plan rotation nor decide quickly which key to revoke during a leak. Start keeping this list the moment you have more than three keys.
If Your Key Leaked: the First-30-Minutes Checklist
The correct order in the moment of a leak is: revoke the key first, measure the damage second, close the source last — doing it backwards and starting with "cleanup" means minutes during which the attacker keeps spending.
- Revoke the key immediately (minutes 0-5): Disable the leaked key from the dashboard and generate a new one for the service that needs it. Revocation stops the spending at that instant; every remaining step now happens without time pressure.
- Measure the damage (minutes 5-15): Narrow the usage report to the leak window with the date filter, isolate unfamiliar traffic with the model filter, and total the
costvalues. In a prepaid architecture the ceiling on that total is your balance — or the limit you defined, if the key was limited. - Close the source (minutes 15-30): If the key entered a repository, clean the history — but know that alone is not sufficient; revocation is the real guarantee. Audit log masking, the frontend bundle, and CI configuration with the same eye.
- Review your other keys: If the leak happened through a channel (repo, logs, Slack), other keys may have leaked through the same channel; check every key in your inventory over the same window.
- Update the process: Inform the team, move the rotation schedule forward, and permanently fix whatever made the leak possible (a missing
.gitignore, an unmasked log).
Rehearsing this list once before a leak turns panic into a plan when one happens. To start, open a free account and split your keys by environment; for the broader picture, see the AI API guide.
Last updated: August 5, 2026 · Data: api.onysoft.com live catalog
Frequently Asked Questions
Is it safe to store an API key in a .env file?
For local development, yes — on the condition that the .env file is added to .gitignore before the very first commit and never enters the repository. In production, prefer a cloud secret store or a Vault-style secret manager over a .env file: the key stays encrypted, access is audited, and the value is injected into the application as an environment variable at deploy time.
If my API key leaks, what is the maximum I can lose?
It depends on your architecture. On credit-card-backed pay-as-you-go accounts, the ceiling is your spending limit, and the bill arrives later. On Onysoft's prepaid model, the maximum loss is bounded by your loaded balance: each request's estimated cost is checked against the balance with a 1.2 factor, and if it does not cover the request, HTTP 402 is returned before the model is called. If you defined a token limit on the key, the damage narrows further to that limit.
Can I use an API key in the frontend?
No. A key in the JavaScript bundle shipped to the browser is visible to anyone who opens DevTools and can be abused within minutes. LLM requests should always pass through your own backend, with the key living only in a server-side environment variable. Using a separate, narrowly token-limited key for frontend-adjacent services adds one more layer of protection.
How often should an API key be rotated?
Every 90 days is a reasonable baseline schedule; rotate immediately, without waiting, when a team member with key access leaves or a leak is suspected. The zero-downtime order matters: generate the new key, distribute it via the secret manager, confirm traffic has switched using the usage report, and only then revoke the old key.
How do I notice that my key is being abused?
Watch two signals: log the cost field from every API response together with the request ID, and regularly review the date/model-filtered usage reports in the dashboard. Requests to a model you never use, volume spikes at unusual hours, or unexplained cost growth are the typical first signs of a leak. The right reflex on suspicion is to revoke the key first and investigate second.
Related pages
Ready to build?
Access 739+ AI models through a single API. Pay as you go — no subscription.