← all posts
[ deep dive ]August 4, 202610 min read

Where the credential lives: credential brokering for AI agents

An IETF draft and the LiteLLM supply-chain compromise are converging on one rule: never give an AI agent a reusable secret. Here's the architecture, and an honest account of how much of it Wide Area Intelligence already implements — including the parts we haven't finished.

Before you get to sandboxing, egress filtering, or where your agent runs, there is a more basic question, and most architectures answer it by accident: at the moment the agent makes a call, where does the credential live?

If the answer is anywhere the agent can read — its environment, its config file, its context window — you have decided to trust a goal-seeking, stochastic system with a reusable secret. That deserves more scrutiny than it usually gets, because the failure mode is not exotic. Prompt injection, context exfiltration, and plain accidental disclosure sound like three different attacks. They are three delivery mechanisms for the same outcome: the bytes of a credential leave the agent, and they still work.

And leaking is not even the interesting case. An agent can hand over its own credentials without being attacked at all, because it believes doing so solves the problem you gave it.

What March 2026 demonstrated

This stopped being theoretical in March, when the TeamPCP supply-chain campaign compromised LiteLLM — an AI gateway whose entire job is holding API keys for dozens of model providers. The injected credential stealer harvested LLM API keys, SSH keys, cloud credentials, and .env files from every machine running the affected versions. Public estimates put it at 300+ GB of compressed credentials across roughly 500,000 corporate identities.

The lesson is uncomfortable for anyone who operates an AI gateway, ourselves very much included: when AI infrastructure concentrates long-lived credentials into a single process or configuration, compromise of that process yields catastrophic access. “We encrypt at rest” is not an answer, because the compromised process is the thing holding the decryption capability.

The three answers

Kenneth G. Hartman's IETF Internet-Draft Credential Broker for Agents (CB4A), published the same month, sets out the design space. Its core structural idea is to split the component that decides “yes” from the component that hands out the credential, so that compromising one does not yield the other. On top of that split, it defines three ways a broker can mediate access:

modelwhat the agent getsblast radius
A — proxy gatewayNothing. It calls a proxy; the real credential is injected on egressMinimal — there is no secret on the agent's side worth stealing
B — token mintingA short-lived, narrowly scoped derivative tokenBounded by the TTL, but a real credential still sits in agent memory
C — credential wrappingThe real long-lived credential, revoked afterwardFull, until revocation succeeds — if it succeeds

The draft recommends Model B as the primary, with Model A as a fallback. We think that is backward for most systems being built today, and so does Christian Posta, who has argued the case at length in the agentgateway project. Model B leans on sender-constrained tokens (DPoP) to make a stolen token useless — but that takes two participants. The issuer has to bind the token to a key, and the receiving service has to verify the proof on every request. GitHub personal access tokens, most SaaS OAuth tokens, and essentially every API key in circulation verify nothing of the kind. Miss either half and you are back to a bearer token, just a shorter-lived one.

Models B and C shrink the window in which a leaked credential is useful. Model A removes the thing that leaks.

What we already do

Wide Area Intelligence is a Model A proxy gateway, and has been since before the draft existed — not because we were following a specification, but because routing inference across hardware you own and clouds you don't makes any other answer untenable. Here is the actual arrangement, layer by layer.

01

Your application holds a handle, not a secret

Callers authenticate with a wai_sk_… gateway key. We store a SHA-256 hash of it plus a short display prefix — never the key. It cannot be read back out of our database by anyone, ourselves included, and revoking it takes effect on the next request. It is also a handle to us, not to any provider: possessing it does not let you spend against an OpenAI or Google account.
02

The gateway does not hold the provider keys either

This is the part that matters most given LiteLLM. Our provider credentials — OpenAI, Google, OpenRouter and the rest — are stored inside Cloudflare AI Gateway. The application worker holds only a token authenticating it to that gateway. Compromising our worker does not yield a set of portable provider keys an attacker can walk away with and use from anywhere, forever. It yields the ability to make calls while the compromise is live — which is revocable, rate-limited, and visible. That is precisely the distinction between the offline smash-and-grab that hit LiteLLM and something you can actually respond to.
03

We removed the option to give us your keys

Earlier versions accepted user-supplied provider keys. In June 2026 we deleted that path: cloud failover is credit-billed only, and existing stored values were nulled out in production. The column survives in the schema, deprecated and never read, as a reminder. The most reliable way to avoid becoming a credential concentrator is to decline to hold the credentials.
04

Node identity is scoped, rotatable, and expiring

