Registered Servers

Registered Servers

Create, enroll, and operate persistent WebTTY servers.


A registered WebTTY server is the production form of WebTTY. It is a persistent server record attached to a project. The record keeps a stable server id, metadata, labels, access policy, recording policy, encryption policy, and enrollment state even when the remote process is offline.

Use registered servers when operators need to find the same machine later, when recordings matter, when live attach/control is required, or when workspace-managed encryption is part of the security model. A lightweight WebTTY tunnel is enough for temporary access; a registered server is the right object for an administered fleet.

A registered server separates durable product state from the live runtime connection. That boundary is the reason it can remain visible while the remote process is offline.

control plane database
  registered server record
  policy, labels, enrollment state, history
        |
        | authenticated enrollment from the runtime host
        v
remote host
  enrollment file + server identity
        |
        | outbound runtime connection
        v
engine
  online projection from tunnel state
  managed WebTTY protocol routing

The database owns durable product state. The engine owns live runtime state. A registered server can be offline and still be visible because the product object exists independently from the current tunnel connection.

Create the server record

A registered server record can be created from the Dashboard, from the CLI, or through the Control plane API. They all create the same durable product object. The Dashboard path is the product path for day-to-day administration because it can explain the policy choices, show enrollment commands, and keep the server visible while it is offline. The CLI path is the operator and automation path, and it is the easiest path to reproduce in documentation and tests.

In the Dashboard, create the server from the project WebTTY page. The form asks for the server name, optional description, labels, recording policy, encryption policy, and access policy. After creation, the operator receives the server id and an enrollment command for the remote host.

The Dashboard flow and CLI flow produce the same server record. The Dashboard is usually clearer for human administration; the CLI is easier to automate and to document precisely.

Dashboard
  Project -> WebTTY -> Create server
        |
        | name, labels, recording policy, encryption policy, access policy
        v
registered server record
        |
        | server id + enrollment command
        v
remote host enrollment

From the CLI, the shortest same-machine path creates the record and enrolls the local host immediately:

rstream webtty server create prod-shell \
  --recording-policy recorded \
  --encryption-policy disabled \
  --access-policy project_members \
  --enroll

That command creates the product object, writes the local enrollment, and prints a Run command.

For a split-machine workflow, create the record from a machine that can access the target project:

rstream webtty server create prod-shell \
  --recording-policy recorded \
  --encryption-policy disabled \
  --access-policy project_members

The split-machine command creates the product object and prints the server id, an Enroll command, and a Run command. The enrollment command is run from the host that will run WebTTY and uses the authenticated rstream context on that host.

The command returns the durable identifiers needed for enrollment and automation.

OutputPurpose
Server idStable identifier used by APIs and automation.
Enroll commandCommand that associates the runtime host with the server record.
Server nameHuman-facing name used by rstrm:// resolution.

Use --project-id <project-id> when the active CLI project is not the project that owns the server.

rstream webtty server create prod-shell \
  --project-id <project-id> \
  --description "Production shell access" \
  --label environment=prod \
  --label role=ops

Labels on the registered record are durable inventory metadata. They are useful for search, policy, and UI grouping. The running server can still add runtime labels later for local host information.

The important product invariant is the same regardless of entrypoint. The server record is created before the remote process starts using it. That is what separates a registered server from a lightweight WebTTY tunnel.

Enroll the remote machine

When the same machine creates and runs the server, prefer the one-command path:

rstream webtty server create prod-shell --enroll

That command creates the registered server and writes the local enrollment in the same operation.

For split-machine operation, run enrollment on the host that will run the WebTTY server:

rstream webtty server enroll <server-id>

Use the enrollment command printed by server create. The runtime host must be logged in with access to the project that owns the registered server. If the local context points to another project or workspace, enrollment fails before writing local state.

Enrollment writes a local enrollment file and a local WebTTY server identity:

~/.rstream/webtty/enrollments/<server-id>.yaml
~/.rstream/webtty/identities/<server-id>.identity.json

The enrollment file tells the server process which registered object it belongs to. The identity file contains private key material and must be readable only by the local account or service identity that runs WebTTY.

enrollment file
  project/server association, runtime target, server metadata
 
identity file
  local private key material for the WebTTY server

Do not copy an enrolled identity between unrelated hosts. If a machine is replaced, enroll the replacement host from an authenticated project context.

For service accounts or configuration management, write the enrollment file to an explicit path:

rstream webtty server enroll \
  <server-id> \
  --server-enrollment /etc/rstream/webtty/prod-shell.enrollment.yaml \
  --identity-file /var/lib/rstream/webtty/identities/prod-shell.identity.json

Start the registered server

The shortest command uses the server id:

