bus-api-provider-terminal — terminal API provider
bus-api-provider-terminal — terminal API provider
bus-api-provider-terminal owns the API boundary for browser terminal access.
Portal UI modules call this provider for authenticated browser terminal
sessions.
Use this provider when a web portal needs shell-style access to a user-owned runtime, such as a non-persistent container running Codex. The provider exposes an authenticated API surface for session creation, input, output, and cleanup.
Authentication
Terminal APIs require a Bus API JWT with audience ai.hg.fi/api.
Clients send it as Authorization: Bearer <Bus API JWT>.
Write operations require terminal:write. Read operations require
terminal:read. Every operation is account-isolated by JWT sub.
JWT validation is strict: tokens must be HS256 signed, use JWT type when typ
is present, include exp, pass issued-at/expiry checks with configured clock
skew, match the accepted audience, and match the configured issuer when one is
set. none and wrong-algorithm tokens are rejected.
The local backend stores terminal session state in memory. Production deployments can connect this API boundary to container or SSH execution while keeping portal clients on the authenticated terminal API.
POST /api/v1/terminal/sessions
Creates a terminal session for the authenticated account.
Use this after the user has an approved account and the portal has a valid Bus
API token.
The request body may be {} for the default local backend. Success returns
201 Created with id, account_id, state, optional rows, cols, and
initial output.
GET /api/v1/terminal/sessions/{id}
Returns metadata for one owned terminal session.
The provider rejects reads for sessions owned by another account.
Success returns 200 OK with the session object.
GET /api/v1/terminal/sessions/{id}/output
Returns terminal output for one owned session.
Use this endpoint for browser polling or streaming-style UI updates, depending
on deployment configuration.
Success returns 200 OK with {"id":"...","output":["..."]}.
GET /api/v1/terminal/sessions/{id}/stream
Streams terminal output for one owned session as Server-Sent Events.
Each event uses event: output and a JSON data payload containing the
session id and one output line. Closing the browser stream cancels the server
subscription.
POST /api/v1/terminal/sessions/{id}/input
Sends input to one owned terminal session.
Treat terminal input as sensitive operational data. Do not log raw input in
production.
Send {"input":"command text\n"}. Success returns 202 Accepted with the
updated session object.
POST /api/v1/terminal/sessions/{id}/resize
Updates terminal dimensions for one owned session.
The JSON body contains positive integer rows and cols. Use this when the
browser terminal viewport changes size.
Rows and columns must be between 1 and 1000. Success returns 202 Accepted
with the updated session object.
DELETE /api/v1/terminal/sessions/{id}
Closes one owned terminal session.
Call this when the browser session ends or the owning container run is cleaned
up.
Success returns 200 OK with the closed session object.
GET /readyz
Reports provider readiness.
Success returns 200 OK with {"ok":true}.
Errors use {"error":{"type":"...","message":"..."}}. Missing or invalid
bearer tokens return 401 invalid_auth, invalid JSON or dimensions return
400 bad_request, missing sessions return 404 not_found, and unavailable
streaming returns 500 streaming_unavailable.
Portal Use
bus-portal-ai calls this provider after the user has logged in through
bus-portal-auth. The browser sends the Bus API token as bearer
authorization. The terminal provider validates the token and ensures the
session belongs to the account in JWT sub.
Terminal access should be combined with container ownership checks when the terminal is attached to container-backed work. A user must not be able to read or write terminal sessions for another account’s container.
Security Notes
Use HTTPS for browser access. Do not expose terminal APIs without JWT validation. Do not log bearer tokens, terminal input containing secrets, SSH keys, or provider credentials. Prefer short session lifetimes and close sessions when the browser disconnects or the owning container run ends.