Each node authenticates with a wai_node_… key, again stored only as a hash. Every key carries a scope — the default lets a node act on its own row and nothing else, rather than as an account-wide credential, because a node key sits on every machine in the fleet. The bearer the gateway presents for inference is a separate, independently rotatable secret, deliberately decoupled from the identity credential so that rotating one never bricks the other.
05

Fleet enrollment assumes the credential will leak

Enrollment tokens (wai_enroll_…) exist to be baked into machine images and cloud-init user-data, so we treat them as already-leaked. They can do exactly one thing: exchange themselves for a fresh node key. Expiry is mandatory and cannot be null. Each carries a cap on how many live nodes it may hold at once, so a runaway autoscale — or a stolen token — hits a wall instead of a billing surprise. Every attempt, successful or refused, is written to an audit table with its source IP, so a walked credential shows up as refusals piling up rather than as an inference from node counts.
06

Nodes never receive cloud credentials

A node in the fleet gets an inference bearer scoped to itself. Cloud provider credentials never traverse that boundary. When a request fails over from your hardware to the credit-billed cloud, that egress happens at the gateway, with the credential injected there — the node is not involved and never sees it.
07

Connector tokens are encrypted at rest

OAuth tokens for read-only account connectors are sealed with AES-GCM before they touch the database, with a versioned ciphertext prefix so the scheme can be rotated without ambiguity. The encryption key is never sent to a browser, and plaintext credentials never reach the client.

What we have not solved

An architecture post that only lists strengths is marketing. Two things here are genuinely unfinished, and both are worth stating plainly.

Our connector envelope is the weak mode. Posta classifies these deployments by who holds the key-encryption key. The strong version keeps it in a KMS and requires a separate broker to authorize each individual unwrap, so the process holding the ciphertext cannot decrypt it using its own authority. Ours does not do that yet: the encryption key is derived inside the same worker that performs the decryption. That is enough to make a database export useless to whoever obtains it, which is what it was built for. It is not enough to contain a compromise of the worker itself. The fix is well understood — a fresh per-row data key on every write, cryptographically bound to the owning user and provider so ciphertext cannot be moved between rows, and the unwrap operation moved behind a separate authority that logs and can refuse. Scoped, and on the list.

The harder question is one the draft does not really cover. CB4A assumes the agent runs on infrastructure the operator controls. Distributed inference breaks that assumption. When the agent's tools execute on a node — a workstation, an on-prem server, and eventually hardware belonging to someone selling spare capacity — then “don't give the agent a credential” becomes a strictly harder problem than the draft's version. You are no longer deciding whether to trust a process. You are deciding whether to ship a bearer credential to a machine you do not own, with no revocation story and no audit of what it did with it.

Our answer, and the design constraint we are holding to as node-side tooling lands: tools that require a credential egress through the gateway with just-in-time injection, and node-local execution is reserved for tools that need no credential at all — local search, retrieval over your own documents, transcription. That costs something real. Routing an authenticated tool call through the gateway means the request leaves your hardware, which is exactly the property some customers chose us for. We would rather name that trade-off than quietly resolve it in the direction that demos better.

The rule underneath all of it

Strip away the specification language and one principle does the work: the authority to use a credential should live as far as possible from the component that can be talked into misusing it. An LLM is, by construction, a system that can be talked into things. It should therefore hold nothing that retains value once it leaves.

Everything else — hashing rather than storing, scoping node keys to their own row, capping and expiring enrollment tokens, keeping provider keys out of our own application, declining to accept yours — is that one rule applied at each boundary in turn.

Route your first request through the gateway →

Frequently asked questions

Does Wide Area Intelligence store my OpenAI or Google API keys?
No. We removed the ability to supply provider keys entirely in June 2026 — cloud failover is credit-billed only. The platform's own provider credentials are held inside Cloudflare AI Gateway, not in our application code, so our gateway worker never handles a raw provider key at all.
What happens if my gateway API key leaks?
Revoke it from the dashboard and it stops working immediately. We only ever store a SHA-256 hash of the key plus a short display prefix, so the key itself cannot be read back out of our database — not by us, and not by anyone who obtains a copy of it.
Do my nodes receive cloud provider credentials?
No. A node receives an inference bearer token scoped to that one node and nothing else. Cloud provider credentials never leave the gateway, so a compromised node cannot spend against a provider account.
What is CB4A?
Credential Broker for Agents, an IETF Internet-Draft by Kenneth G. Hartman published in March 2026. It specifies an architecture where AI agents never hold long-lived API credentials; instead a broker injects or mints short-lived, scoped, audited credentials on their behalf.

/// get started

That GPU is already paid for.
Put it on the network.

Create your gateway — free →