Skip to content

Force-terminate an active or pending shell session (TASK-S20-004)

DELETE
/api/sessions/{session_id}

Force-terminate a shell session immediately.

Auth

Caller must be authenticated and an org member. Authorisation is then:

  • Session owner (user_id matches): always allowed, regardless of role. Rationale: a user can always close their own session. Documented explicitly because the role-separation invariant otherwise rejects OWNER/ADMIN without a grant.
  • Org OWNER: allowed without a separate role grant (per project convention — OWNER is the unconditional administrative bypass for cross-cutting lifecycle ops like force-terminate).
  • Caller holds ShellRole.SESSION_TERMINATE (“device.shell.terminate”): allowed. This is the normal path for admins who have been granted the terminate role.
  • Any other caller: 403.

Cross-org isolation: the session must belong to organization_id; a session in a different org returns 404 (not 403) to avoid leaking existence information — matches the convention established in approve/deny.

Status guard: only ACTIVE or PENDING sessions can be force-terminated. An already-ENDED session returns 409 Conflict.

Behaviour

On success:

  1. Row-locks the ShellSession row (serialised against concurrent mutations).
  2. Flips status → ENDED, sets ended_at = now, exit_reason = “forced_close”.
  3. Appends a session.ended audit event in the same transaction.
  4. Commits.
  5. Calls gateway_client.kill_session() OUTSIDE the transaction (best-effort WS close — if the gateway is down the backend has already flipped the row).

Errors

404 — session not found, or belongs to a different org. 409 — session is already ENDED or DENIED. 403 — caller lacks terminate permission. 204 — success.

Authorizations

Parameters

Path Parameters

session_id
required
string format: uuid

Query Parameters

organization_id
required
string format: uuid

Request Body

Any of:

Optional request body for DELETE /sessions/{session_id}.

object
reason
Any of:
string
>= 1 characters <= 1000 characters

Responses

204

Successful Response

422

Validation Error

object
detail
Array<object>
object
loc
required
Array
msg
required
string
type
required
string