Skip to content
Draft, pre-release documentation

Kasm Session Runtime takes its run contract from the environment: which app, which model endpoint, where the output goes, how long the run may take, and how it can be reached. They are set by whoever launches the run, whether an orchestrator, a CI job, a Kasm workspace’s environment settings or a person at a shell.

The runtime’s own variables start with KASM_RUNTIME_. The exceptions are KASM_SESSION_RUNTIME_PORT, KASM_ENABLE_CDP and DISPLAY.

  • Booleans take these spellings: 1, t, T, TRUE, true, True, and 0, f, F, FALSE, false, False. Anything else logs a warning and the variable is treated as unset.
  • An empty variable counts as unset, except for the list variables noted below, where setting a variable to nothing clears the list.
  • Some bad values stop the run before it starts; the rows say which. Every other bad value logs a warning and keeps the default. KASM_RUNTIME_CONFIG_STRICT=true makes those warnings fatal too.
Variable Default What it does When to change it
KASM_RUNTIME_APP required for run Names the app under test. Fills in the scenario’s app, window and process when the scenario leaves them out, and names the report. Under mcp it is optional and defaults to session Always, for run and the no-argument invocation
KASM_RUNTIME_SCENARIO_B64 empty The scenario YAML, base64-encoded, for the no-argument invocation. Empty means the default scenario: launch, settle, one observation, verdict, no steps. Under mcp it only supplies declared names. run ignores it When the orchestrator cannot mount a scenario file
KASM_RUNTIME_OUT /testbench/out The directory the report, trace, screenshots, log tails and DONE are written to. Must be writable When the host mounts output somewhere else
KASM_RUNTIME_BASELINE /testbench/baseline A read-only directory of known-good screenshots (good-*.png or good-*.jpg). It may be missing; the run then saves a candidate for a person to promote When baselines live elsewhere
KASM_RUNTIME_DEADLINE_S 600 The run’s time limit in seconds. The last timing.lifecycle.wrap_up_reserve_s (30 by default) is kept for diagnosis and the report. Under run it bounds all the scenario files together. Under mcp there is no limit unless you set this. Not a positive integer: fatal Raise it for long installs or remediation loops, lower it to fail fast in CI, set it under mcp for a maximum server lifetime
DISPLAY :1 The X display to capture from and inject into Only when the session’s display is not :1

A model is optional. With KASM_RUNTIME_VISION_ENDPOINT empty the runtime runs in deterministic-only mode: the window and process probes own the verdict, screenshots are still taken, and a step that needs visual judgement is recorded as not judged. Scripted steps, cdp_* browser steps, postconditions other than screen, plans, and an outside agent driving the session over MCP all work without one. A goal: scenario, click_grounded, and the model-backed MCP methods need one. See When you need a model.

The same endpoint is used for judging screenshots, for locating things on screen and for the runtime’s own agent loop. Any OpenAI-compatible chat-completions server works, local or hosted.

Variable Default What it does When to change it
KASM_RUNTIME_VISION_ENDPOINT empty Base URL of an OpenAI-compatible server, for example http://host:8001/v1. Empty means deterministic-only mode Whenever runs should judge screenshots, ground clicks or pursue a goal
KASM_RUNTIME_VISION_MODEL qwen3-vl-4b The model name sent with each request. It implies nothing about image shape or answer format When the server hosts another model
KASM_RUNTIME_VISION_API_KEY empty Sent as Authorization: Bearer <key>. Never logged; redacted from every report and trace Only for a hosted API that needs a key
KASM_RUNTIME_VISION_CAPTURE_GEOMETRY native The shape of the screenshot sent to the model: native sends the session’s pixels as captured, square-padded centres them on a black square. Any other value: fatal When changing model family. See Vision models
KASM_RUNTIME_VISION_ANSWER_CONVENTION point What the model is asked to return when locating something: a point or a box2d bounding box. Any other value: fatal Same as above
KASM_RUNTIME_VISION_GROUNDING_SCALE 1000 The size of the normalised grid the model answers in, on each axis: coordinates run from 0 to this number. A wrong value produces no error. The clicks land in the wrong place instead. Not a positive integer: fatal Only for a model family that grounds in another range. Check the model card

The three vision-format settings are independent of the model name, so any model can use any combination.