rstream webtty server -v --server-id <server-id>

--server-id implies --rstream and loads the default enrollment file:

~/.rstream/webtty/enrollments/<server-id>.yaml

Use an explicit enrollment file when the process runs under a service account or when host configuration management owns the file location:

rstream webtty server -v --server-enrollment /etc/rstream/webtty/prod-shell.enrollment.yaml

Use a runtime config file when you want the service manager command to stay short and reviewable:

rstream webtty server -v --webtty-config /etc/rstream/webtty/prod-shell.yaml

The config file can reference either the server id or the enrollment file and can also carry runtime settings:

version: 1
server:
  serverEnrollment: /etc/rstream/webtty/prod-shell.enrollment.yaml
  transport: websocket
  executionMode: login
  labels:
    environment: prod
    region: eu-west

Do not put secrets in a shared runtime config. Keep private keys in identity files with strict local permissions or in the host secret manager.

The three start forms are equivalent in intent, but not in operational ownership:

Start formUse when
--server-id <id>An operator runs the server from the normal rstream home directory.
--server-enrollment <file>A service account uses an enrollment file managed outside the default home.
--webtty-config <file>A daemon keeps runtime options in one audited YAML file.

Default execution mode

Registered servers default to login execution mode. This makes registered WebTTY behave like a managed shell service, where the server can use the host login path and map the rstream caller or requested user into an operating-system user when the host supports it.

Lightweight WebTTY defaults to spawn, because it is usually started from an existing user session and spawns commands as a child of that process.

Override the registered default only when the host model requires it:

rstream webtty server -v --server-id <server-id> --execution-mode spawn
rstream webtty server -v --server-id <server-id> --execution-mode login --login-user deploy

Use --allow-client-user only when clients may request an operating-system user. That is a host security decision, not just a WebTTY convenience flag.

Recording policy

--recording-policy recorded enables managed recordings for sessions created through the registered WebTTY path. Recordings are stored as ordered events with stream type, timestamps, resize metadata, and terminal payloads. If E2E is disabled, payloads can be stored in plaintext according to policy. If E2E is active, payloads are stored encrypted.

--recording-policy private keeps the server registered but disables managed recordings. The server remains persistent, enrolled, searchable, and policy-controlled; it does not store session logs.

rstream webtty server create prod-private-shell \
  --recording-policy private \
  --encryption-policy disabled

Encryption policy

Registered servers support three encryption policies.

disabled means terminal payloads are protected by transport encryption but not by WebTTY payload encryption. This is the simplest managed path and is useful when server-side logs are expected to be readable by authorized operators without client-held decrypt material.

explicit_key means operators trust the WebTTY server key directly, similar in spirit to a known-host workflow. It can be used without Workspace Protection.

workspace_managed means terminal encryption is tied to Workspace Protection. Trusted browsers and trusted devices resolve the needed key material at runtime. The client does not need to copy or pin the server public key directly.

Workspace-managed servers require a trusted workspace device on the runtime host before enrollment. During enrollment, the CLI pins the public workspace keyset identity into the server enrollment from that trusted local device. The server never receives workspace private keys; it receives only the public trust material required to verify workspace-managed client proofs during terminal sessions.

The normal workspace-managed path is:

rstream login
rstream project use <project-endpoint>
rstream workspace device enroll --kind service --label prod-shell-host
rstream workspace device status
rstream webtty server create prod-shell \
  --recording-policy recorded \
  --encryption-policy workspace_managed \
  --enroll

If the machine later loses trusted-device state and is trusted again, refresh the local trust pins:

rstream webtty server trust <server-id>

server trust is a repair and rotation command. It is not a bypass for device trust, and it does not make an untrusted machine eligible to run a workspace-managed E2E server.

That pin lets the remote server verify workspace-managed WebTTY client proofs without receiving workspace private key material.

The detailed setup is covered in End-to-End Encryption.

Inventory and lifecycle

Registered servers can be listed even when no runtime tunnel is currently online:

rstream webtty server list
rstream webtty server list --status active
rstream webtty server list --q prod

Show one server when you need enrollment, policy, label, or status details:

rstream webtty server show <server-id>

Delete the registered object only when the server no longer belongs in product inventory:

rstream webtty server delete <server-id> --yes

Deleting the registered object does not clean up files on a remote host that already enrolled. Remove local enrollment and identity files through host configuration management when the machine is retired.

Online state

Registered server online state is derived from the associated live runtime tunnel and engine state. There is no separate WebTTY liveness object to operate. If the process is offline, the registered object remains visible and historical recordings remain available according to retention and permissions.

This separation is important. The database stores the durable server object and finished session records; the engine owns live runtime state.