Skip to content

Open a Standard, Elevated, or Break-Glass shell session

POST
/api/devices/{device_id}/sessions

Create a new shell session record for a device (Standard, Elevated, or Breakglass).

After creating the session DB row, calls the gateway to mint a short-lived WS upgrade token and includes ws_url, ws_token, and ws_expires_at in the response.

Tier dispatch

The AND-gate (device.shell.<tier> role + Shell Access Group membership) is enforced at runtime via enforce_shell_access_for_tier because the tier is read from the request body. All three tiers use the same single endpoint and the same single shell session constructor call.

Justification policy

Standard: optional. Elevated/Breakglass: required (validated by OpenSessionRequest — Pydantic 422 before this function is called).

Break-Glass incident

For breakglass sessions a ShellIncident row is created immediately after the session commits, BEFORE the gateway call, to ensure the audit trail is intact even when the gateway is down.

Graceful degradation

  • If the gateway is not configured (dev/test, no GATEWAY_INTERNAL_URL), ws_url / ws_token / ws_expires_at are returned as None and the session row is still created (HTTP 201).
  • If the gateway IS configured but returns an error → HTTP 502 Bad Gateway.

Errors

403 — caller lacks the required tier role or Shell Access Group membership. 404 — device not found in this organisation. 409 — device tunnel is offline; cannot open a shell session. 422 — validation error (unknown tier, justification missing/too-long, etc.). 502 — gateway configured but returned an error.

Authorizations

Parameters

Path Parameters

device_id
required
string format: uuid

Query Parameters

organization_id
required
string format: uuid

Request Body required

Request body for opening a new shell session.

Tier validation

tier must be one of "standard", "elevated", or "breakglass". Unknown values are rejected with HTTP 422.

Justification policy (TASK-S17-004)

  • standard: justification optional (unchanged behaviour).
  • elevated: justification required (after .strip(), non-empty). Empty/whitespace-only → 422 "justification is required for elevated sessions".
  • breakglass: justification required (same enforcement as elevated). Empty/whitespace-only → 422 "justification is required for breakglass sessions".
object
justification
Any of:
string
<= 1000 characters
tier

Session tier: ‘standard’, ‘elevated’, or ‘breakglass’. Elevated and Breakglass require a non-empty justification.

string
default: standard
Allowed values: standard elevated breakglass

Responses

201

Successful Response

Public representation of a shell session.

Secret / sensitive fields (client_ip, user_agent, recording_uri, recording_sha256) are intentionally EXCLUDED from this schema.

WebSocket connection fields (ws_url, ws_token, ws_expires_at) are populated only when the gateway is configured and the session was opened via POST /devices/{id}/sessions. They are None in list/get responses and in dev environments where the gateway is not running.

ws_token is included so the browser can supply it as a WebSocket subprotocol (Sec-WebSocket-Protocol) when opening ws_url — never appended to the URL query string, so it does not land in proxy access logs (GAP-FE-007). It is short-lived (~60 s) and single-use; do NOT persist it.

object
created_at
required
string format: date-time
device_id
required
string format: uuid
ended_at
required
Any of:
string format: date-time
exit_reason
required
Any of:
string
id
required
string format: uuid
justification
required
Any of:
string
organization_id
required
string format: uuid
recording
boolean
started_at
required
Any of:
string format: date-time
status
required
string
tier
required
string
user_id
required
Any of:
string format: uuid
ws_expires_at
Any of:
string format: date-time
ws_token
Any of:
string
ws_url
Any of:
string

422

Validation Error

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