Variable Default What it does When to change it
KASM_RUNTIME_CDP_ENDPOINT http://127.0.0.1:9222 The browser’s Chrome DevTools Protocol HTTP endpoint, used by scenarios with cdp: true. Must be a loopback address unless the next variable is set; otherwise fatal Only when the browser listens on another port
KASM_RUNTIME_CDP_ALLOW_REMOTE false Permits a DevTools endpoint that is not on the loopback interface. The runtime still refuses redirects and targets advertised on a different host Only when deliberately driving a browser in another container
Variable Default What it does When to change it
KASM_RUNTIME_CONFIG_FILE empty Path to the operator file. A named file that cannot be read or decoded is fatal When a deployment tunes loop budgets, sampling, reply caps, timing or evidence sizes
KASM_RUNTIME_CONFIG_STRICT false Makes every configuration warning fatal, listing them all In CI, and wherever running on a default you did not choose is worse than not running

Every operator-file leaf also has its own override, listed below.

These apply to mcp and to the read-only observe routes the in-session sidebar watches.

Variable Default What it does When to change it
KASM_RUNTIME_SESSION_TOKEN empty Switches mcp from stdio to HTTP. Every acting request (MCP methods, the HTTP API, the DevTools proxy) must carry it in the X-Kasm-Runtime-Session-Token header. Redacted from every report and trace When a caller outside the container drives the session through Kasm’s port map
KASM_SESSION_RUNTIME_PORT 9434 The port the HTTP transport and the observe listener bind. Note the word order. Not a port number: warning, default kept Only when the workspace’s port map registers another port
KASM_RUNTIME_BIND_ADDR 0.0.0.0 The interface those listeners bind. Kasm’s port-map proxy needs the default 127.0.0.1 when a proxy on the same host fronts the runtime
KASM_RUNTIME_OBSERVE false Under run and the no-argument invocation, also serve GET /events (a live copy of trace.jsonl) and GET /artifacts/<file> (the output directory) for the run’s lifetime. mcp serves them whenever HTTP is on When the sidebar or another viewer should watch a scripted or agentic run
KASM_RUNTIME_OBSERVE_TOKEN_REQUIRED false Makes the observe routes and inbox reads require the session token or the inbox token, from the header or a token query parameter. With neither token set they refuse every request When the port is reachable from other containers or hosts
KASM_RUNTIME_OBSERVE_INPUT false Records every key and button event the session receives, from any source, as input trace events. Key events carry no key or text while the runtime itself is typing. Forces KASM_RUNTIME_OBSERVE_TOKEN_REQUIRED on When a test drives the session from outside and needs proof its input arrived
KASM_RUNTIME_INBOX_TOKEN empty The messaging credential for the human-in-the-loop routes: post messages and replies, upload attachments, and issue stop and finish_handoff. With neither this nor the session token set, there is no inbox. Redacted from every report and trace When a person or a backend should be able to talk to a running run. See People in the loop
KASM_ENABLE_CDP false Under mcp over HTTP, also mounts a raw DevTools proxy at /cdp/, gated by the session token. Ignored, with a log line, without a session token When a client such as Playwright needs the whole protocol
KASM_RUNTIME_MCP_LOCALHOST_PROTECTION false Makes /mcp require a localhost Host header, a guard against DNS rebinding. Kasm’s proxy never sends one, so turning this on behind the proxy rejects every request Only when serving /mcp directly to a browser on the same machine
KASM_RUNTIME_UPLOAD_MAX_BYTES 1G The most one upload may carry (PUT /v1/files/, or a PUT /v1/dirs/ archive as sent). A byte count or a K, M or G binary suffix. Not a positive size: fatal When larger files must go in
KASM_RUNTIME_EXTRACT_MAX_BYTES 1G The most one uploaded archive may extract to. Same format and rule When archives legitimately expand beyond it

The routes are in HTTP API, MCP methods and Sidebar protocol.

A scenario references a secret as $NAME in a type step, a cdp_fill value or a provides: value. The runtime expands it when the step runs. See Secrets and evidence.

Variable Default What it does When to change it
KASM_RUNTIME_SECRET_* none Any variable with this prefix is a secret: its value is replaced with [REDACTED] in the report, the trace and log output Name every credential a scenario types this way
KASM_RUNTIME_REDACT_ENV empty A comma-separated list of further variable names whose values are redacted the same way. Names only; the values are never logged When an orchestrator injects a credential under a name of its own

