Open a Standard, Elevated, or Break-Glass shell session
const url = 'https://example.com/api/devices/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/sessions?organization_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"justification":"example","tier":"standard"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url 'https://example.com/api/devices/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/sessions?organization_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "justification": "example", "tier": "standard" }'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_atare returned asNoneand 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
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “ Path Parameters ”Query Parameters
Section titled “ Query Parameters ”Request Bodyrequired
Section titled “ Request Bodyrequired ”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".
Responses
Section titled “ Responses ”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
Example
{ "recording": false}Validation Error
object
object
object
Example generated
{ "detail": [ { "ctx": {}, "input": "example", "loc": [ "example" ], "msg": "example", "type": "example" } ]}