# How to limit the damage from a stolen AI API key

URL: https://infro.io/blog/cap-stolen-ai-key-damage
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-10-21
Last modified: 2026-10-21
Last reviewed: 2026-10-21 (next review due 2026-11-20)
Topic: Security and governance
Format: Guide

> Limit the damage from a stolen AI API key by deciding its blast radius before it leaks: give every workload and environment its own provider key in its own project or workspace, put a hard spend limit on that scope at the provider, restrict keys by network where the provider supports it (OpenAI project and organization IP allowlists, Google API key restrictions), give applications gateway keys instead of provider keys, enforce budgets that refuse before the provider is called, and watch provider usage per key. Gateway controls bound only traffic that passes through the gateway; a stolen provider key is bounded by the provider's own limits.

Key takeaways:
- Decide a key's blast radius before it leaks: which account, which models, which networks, how much spend and how fast you will know.
- One provider key per workload and environment, each in its own project or workspace with its own hard limit, is the layer that bounds a key used outside your gateway.
- OpenAI supports IP allowlists per organization and project; Google API keys take IP and API restrictions; Anthropic documents IP allowlisting for Claude Enterprise, not for Claude API keys.
- Give applications gateway keys, so the provider key lives in one place and an application leak is revoked without touching the provider.
- Gateway budgets refuse before the call but govern only gateway traffic; a stolen provider key is bounded by provider limits, revocation and monitoring.

**How do you limit the damage from a stolen API key?** Decide its blast radius before it leaks. Give every workload and environment its own provider key in its own project or workspace, set a hard spend limit on that scope at the provider, restrict keys by network where the provider allows it, give applications gateway keys instead of provider keys, enforce budgets that refuse before the provider is called, and watch provider usage per key. Then a leak is a bounded, visible loss instead of an open-ended one.

