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_..."]}
Incidents and closed-loop remediation¶
Serious containment events (a budget breach that stops a run, a revocation that
halts in-flight sessions) are opened automatically as incidents. An incident
records what was contained and the remediation steps taken, is sealed to the
Provenance Vault, and fires an incident.opened webhook so an on-call human or
system is notified. List, review, and resolve incidents from the Incidents tab
in the dashboard or the API.
Compensating actions (rollback)¶
When an executed action needs to be undone, request compensating actions on
the incident. Xybern records each one, seals it, and dispatches an
incident.compensation_requested webhook; your registered handler performs the
undo. Xybern orchestrates and proves the rollback, it does not reach into your
downstream systems itself.
curl -X POST https://www.xybern.com/api/v1/enforce/incidents/inc_.../remediate \
-H "X-API-Key: $XYBERN_API_KEY" -H "Content-Type: application/json" \
-d '{"compensating_actions": [{"action_type": "reverse_transfer", "target": "txn_123"}]}'
Self-hosted relay¶
If you run the self-hosted relay, actions that belong to a session are authorised by the cloud, so runtime budgets and the kill switch are enforced consistently across your fleet; policies without a session are still evaluated locally, and content for those never leaves your network.
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) |
GET |
/v1/enforce/incidents |
List containment incidents (open first) |
GET |
/v1/enforce/incidents/{id} |
Incident detail + remediation steps |
POST |
/v1/enforce/incidents/{id}/resolve |
Resolve an incident |
POST |
/v1/enforce/incidents/{id}/remediate |
Request compensating actions (rollback) |
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.