Skip to content
Fuse
Esc
↑↓navigate↵open⌘Jpreview

Open a takeover shell

Opens the takeover holder’s shell in the guest. This is the environment attach stream (see attachEnvironment for the handshake, the query string and the fuse-attach/1 frames) with a recording on it. Only the Go SDK and the CLI (fuse hitl takeover) speak it.

Unlike plain attach it does not need the master token: it needs hitl:takeover, and the caller must be the takeover’s holder (the master token skips the holder check). Start the takeover first with POST /v1/environments/{vmId}?action=takeover.

Recorded. The first output frame is a banner saying the session is recorded and that credentials belong in a secret request, never typed into the shell. The guest’s output and window resizes are kept as an asciinema v2 cast; what the human types is not. When the stream closes the cast is sealed with TOKEN_ENCRYPTION_KEY (stored unencrypted, with a warning, when the orchestrator has none) and linked from a takeover_session audit row by recording_id. A cast stops growing at 8 MiB and is marked truncated; the shell keeps working.

GET/v1/interventions/{interventionId}/attach
Authorization
AuthorizationBearer token · headerrequired
`Authorization: Bearer <token>` — either the static master token (`ORCH_AUTH_TOKEN`) or a revocable API key issued via /v1/api-keys (API keys require Postgres; without a database only the master token is accepted). Master-only surfaces (exec, attach, API key management) refuse API keys with 403. An expired key is refused with 401 like an unknown one. A key minted with `scopes` reaches only the hitl routes (`/v1/interventions`, `/v1/hitl/*`, and POST /v1/api-keys to mint a narrower key). Any other route is 403 code `forbidden`, reason `env_scope`, except an `/v1/environments/{vmId}` route for an environment the key does not cover, which is 404 so the key cannot probe which environments exist. **Authentication can be disabled entirely.** When neither `ORCH_AUTH_TOKEN` nor an API key store (`DATABASE_URL`) is configured — the default local-development posture — the bearer middleware becomes a pass-through: every operation this document marks as secured is reachable with no credentials, requests carry no principal, and master-only surfaces therefore admit everyone. Never run that configuration on a reachable network; set `ORCH_REQUIRE_AUTH=true` to make the orchestrator refuse to start without a master token.
or
fuse_sessionAPI key · cookierequired
HttpOnly session cookie set by POST /login for browser callers. Consulted only when no Authorization header is present.
Path parameters
interventionIdstringrequired
A held takeover.
Query parameters
ttystringrequired
Must be `1` or `true`; a takeover shell is pty-only.
Allowed:1true
rowsinteger
Initial pty height. Also the cast's height.
min 1 · max 65535
colsinteger
Initial pty width. Also the cast's width.
min 1 · max 65535
cmdstring[]
The argv to run, one element per repeated `cmd`. Omit it for the guest's login shell.
Header parameters
Fuse-Actorstring
The person behind this request, as an opaque id (`user_42`, `alice@corp.com`, `slack:U0123`). Fuse records it on hitl interventions and the audit log and never checks it. Accepted on every authenticated route; it matters wherever an actor is recorded (raising, deciding, minting). At most 128 bytes, no control characters; a malformed value is 400. How the recorded actor is resolved: - key pinned to an actor: that actor (`source: pinned`). A different `Fuse-Actor` is 403 `forbidden`, reason `actor_mismatch`. - key with `hitl:act-as`: the header value (`source: asserted`, with the asserting key's id), else `key:<key_id>`. - any other key: `key:<key_id>` named after the key's label (`source: key`). Sending the header is 403 `forbidden`, reason `actor_not_allowed`, rather than silently dropped. - master token: the header value (`source: asserted`), else `master` (`source: key`). An asserted actor is only as true as the key holder's own auth.
max length 128
Fuse-Actor-Namestring
Optional display name for `Fuse-Actor`, at most 256 bytes. Sending it without `Fuse-Actor` is 400.
max length 256
Responses
101Upgrade accepted. The connection leaves HTTP and carries fuse-attach/1 frames until either end closes it.
400No `Upgrade: fuse-attach/1`, no `tty=1`, or the intervention is not a takeover.
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
403The key lacks `hitl:takeover` (`details.reason` `missing_scope`), or the caller is not the takeover's holder (code `forbidden`, no reason).
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
404Resource does not exist. Note the distinct code `route_not_found`, returned when the URL matches no registered route at all (wrong host, port, or path prefix) rather than a known route with a missing resource.
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
409The takeover is not held (never started, or already resolved).
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
500Unexpected server error.
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
501The operation is not supported by the backing provider (e.g. an exec or attach against an environment with no real guest).
errorobjectrequired
Show properties
codestringrequired
Stable machine-readable code. `route_not_found` (404) means the URL matches no route this server exposes — usually a wrong host, port, or path prefix — as opposed to `not_found`, where the route exists but the resource does not. `forbidden` is emitted by CIDR-allowlist rejections and by hitl access checks, which set `details.reason` (see the Forbidden response); master-only refusals (exec, attach, listing and revoking API keys) return 403 with code `unauthorized`.
Allowed:not_foundroute_not_foundconflictinvalid_argumentunauthorizedforbiddenunavailableinternalunimplementedlocked
messagestringrequired
Human-readable description.
detailsobject
Optional stable, non-sensitive metadata (e.g. ids, counts). Omitted when empty. A 403 `forbidden` from a hitl access check carries `reason` (`missing_scope`, `env_scope`, `self_approval`, `actor_required`, `actor_mismatch`, `actor_not_allowed`, `mint_escalation`, `hitl_denied`), plus `scope` for `missing_scope`, and `gate` and `intervention_id` for `hitl_denied`. A 423 `locked` carries `intervention_id` and `kind` (`takeover` or `stall`).
Request
curl -X GET "http://localhost:8080/v1/interventions/string/attach?tty=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
Response
Upgrade accepted. The connection leaves HTTP and carries fuse-attach/1 frames until either end closes it.