VNC_PW and VNC_VIEW_ONLY_PW, the vision API key, the session token and the inbox token are always redacted. Screenshots are not redacted: a secret visible on screen is in the image.

The runtime reads these when the session provides them. There is nothing to set.

Variable What the runtime does with it
KASM_ID Set by Kasm in every session. The DevTools proxy needs it to give out addresses that work from outside
DBUS_SESSION_BUS_ADDRESS Where the session bus is, for reaching applications over AT-SPI. The runtime can find the bus without it
XAUTHORITY Read by input observation

The image reads these before the viewer starts. The runtime binary ignores them.

Variable Default What it does
KASM_RUNTIME_SIDEBAR empty Selects a named sidebar installed beside the stock viewer. Empty or unknown means the stock viewer
KASM_SIDEBAR_ROOT /usr/share/kasmvnc-sidebars Where named sidebars are installed

See Replace the sidebar.

Each leaf of the operator file can be set on its own as KASM_RUNTIME_<BLOCK>_<FIELD>, upper-cased, with nested blocks joined the same way. The environment wins over the file, and the file over the default. Defaults and meanings are on the operator-file page. List leaves take comma-separated values, and setting one to nothing clears it.

Block Variables
runner KASM_RUNTIME_RUNNER_MAX_ITERATIONS, KASM_RUNTIME_RUNNER_MAX_RETRIES_PER_STEP, KASM_RUNTIME_RUNNER_MAX_TOOL_ERRORS, KASM_RUNTIME_RUNNER_REASONING_REPLAY, KASM_RUNTIME_RUNNER_RESCUE_ENABLED, KASM_RUNTIME_RUNNER_RESPOND, KASM_RUNTIME_RUNNER_MAX_HOLD_S, KASM_RUNTIME_RUNNER_ESCALATION_PAUSE_S, KASM_RUNTIME_RUNNER_GROUNDING_ATTEMPTS, KASM_RUNTIME_RUNNER_MAX_CONTEXT_RECOVERIES, KASM_RUNTIME_RUNNER_WAIT_TOOL_MAX_S, KASM_RUNTIME_RUNNER_ASK_HUMAN_BUDGET_S, KASM_RUNTIME_RUNNER_ASK_HUMAN_TIMEOUT_S
sampling KASM_RUNTIME_SAMPLING_TEMPERATURE, KASM_RUNTIME_SAMPLING_TOP_P, KASM_RUNTIME_SAMPLING_TOP_K, KASM_RUNTIME_SAMPLING_MIN_P
function_calling KASM_RUNTIME_FUNCTION_CALLING
context KASM_RUNTIME_CONTEXT_STRATEGY, KASM_RUNTIME_CONTEXT_BUDGET_TOKENS, KASM_RUNTIME_CONTEXT_KEEP_RECENT, KASM_RUNTIME_CONTEXT_PHASE_THRESHOLDS (list), KASM_RUNTIME_CONTEXT_WARN_AT (list), KASM_RUNTIME_CONTEXT_CHARS_PER_TOKEN, KASM_RUNTIME_CONTEXT_COMPACT_TRUNCATE_CHARS
max_tokens KASM_RUNTIME_MAX_TOKENS_JUDGE, KASM_RUNTIME_MAX_TOKENS_TOOLS
model KASM_RUNTIME_MODEL_TIMEOUT_S, KASM_RUNTIME_MODEL_ATTEMPTS, KASM_RUNTIME_MODEL_BACKOFF_S, KASM_RUNTIME_MODEL_DISABLE_AFTER
baseline KASM_RUNTIME_BASELINE_SIMILAR_MAX, KASM_RUNTIME_BASELINE_DRIFTED_MAX
findings KASM_RUNTIME_FINDINGS_UPDATER_MARKERS (list), KASM_RUNTIME_FINDINGS_FIRST_RUN_MARKERS (list), KASM_RUNTIME_FINDINGS_ERROR_DIALOG_MARKERS (list)
timing.input KASM_RUNTIME_TIMING_INPUT_ACTIVATE_SETTLE_MS, KASM_RUNTIME_TIMING_INPUT_KEYSTROKE_MS, KASM_RUNTIME_TIMING_INPUT_CLICK_MS, KASM_RUNTIME_TIMING_INPUT_CHORD_SETTLE_MS
timing.settle KASM_RUNTIME_TIMING_SETTLE_POLL_MS, KASM_RUNTIME_TIMING_SETTLE_MAX_CHANGED_FRACTION, KASM_RUNTIME_TIMING_SETTLE_MAX_S, KASM_RUNTIME_TIMING_SETTLE_POST_POLL_MS, KASM_RUNTIME_TIMING_SETTLE_KILL_SETTLE_MS
timing.cdp KASM_RUNTIME_TIMING_CDP_DIAL_S, KASM_RUNTIME_TIMING_CDP_CALL_S, KASM_RUNTIME_TIMING_CDP_RESOLVE_S, KASM_RUNTIME_TIMING_CDP_POLL_MS, KASM_RUNTIME_TIMING_CDP_DEFAULT_WAIT_S, KASM_RUNTIME_TIMING_CDP_READ_LIMIT_MIB
timing.atspi KASM_RUNTIME_TIMING_ATSPI_PROBE_BUDGET_S, KASM_RUNTIME_TIMING_ATSPI_PROBE_APP_WAIT_S, KASM_RUNTIME_TIMING_ATSPI_APP_WAIT_AFTER_ENABLE_S, KASM_RUNTIME_TIMING_ATSPI_ACTION_BUDGET_S, KASM_RUNTIME_TIMING_ATSPI_ACTION_APP_WAIT_S, KASM_RUNTIME_TIMING_ATSPI_MAX_NODES, KASM_RUNTIME_TIMING_ATSPI_MAX_DEPTH, KASM_RUNTIME_TIMING_ATSPI_MAX_ACTIONABLE
timing.lifecycle KASM_RUNTIME_TIMING_LIFECYCLE_RUN_BOOT_TIMEOUT_S, KASM_RUNTIME_TIMING_LIFECYCLE_MCP_BOOT_TIMEOUT_S, KASM_RUNTIME_TIMING_LIFECYCLE_WRAP_UP_RESERVE_S, KASM_RUNTIME_TIMING_LIFECYCLE_WINDOW_ONLY_GRACE_S, KASM_RUNTIME_TIMING_LIFECYCLE_CRASH_RECHECK_DWELL_S, KASM_RUNTIME_TIMING_LIFECYCLE_CRASH_RESCAN_S
evidence KASM_RUNTIME_EVIDENCE_SHELL_OUTPUT_CHARS, KASM_RUNTIME_EVIDENCE_TOOL_RESULT_CHARS, KASM_RUNTIME_EVIDENCE_PAGE_TEXT_CHARS, KASM_RUNTIME_EVIDENCE_PAGE_ELEMENTS, KASM_RUNTIME_EVIDENCE_ELEMENT_TEXT_CHARS, KASM_RUNTIME_EVIDENCE_LISTED_CANDIDATES, KASM_RUNTIME_EVIDENCE_ACCESSIBLE_NAME_CHARS, KASM_RUNTIME_EVIDENCE_LOG_TAIL_LINES, KASM_RUNTIME_EVIDENCE_REPORT_LOG_LINES, KASM_RUNTIME_EVIDENCE_JPEG_QUALITY, KASM_RUNTIME_EVIDENCE_TRACE_REPLAY_EVENTS, KASM_RUNTIME_EVIDENCE_INBOX_MESSAGE_CHARS, KASM_RUNTIME_EVIDENCE_INBOX_ATTACHMENT_BYTES, KASM_RUNTIME_EVIDENCE_INBOX_CONTEXT_CHARS, KASM_RUNTIME_EVIDENCE_INBOX_SUMMARY_CHARS, KASM_RUNTIME_EVIDENCE_INBOX_DRAIN_MAX
tools KASM_RUNTIME_TOOLS_DISABLED (list)

Every KASM_RUNTIME_<NAME> variable is also accepted as TESTBENCH_<NAME>, and TESTBENCH_SECRET_* is redacted like KASM_RUNTIME_SECRET_*. The modern name wins when both are set. KASM_SESSION_RUNTIME_PORT, KASM_ENABLE_CDP and DISPLAY have no legacy form.

Every legacy name a run used is listed in report.json under agent.legacy_env and called out in report.md.