Outcome
By the end of this lesson, you will be able to issue a per-team virtual key with a hard budget and model allow-list, explain the org ceiling above it, and reason about why keys are org-visible rather than personal.
| Tier | Architect |
| JTBD | ”Give each team an LLM budget they cannot exceed, without handing out vendor credentials.” |
| Personas | Engineering Leader · FinOps Lead · Platform Engineer |
| Prerequisites | M3.10.L2 · M3.6 (budget governance) |
| Time | 9 minutes |
| Bloom verb | Issue (Apply), Explain (Understand), Reason (Evaluate) |
1. Concept
A virtual key is what a team’s application uses in place of a vendor’s API key.
You issue it. It points at the gateway rather than at OpenAI or Anthropic directly. And it carries its own limits, which is the part that matters: the team gets a key that cannot spend more than you decided.
A VIRTUAL KEY CARRIES a HARD USD BUDGET a PER-KEY MODEL ALLOW-LIST an org stamp
WHAT THE TEAM GETS one endpoint and one key. Switching providers is a change of MODEL NAME, not a change of integration.That last line is the developer-facing benefit. An application written against the gateway can move from one provider to another without touching its client code.
Three layers of limit
1. PER-KEY BUDGET each key's own maxBudget2. ORG CEILING a hard cap on TOTAL spend across all of the org's keys3. PER-PROVIDER BUDGET the Budgets page, `ai` scope, tracked against live spendThe org ceiling is the one worth understanding structurally.
IT IS ENFORCED BY THE GATEWAY ON THE ORG'S OWN MINTEDTEAM. A caller-supplied team is REFUSED, which is whatprevents cross-tenant misuse of the ceiling.
Per-key budgets still apply WITHIN it. So a team with a$500 key inside a $2,000 org ceiling is bounded by both.There is one migration caveat with a real consequence: keys minted before the ceiling existed are moved onto the org’s team by a backfill sweep, and until that completes they spend uncapped by the ceiling. The sweep logs it. So if you set a ceiling on an org with existing keys, the ceiling is not instantly effective on all of them.
Budget alerts reuse the existing system
A key's own maxBudget participates in the SAMEnotification system as cloud and AI-provider budgets.
The cost-and-rollup cron reads each budget-bearing key'slive spend and fires: budget.warning at >= 80% (fixed) budget.exceeded at >= 100%naming the key.
Delivery follows any org-wide budget.* subscription.
NO new event type, no new budget row, no migration.The hard stop is separate from the alert: the gateway’s own 429 remains the actual cap. Alerts tell you it is coming; the 429 is what stops it.
Note the 80% threshold is fixed for virtual keys, unlike cloud budgets where the alert threshold is configurable per budget.
Keys are org-visible, not personal
This is the design decision that surprises people, and it is a deliberate departure from how PATs work.
PERSONAL ACCESS TOKENS personal. Yours.VIRTUAL KEYS ORG-VISIBLE.
Within an org, listing keys returns EVERY teammate's key(filtered only by provider scope), and any RBAC-authoriseduser can edit, rotate or revoke ANY of them.
There is NO per-creator ownership lock.The reason is operational: a virtual key is a budget-bounded consumption artifact attached to a team’s application, not a personal credential. When the engineer who created it leaves, the application keeps running and somebody has to be able to rotate the key. A per-creator lock would mean an application whose key nobody can rotate.
ATTRIBUTION IS PRESERVED WITHOUT OWNERSHIP Keys are stamped with their creator, surfaced as a "Created by" column, so an admin can attribute each key to the teammate who made it.
Rotation PRESERVES the original creator, so the attribution survives the operation that would otherwise erase it.Rotation is an overlap, not a swap
Rotation MINTS A REPLACEMENT and REVOKES THE OLD ONE.The new key is shown ONCE.The overlap matters: an application can be updated to the new key before the old one stops working, rather than having a window where nothing works.
Rotation is also gated on update, not create, which is a deliberate RBAC choice covered in L5: rotating a key destroys the old one, so a create-only role must not be able to do it.
The use-this-key guide
On create and on rotate, the one-time reveal shows copy-paste snippets for Claude Code, the OpenAI SDK and cURL, with the key and the gateway URL inlined.
EACH SNIPPET PINS A CONCRETE MODEL: the key's firstallowed model, or for an unscoped key the org's firstregistered model.
WHY: a key REJECTS any model outside its allow-list, anda client's own default model names are not names thefleet's registry knows. An unpinned snippet would failon the first call.
The Claude Code snippet pins both the main model and thebackground-traffic model, and reaches the fleet'sAnthropic Messages API.That is a small detail that prevents the most common first-run failure, and it is worth knowing when you hand a key to a team: the snippet works as given, and a team that substitutes their usual model name may not.
2. Demo
Rolling out keys to four teams:
SETUP org ceiling $4,000/mo 4 teams, 4 keys
payments-api budget $1,200 models: strong tier internal-tools budget $400 models: cheap tier data-platform budget $1,500 models: both experiments budget $200 models: cheap tier ───────────────────────────────────────────────────── sum of keys $3,300 < ceiling $4,000
The gap is deliberate: it leaves room to raise one key without immediately hitting the ceiling.
WEEK 2: the experiments key hit 80% budget.warning fired, naming the key, delivered to the existing #finops-alerts subscription. No new subscription was created for AI: it rode the org-wide budget.* subscription that already existed.
WEEK 3: the experiments key hit 100% budget.exceeded fired. The gateway's 429 stopped the traffic. The team asked for a raise; the answer was to look at what they were spending it on first (L4).
MONTH 2: a departure The engineer who created the data-platform key left.
Under a PAT-style personal model, that key would have been unrotatable and the application would have been running on a credential nobody could manage.
Because keys are org-visible, the team lead rotated it: overlap rotation, updated the app, old key revoked. The "Created by" stamp still shows the original engineer, because rotation preserves the creator.
MONTH 2: the ceiling caveat They raised the ceiling to $5,000 and expected all four keys to be immediately bounded by it.
Three were. One key predated the ceiling's introduction and was still awaiting the backfill sweep onto the org team, so it was spending uncapped by the ceiling. The sweep logged it.
LESSON: after setting or changing a ceiling on an org with existing keys, verify the sweep has completed before treating the ceiling as effective.3. Hands-on (6 min)
1. Issue a virtual key for one team: budget $______ allowed models: ______________
2. Check the reveal snippet. Which model does it pin? ______________________________________________ Is that the key's first allowed model? Y / N (Substituting your usual model name may fail.)
3. Sum your keys' budgets: $______ Your org ceiling: $______ Is there headroom? Y / N
4. If you have pre-existing keys, confirm the backfill sweep completed: Y / N Any key still spending uncapped by the ceiling? ______________________________________________
5. Check your budget.* subscription. Will virtual-key alerts reach a human? Y / N (They ride the existing subscription; no AI-specific one is needed.)Do it through MCP. The same task you just did in the console, asked in one sentence.
BEFORE A ZopNight account with one cloud connected. An AI provider key to register, and a team to issue a virtual key to.ASK "Register this model, issue a key for the research team, and cap it at 2k a month."CHECK the cap is attached to the key you meant. An uncapped key is the AI equivalent of an unscheduled dev environment.Tools behind it: list_ai_models (read, Cost), add_ai_model (write, tier 2, reversible), set_ai_org_budget (write, tier 2, reversible), get_ai_budget_spend (read, Cost). The full catalogue is at zop.dev/learn/mcp-tools.
4. Knowledge check
Q1
Why are virtual keys org-visible and editable by any RBAC-authorised user, unlike personal access tokens?
A. Because the AI spend is a shared budget that nobody in the organisation owns individually to begin with
B. Because RBAC cannot express per-creator ownership on a key entity, so there is nowhere at all to record it against
C. Because the gateway cannot associate a virtual key with any single named user in the first place at all today
D. Because a virtual key is a budget-bounded consumption artifact attached to a team’s application rather than a personal credential
Show answer
Correct: D. When its creator leaves, the application keeps running and somebody must be able to rotate it; a per-creator lock would produce an application whose key nobody can rotate. Attribution is preserved by a creator stamp that survives rotation. The distinction between attribution and ownership is the useful part: you can still see who created a key, and that is a different question from who is allowed to manage it.
Q2
An org sets a ceiling of $4,000 on an org that already has four keys. Immediately afterwards:
A. All four of the existing keys are immediately bounded by the new ceiling from the very moment that it is saved in the settings page
B. The existing keys are all revoked and have to be re-issued under the new ceiling before any of them will function once more
C. The ceiling applies only to keys created after it, permanently, so the four pre-existing keys stay outside it for good
D. Keys minted before the ceiling existed are moved onto the org’s team by a backfill sweep, and until that completes they spend uncapped by the ceiling
Show answer
Correct: D. The sweep logs it, so the ceiling should be verified as effective rather than assumed. C overstates it: the sweep does bring them in, it just is not instant. This is the kind of caveat worth checking rather than assuming, because the failure mode is a ceiling you believe is enforcing and is not.
Q3
The one-time key reveal pins a concrete model in every snippet because:
A. The gateway requires a default model to be pinned on every single key before it will accept any request at all from that key, on any provider it is registered against
B. Model pinning is required for cost attribution, since the spend cannot be split at all without knowing which model actually answered each request that was made
C. A key rejects any model outside its allow-list, and a client’s own default model names are not names the fleet’s registry knows, so an unpinned snippet would fail on the first call
D. Snippets cannot include variables of any kind, so a concrete value has to be substituted into them before they are ever shown to the user in the reveal dialog
Show answer
Correct: C. It pins the key’s first allowed model, or the org’s first registered model for an unscoped key. Worth passing on when you hand a key to a team: the snippet works as given, and a team that substitutes their usual model name may find it rejected. The Claude Code snippet pins both the main and background-traffic models for the same reason.
5. Apply
Issue keys with the sum of budgets deliberately below the org ceiling, so you have room to raise one without a second conversation. Then confirm your existing budget.* subscription reaches a human, because virtual-key alerts ride it rather than needing their own.
If you set a ceiling on an org with existing keys, verify the backfill sweep before treating the ceiling as enforced.
Related lessons
- L2: Providers and model registration
- L4: Routing and spend reporting (next)
- L5: AI RBAC and provider scoping
- T3.M3.6.L3: Threshold-crossing notifications
Glossary terms touched
Virtual key · Org ceiling · Overlap rotation · Model allow-list