---
title: Kill switch and session controls
description: Suspend, resume or revoke one agent session, quarantine an agent
  reversibly, or kill an agent, a session or a wider scope for good.
url: https://hexelstudio.com/docs/titan/kill-switch
---

Titan gives you three ways to stop an agent. Each one takes effect on the agent's next action through Titan and is recorded in the [Agent Ledger](https://hexelstudio.com/docs/titan/agent-ledger) with who did it and why.

| Control | Scope | Reversible | Permission |
| --- | --- | --- | --- |
| [Suspend, resume or revoke a session](#suspend-and-resume-a-session) | One running session | Suspend: yes. Revoke: no. | `titan:session:manage` |
| [Quarantine](#quarantine) | An agent, an agent deployment, the organization, a workspace or an environment | Yes | `titan:session:manage` |
| [Kill](#kill) | An agent, deployment, session, organization, workspace, environment, capability, connection or destination | **No** | `titan:kill:manage` |

Every control takes a `reason_code`: `OPERATOR_REQUEST`, `SECURITY_INCIDENT` or `POLICY_VIOLATION`.

These controls stop what the agent does **through Titan**. A process that doesn't call Titan keeps running; see [What Titan does not control](https://hexelstudio.com/docs/titan/overview#what-titan-does-not-control).

## Suspend and resume a session

A suspended session can't act: Titan refuses its requests, and coding agents on a developer's machine refuse their tool calls with a message that the session is suspended. Resuming restores the session exactly as it was. Find session ids (`ses_...`) in **Titan → Sessions** in the console, or with `hexel titan session list`.

```bash
curl -X POST https://api.hexelstudio.com/v1/titan/admin/sessions/ses_0123456789abcdef/restrict \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Titan-Enforcement-Deployment: $TITAN_ENFORCEMENT_ID" \
  -H "Content-Type: application/json" \
  -d '{"action": "suspend", "reason_code": "SECURITY_INCIDENT"}'
```

| `action` | Result |
| --- | --- |
| `suspend` | The session's state becomes `suspended`. |
| `resume` | A suspended session becomes `active` again. Resuming a session that isn't suspended returns `409 SESSION_NOT_SUSPENDED`. |
| `revoke` | The session's state becomes `revoked`, for good. A revoked session can't be resumed. |

The response is `{"session_id", "state", "changed"}`; `changed` is `false` when the session was already in that state. A session that has ended or expired returns `409 SESSION_NOT_ACTIVE`.

With the CLI:

```bash
hexel titan session suspend ses_0123456789abcdef
hexel titan session resume ses_0123456789abcdef
hexel titan session revoke ses_0123456789abcdef
```

Resuming never extends a session's lifetime, changes its identity, or lifts a quarantine or a kill that also applies to it.

## Quarantine

A quarantine stops every session inside a target at once, and can be lifted. While it is in force Titan refuses every token exchange and request of those sessions, refuses actions that were already approved, and tells connected agents their sessions are suspended. Lifting it restores exactly what was there.

```bash
curl -X POST "https://api.hexelstudio.com/v1/titan/admin/agent-controls:quarantine" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Titan-Enforcement-Deployment: $TITAN_ENFORCEMENT_ID" \
  -H "Content-Type: application/json" \
  -d '{"target_type": "agent", "target_id": "agt_0123456789abcdef", "reason_code": "SECURITY_INCIDENT"}'
```

`target_type` is `agent`, `deployment` (an agent deployment), `organization`, `workspace` or `environment`. To lift it, send the same body to `agent-controls:resume`. With the CLI:

```bash
hexel titan control quarantine agt_0123456789abcdef --reason SECURITY_INCIDENT
hexel titan control resume agt_0123456789abcdef
hexel titan control list
```

## Kill

A kill is permanent. Once Titan has it, every check refuses the target forever: token exchange, every request, every grant, and connected agents are told to stop. Nothing lifts a kill; to start again, create a new agent, deployment or session.

```bash
curl -X POST "https://api.hexelstudio.com/v1/titan/admin/agent-controls:kill" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Titan-Enforcement-Deployment: $TITAN_ENFORCEMENT_ID" \
  -H "Content-Type: application/json" \
  -d '{"target_type": "session", "target_id": "ses_0123456789abcdef", "reason_code": "SECURITY_INCIDENT"}'
```

| `target_type` | `target_id` |
| --- | --- |
| `agent`, `deployment`, `session` | The agent, agent deployment or session id |
| `organization` | Your organization id |
| `workspace`, `environment` | A workspace or environment one of the deployment's agents runs in |
| `capability` | A capability id in the deployment's catalog, for example `slack.message.post` |
| `connection` | The connected account's id |
| `destination` | A `type:id` boundary that a capability uses |

A target outside your organization returns `404`. With the CLI, `hexel titan kill TARGET_ID --type <type>` asks for confirmation first. See [`hexel titan kill`](https://hexelstudio.com/docs/cli/commands).

<Warning>
Prefer a quarantine while you investigate. Use a kill when the target must never act again, for example a leaked credential's connection.
</Warning>
