What the runtime can reach
The runtime is one process inside the session container, running as the session user. This page covers what starts it, who can talk to it, and what the process itself can touch. None of it depends on a model.
No process confinement
Section titled “No process confinement”The runtime has the session user’s rights. It can read and write anything that user can, including the home directory, a mounted persistent profile and other applications’ state, and it can open network connections to anywhere the container’s network allows. It applies no Landlock, seccomp or other kernel-level confinement to itself, and nothing wraps it in a sandbox.
A reviewer should plan for these consequences.
- The runtime handles screenshots of whatever is on the session’s screen, and sends them to
KASM_RUNTIME_VISION_ENDPOINTwhen one is set. A wrong endpoint sends them to the wrong place; the runtime does not restrict egress. - Scenario-provided credentials (
KASM_RUNTIME_SECRET_*) are in the process’s environment and memory. - A bug in the runtime or a library it uses, triggered by hostile content on screen or in a page, would run with the session user’s rights.
The isolation barrier is the session container that Kasm manages. Process confinement is on the roadmap.
The on switch
Section titled “The on switch”On images that include the runtime, it starts only when the session’s environment sets KASM_RUNTIME_SESSION_TOKEN. Without the variable there is no process and no listening port. The same value is the credential callers must present, so switching it on and choosing the token are one step. It is normally set through the Kasm API’s request_kasm environment map. See Enable the runtime on a workspace.
A scripted run (kasm-session-runtime run) is started by whoever launches it, inside the session. It listens on a port only if KASM_RUNTIME_OBSERVE=true, and then serves the read-only observe routes and, with a token set, the inbox routes, never the methods below.
Callers and credentials
Section titled “Callers and credentials”With a session token set, kasm-session-runtime mcp serves HTTP on KASM_SESSION_RUNTIME_PORT (default 9434), bound to KASM_RUNTIME_BIND_ADDR (default 0.0.0.0, which Kasm’s port-map proxy needs). Without a token it serves MCP on stdio to the process that started it, with no authentication, because that process is the caller.
Every credential check is a constant-time comparison of the X-Kasm-Runtime-Session-Token header. The header is not Authorization because Kasm’s port-map proxy overwrites that header.
| Route | What it does | Credential |
|---|---|---|
/mcp |
MCP over Streamable HTTP: every method, including shell |
Session token |
POST /v1/call/{method} |
The same methods over plain HTTP | Session token |
/v1/files/..., /v1/dirs/... |
File transfer | Session token only; the messaging token is refused |
/cdp/ |
Raw Chrome DevTools Protocol proxy, only when KASM_ENABLE_CDP is set |
Session token |
GET /events, GET /artifacts/<file> |
Read-only: the live trace and the run’s output directory | None by default; see below |
| Inbox write routes | Messages, attachments, stop, finish_handoff |
Messaging token (KASM_RUNTIME_INBOX_TOKEN) or session token |
Inbox request routes, ack |
Typed questions to the person, delivery acknowledgement | Session token only |
GET /v1/openapi.json |
The OpenAPI description of this listener | None |
Limits:
- The observe routes (
/events,/artifacts/) and inbox reads are open by default, because the in-session sidebar is a static page with no way to hold a token. Kasm’s reverse proxy limits the port map to the session’s owner, but anything else that can reach the port directly, such as another container on the same network, can read the run’s screenshots, trace and report. SetKASM_RUNTIME_OBSERVE_TOKEN_REQUIRED=trueto require a token on them; with that set and no token configured they refuse every request. Pair it withKASM_RUNTIME_BIND_ADDR=127.0.0.1behind a same-host proxy where you can. KASM_RUNTIME_OBSERVE_INPUTrecords keystrokes into the trace and forces the token requirement on.- The messaging token is meant for a sidebar. It cannot call tools, the DevTools proxy, the shell or file transfer, and cannot create requests or acknowledge delivery.
- There is one session token per session and no per-method scopes. A holder can call every method.
KASM_RUNTIME_MCP_LOCALHOST_PROTECTION(DNS-rebinding guard on/mcp) is off by default because Kasm’s proxy never sends a localhost Host header. Turn it on only when/mcpis served directly to a browser on the same machine.- Fixed listener limits: 10 s to send request headers, 2 min idle keep-alive, 8 MiB per
/mcpor/v1/call/request body.
Rights of a token holder
Section titled “Rights of a token holder”An outside caller is treated as an agent with its own reasoning, so the MCP and HTTP methods are broad:
shellruns a command line to completion and returns its output.launchandproc.spawnstart processes;proc.killstops them.input.clickclicks raw pixel coordinates;input.typeanddom.filltype literal text the caller supplies.dom.queryanddom.clicktake a CSS selector;dom.waitevaluates a JavaScript expression the caller writes;dom.navigategoes to any URL.- With
KASM_ENABLE_CDP,/cdp/gives the full DevTools protocol, which includes running script in the page and reading its cookies and storage.
Each call is recorded as a step in the report with backend rpc. Holding the session token is equivalent to a shell as the session user. The full list is on MCP methods.
A scenario-provided value referenced with ref is resolved inside the session and never returned to the caller, so a caller can type a credential it cannot read.
Browser debugging stays on the machine
Section titled “Browser debugging stays on the machine”The runtime’s own DevTools connection (cdp: true scenarios, the dom.* methods, and the /cdp/ proxy) goes to KASM_RUNTIME_CDP_ENDPOINT, default http://127.0.0.1:9222. The runtime refuses to start with an endpoint that is not loopback (127.x, ::1, localhost) unless KASM_RUNTIME_CDP_ALLOW_REMOTE=true. It also:
- refuses a discovery response that redirects;
- refuses a debug target the browser advertises on a different host from the endpoint;
- refuses a WebSocket handshake that redirects away from that target.
The last two checks still apply with KASM_RUNTIME_CDP_ALLOW_REMOTE set.
Limits: this controls where the runtime connects for DevTools. It does not stop another process in the session from connecting to the browser’s debugging port, and it does not restrict any other outbound connection.
File transfer: home and /tmp only
Section titled “File transfer: home and /tmp only”The file methods (file.get, directory.get) and streaming routes (/v1/files/, /v1/dirs/) reach two roots: the session user’s home directory and /tmp. A path outside them is refused. They are offered to outside callers in mcp mode, never to the runtime’s own loop.
How it is enforced:
- Each root is opened once as a root handle, and every open, create and rename goes through it. That refuses
..climbing out, absolute components, and symlinks pointing outside the root, including one swapped in between a check and the open. - Reads accept only a regular file, checked after the open, so a FIFO or device node at the path is refused.
- A write goes to a temporary file first, then is linked into place without replacing an existing file, or renamed over it with
overwrite. Setuid, setgid and sticky bits are never set. - Uploaded zip archives are validated whole before anything is written: relative clean names only, regular files and directories only, at most 10,000 entries, and the declared and actually decompressed sizes capped by
KASM_RUNTIME_EXTRACT_MAX_BYTES(default 1 GiB). One upload is capped byKASM_RUNTIME_UPLOAD_MAX_BYTES(default 1 GiB). At most four transfers run at once, and one idle for 60 s is cut off.
Limits:
- The roots stop a caller’s path from leaving them. They do not isolate a hard link already inside a root that points elsewhere, a bind mount under a root, or anything the session user’s filesystem already exposes there.
/tmpis writable by every user in the container.- The roots bound the file methods only. The
shellmethod can move files anywhere the session user can write.