No control here prevents a leak. Keys end up in repositories, laptops, CI logs, browser bundles and third-party tools that store them for you. On 2026-10-17 OpenCode disclosed that provider keys saved in its Console had been exposed; BleepingComputer reported users describing unauthorized charges from several hundred dollars to more than $1,700 overnight, and some said Google suspended their projects for "abusive activity consistent with hijacked resources"[1]. The [OpenCode incident write-up](https://infro.io/blog/opencode-console-breach-what-happened) covers what is known. This guide is about the part you control: how much any one key can do once someone else has it.

## The rule that decides everything else

Controls in your gateway govern traffic that goes **through** your gateway. A provider key stolen from anywhere, including from a gateway or platform that stores customers' provider keys, can be sent straight to the provider. It bypasses every gateway budget, allowlist, guardrail and alert. Only the provider's own controls apply to it: how the key is scoped, the spend limit on its project or workspace, network restrictions the provider enforces, revocation at the provider, and the provider's usage reports.

So the layers below split in two. Layers 1 to 3 bound a **provider key** used anywhere. Layers 4 and 5 bound what flows through your gateway, including a leaked **gateway key**. Layer 6 is how you find out.

## Layer 1: one provider key per workload and environment

A key shared by five services and two environments cannot be revoked without breaking all of them, and its usage cannot be told apart. Give each workload its own key, in its own provider scope:

- **OpenAI:** a project per workload and environment. Project hard limits apply only to traffic billed to that project[2].
- **Anthropic:** a workspace per workload and environment, with keys scoped to that workspace. A single-workspace key can only act in its workspace[3].
- **Google:** a project per workload, with each key restricted to the APIs it needs. Google recommends setting both API restrictions and application restrictions, and calls unrestricted keys insecure[4].
- **Amazon Bedrock:** prefer short-term API keys, which last up to 12 hours and inherit the permissions of the IAM principal that made them; AWS recommends long-term keys only for exploration[5].

The same applies to keys you hand to third parties. A coding agent, an evaluation vendor or a BYOK platform gets a key of its own, in a scope of its own, so you can revoke it without touching anything else.

## Layer 2: a hard limit on every scope that holds a key

With one key per scope, the scope's limit is the key's limit. OpenAI enforces hard limits per project and organization and returns `429 project_spend_limit_exceeded` at the limit, noting that enforcement is not instantaneous[2]. Anthropic workspaces take their own monthly spend limit, except the Default Workspace[3]. Which providers refuse and which only alert, and how late each acts, is in [AI provider spend limits compared](https://infro.io/blog/provider-spend-limits-compared).

Set each limit from the workload's normal month, not from the account's. An evaluation pipeline that spends a few hundred dollars a month needs a limit near that, not the organization's ceiling. Keep the Default Workspace and any project without a limit free of keys.

## Layer 3: restrict where a key works

A key that only works from your servers is worth little to someone who copies it. Support differs:

| Provider | Restriction you can put on an API key | Documented response when blocked |
| --- | --- | --- |
| OpenAI | IP allowlist per organization or project, up to 50 addresses or CIDR ranges; a project list overrides the organization list | `401 ip_not_authorized` |
| Google (Gemini API, Cloud APIs) | Application restriction by IP address (one restriction type per key), plus API restrictions | Not stated on the cited page |
| Anthropic | IP allowlisting is documented for Claude Enterprise plans; the article does not say it covers Claude API keys | Not documented for API keys |
| Amazon Bedrock | No network setting on the API keys page; IAM policies control who may create and use keys, including a deny on `bedrock:CallWithBearerToken` | Not stated on the cited page |

Table: From each provider's documentation on 2026-10-21.

OpenAI's allowlist applies only to API requests, takes up to 15 minutes to apply, and "does not replace secure API key storage, key rotation, or account security"[6]. Check the address the provider sees: NAT gateways and proxies change it. Google's IP restriction "specifies the servers or cron jobs that can use the key", and only one application restriction type can be set per key[4]. Anthropic's IP allowlisting article is for Enterprise plans and lists chats, projects and similar Claude surfaces without stating that Claude API requests are covered[7]; do not count on it for API keys without confirming with Anthropic. On Bedrock, AWS documents IAM actions that control generating and using API keys, including a deny on `CallWithBearerToken`[5].

Where the provider cannot restrict by network, the remaining layers carry more of the weight.

## Layer 4: applications hold gateway keys, not provider keys

The fewer places a provider key exists, the fewer places it can leak from. Put a gateway between your applications and the providers, store the provider key there, and give each application a gateway key scoped to one service and one environment. A leaked application key is then:

- **Revocable without touching the provider.** You revoke one gateway key; the provider key and every other service keep working.
- **Narrow.** It reaches only the providers, models and networks its gateway key allows.
- **Bounded by the gateway's limits**, which refuse before the provider is called.

This concentrates provider keys in one system, which makes that system a target. Hold it to the standard in [BYOK credential architecture](https://infro.io/blog/byok-credential-architecture): provider keys sealed with authenticated encryption, never returned after saving, and still scoped and limited at the provider as if they might leak. They might. [AI gateway keys: environments, limits, rotation](https://infro.io/blog/gateway-key-controls-environments) covers running the gateway keys themselves.

## Layer 5: budgets that refuse before the call

A gateway budget that records cost after a request completes can be passed by everything already in flight. One that admits a request only if its worst-case cost fits the room left cannot. Put a limit on each gateway key, sized for that service, and a blocking budget on each project and on the organization. For a leaked gateway key, the key's limit is the exposure. For a runaway agent using a legitimate key, the same limit is what stops it. [LLM spend limits compared](https://infro.io/blog/llm-spend-limits-compared) explains when each gateway counts spend.

## Layer 6: know within hours, not at the invoice

Every layer above bounds the loss. Detection decides how much of the bound is used. Three signals, in order of speed:

1. **Gateway alerts** on a key, project or organization spending outside its usual day. Fast, but blind to traffic outside the gateway.
2. **Provider usage per key.** OpenAI and Anthropic both report usage grouped by API key through their admin APIs. Traffic on a provider key that your gateway never sent is a leaked key or shadow usage; [detecting gateway bypass](https://infro.io/blog/detect-gateway-bypass-provider-usage) shows the comparison with a script.
3. **Provider spend alerts** on each project or workspace, set below the hard limit.

Then make revocation fast. Write down, for every key, where it is revoked and who can do it; [the AI credential inventory](https://infro.io/blog/ai-credential-inventory) has a template. Rehearse it once. A key you cannot find in the provider console at 2 a.m. is a key that keeps spending.

## A worked example

> **Example: One leaked key, six layouts**
> A company runs a support assistant, a nightly evaluation job and a coding agent, all on OpenAI. A developer pushes a config file containing a key to a public repository. The numbers are invented.
> 
> - **Layout 1, one organization key everywhere, no limits.** The key reaches every model the organization can use. Exposure is bounded only by the organization's usage tier and how long until someone notices; revoking it takes down all three workloads.
> - **Layout 2, one project key per workload, no limits.** The leaked key is the evaluation job's. Revoking it affects only that job, but nothing bounds its spend until the next invoice.
> - **Layout 3, plus a $1,500 project hard limit.** Exposure is about $1,500 plus whatever lands during enforcement lag. When the limit trips, the evaluation job stops; the assistant does not.
> - **Layout 4, plus a project IP allowlist.** Requests from the attacker's network return `401 ip_not_authorized`. Exposure is close to zero, provided the allowlist is right.
> - **Layout 5, applications hold gateway keys.** The file contained a gateway key with a $40 daily limit, limited to one provider and to the company's egress range. Exposure is at most $40 a day until revoked, and revoking it does not touch the provider key.
> - **Layout 6, the provider key leaks from the gateway's own store.** Gateway budgets do not apply. Exposure falls back to layouts 3 and 4: the project limit and the allowlist on the provider key.

The last line is the reason for the order of this guide. Gateway controls make the common leak small; provider controls make the worst leak bounded.

## How INFRO bounds a leaked key

INFRO is an AI control plane in front of provider accounts you connect. For traffic through it:

- **Gateway keys** (`sk_infro_`, stored as a SHA-256 digest) can be limited to chosen providers and to IP ranges; a request from outside them returns `403 ip_not_allowed` before any budget check or provider call. Rotation copies every setting and offers an overlap of none, 1 hour, 24 hours or 7 days; after a leak, use none. See [Authentication](https://infro.io/docs/authentication).
- **Environments:** each gateway key belongs to one environment and never reaches a connection outside it.
- **Budgets** per organization, project, member and key are checked before the provider is called; a request that does not fit returns `402`. See [Spend controls](https://infro.io/docs/org/spend-controls).
- **Provider credentials** are encrypted with AES-256-GCM under a key held outside the database, bound to their organization and connection, and never shown again after saving.
- **Spend alerts** flag a scope whose day departs from its usual day, by email, Slack, Teams, PagerDuty or webhook. See [Alerts](https://infro.io/docs/observability/alerts).

None of that applies to a provider key used directly against the provider, including one taken from INFRO itself. For that case, keep the provider-side layers: a key per connection in its own project or workspace, a provider spend limit on it, network restrictions where the provider offers them, and revocation at the provider. On the Business plan, INFRO's [reconciliation](https://infro.io/docs/cost/reconciliation) with usage access on reads OpenAI's and Anthropic's usage by provider key and can name traffic that did not pass through INFRO; without usage access it reports "not checked".

## Blast-radius checklist

- [ ] Every provider key belongs to one workload and one environment, in its own project or workspace.
- [ ] Every project or workspace that holds a key has a hard spend limit at the provider, sized to that workload.
- [ ] No key lives in the Default Workspace or in a project without a limit.
- [ ] OpenAI projects that call from fixed addresses have an IP allowlist; Google keys have IP and API restrictions.
- [ ] Bedrock uses short-term keys in production.
- [ ] Applications hold gateway keys scoped to one service and environment, each with its own spend limit.
- [ ] Gateway budgets block before the call at key, project and organization level.
- [ ] Provider usage is reviewed per key at least daily for keys that carry production traffic.
- [ ] Each key has a written revocation path and an owner, and revocation has been rehearsed.

## Questions

### What is the fastest way to stop a stolen AI API key?

Revoke it at the provider: delete the key in the provider's console or deactivate it through the provider's API. Rotating it in your own systems is not enough; until the provider revokes it, the old key keeps working for whoever holds it. Then review the provider's usage for that key and contact provider support if you see charges you did not make.

### Can I restrict an OpenAI API key to my server's IP address?

OpenAI supports IP allowlists per organization and per project, with up to 50 addresses or CIDR ranges per list. A request from outside the list fails with 401 ip_not_authorized. Changes can take up to 15 minutes, and OpenAI notes that an allowlist does not replace secure key storage or rotation.

### Does a gateway budget protect me if my provider key is stolen?

No. A gateway budget limits the traffic that goes through the gateway. Someone holding your provider key can call the provider directly and never touch the gateway. Provider-side limits on the key's project or workspace, revocation at the provider and per-key usage monitoring are what bound that case.

### Should applications hold provider API keys?

Preferably not. Give applications keys for your own gateway, scoped to one service and environment, and keep the provider key in one place. A leaked application key can then be revoked without rotating the provider key, and it can only spend what its gateway limits allow.

## Sources

1. OpenCode hack exposes API keys amid AI distillation attacks — BleepingComputer. https://www.bleepingcomputer.com/news/security/opencode-hack-exposes-api-keys-amid-ai-distillation-attacks/ (accessed 2026-10-21)
2. Spend limits — OpenAI. https://developers.openai.com/api/docs/guides/spend-limits (accessed 2026-10-21)
3. Workspaces — Anthropic. https://platform.claude.com/docs/en/manage-claude/workspaces (accessed 2026-10-21)
4. Manage API keys — Google Cloud. https://docs.cloud.google.com/docs/authentication/api-keys (accessed 2026-10-21)
5. API keys — Amazon Web Services. https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html (accessed 2026-10-21)
6. IP allowlist — OpenAI. https://developers.openai.com/api/docs/guides/ip-allowlist (accessed 2026-10-21)
7. Restrict access to Claude with IP allowlisting — Anthropic. https://support.claude.com/en/articles/13200993-restrict-access-to-claude-with-ip-allowlisting (accessed 2026-10-21)
