Runtime Containment (Agent EDR)¶
Most agent authorisation is a point-in-time gate: each action is allowed or denied on its own. Runtime containment goes further, giving you continuous control over an agent that is already running. You can set live budgets, kill a runaway or compromised agent mid-run, and revoke a credential to halt everything using it, not just its next action. Think of it as EDR (endpoint detection and response) for AI agents: not a policy form, but the ability to contain an agent in flight.
Every containment action is sealed to the signed, tamper-evident Provenance Vault, so it is fully auditable.
Sessions¶
A session ties one agent run together. Live budgets, the kill switch, and the
in-flight halt all hang off it. Open one with the SDK or the API at the start of
a run, and pass its session_id on every action.
curl -X POST https://www.xybern.com/api/v1/enforce/sessions/start \
-H "X-API-Key: $XYBERN_API_KEY" -H "Content-Type: application/json" \
-d '{"agent_id": "loan-bot", "label": "loan-risk monitor",
"budgets": {"max_actions": 200, "ttl_seconds": 3600}}'
# -> {"session_id": "sess_...", "status": "active", "budgets": {...}}
Live budgets¶
Set per-session limits when you open the session. Every action is counted at the
enforcement choke-point, and when a budget is exceeded the session is killed and
the action returns the terminate verdict.
| Budget | Meaning |
|---|---|
max_actions |
Maximum actions the agent may take in this run |
ttl_seconds |
Wall-clock lifetime of the session |
This stops a runaway loop or a scraping burst automatically, before it runs up a bill or exfiltrates a dataset. (Token and spend budgets are on the roadmap.)
The kill switch¶
Kill a running session at any moment, from the Live Sessions tab in the dashboard (a Kill button on every active run) or via the API:
curl -X POST https://www.xybern.com/api/v1/enforce/sessions/sess_.../kill \
-H "X-API-Key: $XYBERN_API_KEY" -d '{"reason": "manual stop"}'
The session's next action returns terminate, and an integrated agent aborts
within seconds (see below).
In-flight halt (SDK heartbeat)¶
Terminating the next action is not enough for a long-running agent that might not
call out for a while. The Python SDK opens a session and runs a background
heartbeat, so the moment a session is killed, expires, or blows a budget, the
next guard() or intercept() raises SessionTerminated and aborts the run at
the next action boundary.
from xybern import auto, RuntimeSession, SessionTerminated
client = auto.client()
try:
with RuntimeSession(client, agent_id="loan-bot",
budgets={"max_actions": 200, "ttl_seconds": 3600}) as sess:
for step in agent:
sess.guard() # aborts fast if killed / expired
sess.intercept("transfer_funds", action_content=step.text)
...
except SessionTerminated as e:
log.warning("Agent contained: %s", e)
Honest boundary: Python cannot safely interrupt a blocked, non-cancellable
call, so the halt lands at the next guard()/intercept(). That is still far
beyond "deny the next action", a runaway or compromised agent is stopped within
one heartbeat plus one step.
Credential revocation cascade¶
Revoke once, everything using it stops. Revoking an agent credential kills every active session bound to that credential or its agent, so in-flight runs halt immediately rather than only future actions. The revoke response reports which sessions were stopped.
curl -X POST https://www.xybern.com/api/v1/enforce/credentials/cred_.../revoke \
-H "X-API-Key: $XYBERN_API_KEY" -d '{"reason": "key compromised"}'
# -> {"ok": true, "credential": {...}, "killed_sessions": ["sess_..."]}
The terminate verdict¶
Runtime containment introduces a terminal decision distinct from block:
blockdenies one action; the agent can carry on with others.terminatestops the whole run; the session is over.
Both are recorded as enforcement decisions and sealed to the Vault.
Live Sessions dashboard¶
The Live Sessions tab (under Authorisation in the Sentinel dashboard) shows every session with its status, agent, a real-time action-budget bar, and its start time. Active runs carry a Kill button, and the tab refreshes on its own so you can watch a budget fill and stop a run with one click.
API reference¶
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/enforce/sessions/start |
Open a session (optional budgets) |
GET |
/v1/enforce/sessions |
List sessions (active first) |
GET |
/v1/enforce/sessions/{id} |
Session detail |
POST |
/v1/enforce/sessions/{id}/heartbeat |
Poll status (SDK uses this to abort out of band) |
POST |
/v1/enforce/sessions/{id}/kill |
Kill the session |
POST |
/v1/enforce/sessions/{id}/end |
End a completed session |
POST |
/v1/enforce/intercept |
Pass session_id to enforce budgets + kill switch |
POST |
/v1/enforce/credentials/{id}/revoke |
Revoke a credential (cascade-kills its sessions) |
Everything is sealed¶
Every session lifecycle event (started, budget exceeded, killed, expired, ended) is written to the hash-chained, ECDSA P-256 signed Provenance Vault. So a containment action is not just done, it is provable: an auditor can verify offline that the agent was stopped, when, and why.