Kill switch and revocations#
The kill switch is the capability to stop an agent, a session, a user's agents, a token, a namespace or everything, across every gateway replica, within seconds. Each kill-switch entry is a revocation: what is revoked, by whom, why and until when. The verb is revoke.
Revocations work at two levels:
- At the gateway, every
/mcp,/llm,/a2aand egress call is checked against the revocation list right after the token is verified, and again after an approval wait. A match is denied with reasonrevoked. - At the operator, a revocation can also act on the sessions themselves:
suspendpauses their sandboxes andterminatedeletes the sandbox and token and fails the session with resultRevoked. A revoked session is never given a new token.
Two ways to revoke#
| Path | How | Effective |
|---|---|---|
AgentRevocation (short name arev), GitOps-friendly |
Create the object (or maqpna kill --emit-yaml \| kubectl apply -f -). The operator renders every non-expired revocation into the ConfigMap maqpna-revocations; the gateway polls it |
About 1 to 3 seconds with the gateway's configSync (default on in the chart); 60 to 90 seconds if the gateway relies on kubelet volume refresh only |
| Break-glass at the gateway | maqpna kill --gateway URL ... calls POST /v1/revocations (role killswitch or admin) |
At once on the receiving replica; on other replicas within stateBackend.pollMillis (250 ms) with Postgres. Mirrored to an AgentRevocation named breakglass-<id> so the operator applies suspend and terminate |
What a revocation matches#
A revocation has a namespace (empty, or created in the gateway namespace, means cluster-wide) and matchers:
| Matcher | Matches |
|---|---|
sessions |
Session names (globs) |
agents |
Agent names (globs) |
users |
The person the agent acts for (globs) |
jtis |
Token IDs, exactly; also tokens exchanged from them (maqpna_parent_jti) |
all |
Every session in scope (the global kill when cluster-wide) |
Matching is AND across fields and OR within a field. For A2A calls the gateway checks the caller, every agent in its delegation chain and the callee. The action is block (default; calls are refused), suspend or terminate; when several revocations match a session, the strictest action wins.
flowchart LR
K1["maqpna kill --gateway ..."] -- "POST /v1/revocations" --> G["Gateway replicas<br/>(revocation list)"]
K1 -. "mirror: AgentRevocation breakglass-id" .-> AR
K2["kubectl apply AgentRevocation"] --> AR["AgentRevocation"]
AR --> OP["Operator"]
OP -- "ConfigMap maqpna-revocations" --> G
OP -- "suspend or terminate" --> SB["Sessions and sandboxes"]
G -- "every call: revoked?" --> D["deny · revoked<br/>rule revocation/id"]
Fail closed#
If the gateway is configured with a revocation list and cannot read it (missing, unreadable or invalid; one bad entry rejects the whole file), every /mcp and /llm call is denied with revocation_list_unavailable, /readyz returns 503, and maqpna_gateway_revocation_list_ok is 0. The Helm chart creates the ConfigMap with an empty list and mounts it, so a fresh installation starts with a readable list.
What you see#
The maqpna kill usage, from cmd/maqpna/testdata/help-kill.golden:
Usage:
maqpna kill --gateway URL [-n NS] [--agent A]... [--session S]... [--user U]... [--jti J]... [--all] --reason TEXT [--suspend|--terminate] [--ttl 1h] [--emit-yaml] [--yes]
maqpna kill asks for confirmation (for example Revoke and terminate agent coder in namespace team-a), warning that "Revoking stops every matching session's tool and model calls within about a second. Running tool calls are cut off." It then prints the revocation and where it was mirrored (values illustrative):
revoked (terminate, namespace team-a): breakglass/7f3a9c0e5b21d4a6
mirrored to AgentRevocation team-a/breakglass-7f3a9c0e5b21d4a6
maqpna revocations list prints ID SOURCE ACTION NAMESPACE EXPIRES REASON, with * for cluster-wide entries and - when an entry does not expire. A denied tool call carries {"reason":"revoked","policy":"revocation/<id>"} in its JSON-RPC error. See maqpna kill, maqpna revocations list and maqpna revocations delete.