sk-orca-… string can
spend your balance and drive your agents until you cut it off. This page
is the incident runbook — cut the credential first, then audit what it
did — for customers managing their own keys in the console.
The lifecycle mechanics (disable vs. delete, key states, roles) live in
Manage keys; this page is the under-attack
sequence and, critically, what to check in the audit trail once the
bleeding has stopped.
1. Revoke the leaked api key (do this first)
You have two cut-off moves, both in the console Keys screen (/console/token). Both require the Developer role or above — the
action runs on your session / access token, never on a relay key.
Disable — reversible pause
Flip the key’s status to Disabled. Every request it makes is
rejected immediately, but the key, its limits, its policy
attachments, and its usage history all stay intact. Use this when you
need the config and logs preserved while you dig in.
Delete — permanent revoke
Choose Delete on the key. The credential can never authorize a
request again and is not recoverable. Use this once the leak is
confirmed and you’ve captured what you need from the trail.
2. While you’re at it, tighten the replacement
A leak is the moment to fix the scope that let it hurt. The replacement key should carry the narrowest identity the workload actually needs, so the next leak is a non-event:allow_ips — pin the source
allow_ips — pin the source
An IP allow-list means a leaked key is
useless from any address but yours. Requests from unlisted IPs are
rejected at the auth layer before they cost anything.
credit_limit_usd — cap the spend
credit_limit_usd — cap the spend
A spend cap (
0 = unlimited)
bounds the worst case. A leaked key with a tight weekly ceiling can’t
drain your workspace balance.model_limits — pin the models
model_limits — pin the models
Model limits stop a thief from
switching your cheap key onto your most expensive model.
expired_time — give it a deadline
expired_time — give it a deadline
An expiry (
-1 = never) means a key
that escapes your notice still stops authorizing on its own.3. Audit the request logs — what did the key call?
With the credential cut, scope the damage. Every relay call that key made is recorded in your workspace request logs, and each row carries the fields you need to reconstruct the incident:| Field | What it tells you |
|---|---|
token_name / token_id | Which key — confirm you’re looking at the leaked one. |
ip | The source address of each call. A burst from an IP you don’t recognize is the smoking gun. |
| model + usage | Which models were hit and what they cost — your spend exposure. |
- Is there traffic from an IP that isn’t yours? That’s confirmed misuse, not a false alarm.
- Did the spend or call pattern spike around the leak window? A sudden jump is the attacker’s footprint.
If the key carried an
allow_ips list, calls from outside it never
authorized in the first place — so the absence of foreign-IP rows is
itself a clean bill of health. This is exactly why pinning the source
(§2) turns a leak into a
non-event.4. Read the policy trail — what did it try to do?
Request logs tell you what the key called; the policy planes tell you what it tried to make the model say or do, and whether your guardrails and firewall caught it. Both are workspace-scoped. Guardrail matches are readable by any workspace member; the firewall Events / Runs view requires the Developer role or above (firewall policies and settings stay open to every member).Guardrail matches
Every time the key’s traffic hit a guardrail rule, a match record
landed at
GET /api/guardrail/match — carrying the rule type,
action (block / mask / flag), stage, and the offending detail.
Filter to the leaked key’s window to see what content it pushed
through (PII, secrets, jailbreak attempts).Firewall events
Every tool call the key issued is a firewall event —
allow,
audit, deny, sanitize, or held. A run of deny events is an
agent that tried something it wasn’t allowed to. Roll them up by run
in the Events / Runs view.- Guardrail matches log the matched substring only if “Log raw content” was on for that guardrail (it’s off by default) — so a match row may show the rule and action without the raw text. The type / action / stage are always there.
mark-fpon a match (POST /api/guardrail/match/:id/mark-fp, Admin) lets you flag a hit as a false positive so it stops skewing your incident view — don’t use it to bury real misuse.- Firewall denies are pre-tool. A
denyevent means the attacker’s tool call was blocked before it reached the tool — the firewall already contained that action. The event is your evidence it tried.
5. After the incident
Confirm the old credential is dead
Confirm the old credential is dead
Re-check the Keys list: the leaked key should read Disabled or be
gone entirely. If you only disabled it, schedule the delete once
you’ve finished the audit — see Manage keys.
Roll the replacement in cleanly
Roll the replacement in cleanly
Move traffic to the new, tighter-scoped key before retiring the old
one so there’s never a no-working-key gap. Full handoff:
Key rotation.
Harden so the next leak is a non-event
Harden so the next leak is a non-event
If the leaked key had no
allow_ips, no credit_limit_usd, and broad
model_limits, that’s the real finding. Give every agent its own
narrowly-scoped key — the
Least-agency checklist and
Scope & keys
walk the whole posture.6. Related
Manage keys
Disable vs. delete, key states, and the role gates behind each action.
Key rotation
The zero-downtime handoff from a compromised key to a clean one.
IP allow-list
Pin a key to your source addresses so a leak can’t be used elsewhere.
Data exfiltration
The threat a leaked key most often feeds, and how the firewall’s
egress surface bounds it.
