Oko/Docs

Operations

PTY relay

Authentication, operation, and Stado deployment for Oko terminal sharing.

Oko PTY Relay#

Persistent WebSocket relay for internet terminal sharing.

The relay is intentionally dumb: it authenticates each WebSocket, groups connections by session, and forwards bytes/messages between:

  • role=publisher: the Oko that owns the broker PTY
  • role=viewer: a remote Ghostty attach client
  • role=control: one-shot control messages such as resize or input from UI

It never starts, owns, or inspects Claude/Codex processes.

Run#

The relay starts only after Stado returns the token field of the item playing role oko-pty-relay. Stado resolves its own Skarbiec route and credential authority; the relay neither reads a route file nor supplies a separate Skarbiec consumer. The token remains in relay memory:

bash
deno run --allow-net --allow-env --allow-run --allow-read relay/pty-relay.ts

The read runs ~/.stado/bin/stado credentials get --role oko-pty-relay --field token with this process's HOME, PATH and TMPDIR, and no other inherited environment. A read it cannot finish stops the relay before it listens, exiting 1 with the relay token could not be read: <step>: <cause>:

StepCause it names
locating StadoHOME is not set
starting <stado> credentials get …why the program could not start
<stado> credentials get …exit status <n>: <stado's standard error>, field output has no line terminator, or it answered nothing

Stado prints the stored field followed by one newline. The relay removes only that newline, preserving every byte of a nonempty token's text, including leading or trailing whitespace; it does not parse JSON-shaped token text into a different value. An output without Stado's line terminator is refused, not treated as a token. tests/relay/token.rs exercises the missing-HOME and unstartable-Stado refusals through the shipped Deno entry point.

Production deployment must use TLS. Trusted Oko clients independently resolve the same relay item through the exact oko-pty-relay-client grant.

Stado-managed service#

The production relay is a long-lived service on a registered Stado host. Oko does not call a provider deployment API and does not select the backing cloud.

Before deployment, stage a target-local executable wrapper that starts relay/pty-relay.ts with Deno. The --from path is on the registered target; stado service deploy does not upload a local workstation path.

bash
stado service deploy oko-pty-relay \
  --host <registered-host> \
  --from /absolute/target/path/oko-pty-relay
stado service status oko-pty-relay

The managed unit asks its local Stado for the relay credential; neither launchd nor the service environment contains the bearer. Give clients only the Stado-managed TLS endpoint as non-secret configuration:

bash
export STADO_PTY_RELAY_URL=wss://<stado-managed-relay-endpoint>

Keep one managed relay instance for this service: session pairing is in process memory, so every publisher, viewer, and control socket for a session must reach that same instance.

Supabase remains useful for session discovery/presence. Terminal bytes do not flow through Supabase tables or Storage.

Migrated from src/content/docs/pty-relay.md