From a9161410fda9b73c89de3348628c8cd4e0f3a3fb Mon Sep 17 00:00:00 2001 From: Seungmin Kim <8457324+ehfd@users.noreply.github.com> Date: Tue, 29 Sep 2026 01:34:45 +0900 Subject: [PATCH] docs(selkies): Document the session token in the fragment and the /api/tokens endpoint Selkies after 2.0.0 takes the session token from the URL fragment as well as the query, and offers a fragment token on the data WebSocket as the subprotocol selkies.token. beside selkies, so it never reaches a request line. Selkies 2.0.0 already serves the token table on its own port at /api/tokens and has no 8083 control port, and the v2 images' Nginx hands Selkies everything under api/ through one location, where the pages still had the websocket and files locations of the v1 images. --- docs/selkies/components/sealskin.md | 2 +- docs/selkies/components/selkies.md | 5 ++--- docs/selkies/developer-guide/architecture.md | 2 +- docs/selkies/developer-guide/baseimage-internals.md | 6 ++---- docs/selkies/developer-guide/protocol.md | 4 ++-- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/selkies/components/sealskin.md b/docs/selkies/components/sealskin.md index d48e26f4..3b6eb701 100644 --- a/docs/selkies/components/sealskin.md +++ b/docs/selkies/components/sealskin.md @@ -48,7 +48,7 @@ GPU allocation is automatic: the server detects render nodes and drivers at star ## Features beyond launching -- **Collaboration rooms:** launch a session in room mode and invite participants with links, full control, read only, or gamepad player slots, with A/V chat signalling and up to four physical gamepads passed through. Built on the Selkies token control plane (port 8083 inside the container). +- **Collaboration rooms:** launch a session in room mode and invite participants with links, full control, read only, or gamepad player slots, with A/V chat signalling and up to four physical gamepads passed through. Built on the Selkies secure mode token API (`/api/tokens`, behind the container's Nginx). - **File manager:** browse, upload, and download files in your server side homes from the extension, with chunked transfers for large files. - **Public shares:** password protectable, expiring public download links for files in your storage. - **App Lab (meta apps):** launch a base app in customize mode, install software and tweak settings interactively, then commit the home directory as a golden template. New "meta apps" launch from copies of that template, no Docker knowledge required. diff --git a/docs/selkies/components/selkies.md b/docs/selkies/components/selkies.md index f152e9b8..2da7e64f 100644 --- a/docs/selkies/components/selkies.md +++ b/docs/selkies/components/selkies.md @@ -15,7 +15,7 @@ Selkies is the heart of the platform: a ground up, web native remote desktop pro - **Clipboard**: bidirectional sync via `wl-clipboard` on Wayland or `xclip` on X11, with optional binary (image) clipboard support and chunked transfer for large payloads. - **Files**: receives chunked uploads over the socket into the session; downloads are served by the container's Nginx file index. - **Settings and stats**: pushes the sanitized settings schema to the client (this is what builds the sidebar UI, including which controls are locked), and streams CPU, GPU, memory, and network stats. -- **Sharing and roles**: manages primary, collaborator, view only, and player 2 to 4 roles, either via URL fragments (`#shared`, `#collab`, `#player2`) or, in secure deployments, via a token control plane on an internal port (`POST /tokens` authorized by `SELKIES_MASTER_TOKEN`), which is what [SealSkin](sealskin.md) uses for its collaboration rooms. +- **Sharing and roles**: manages primary, collaborator, view only, and player 2 to 4 roles, either via URL fragments (`#shared`, `#collab`, `#player2`) or, in secure deployments, via session tokens registered through the token API (`POST /api/tokens` authorized by `SELKIES_MASTER_TOKEN`), which is what [SealSkin](sealskin.md) uses for its collaboration rooms. Configuration is uniform: every setting is simultaneously a CLI flag (`--framerate`) and an environment variable (`SELKIES_FRAMERATE`), with the value syntax (ranges, enums, `|locked`) described in the [Configuration Reference](../user-guide/configuration.md). The protocol itself is documented in [The Streaming Protocol](../developer-guide/protocol.md). @@ -40,8 +40,7 @@ Both are preloaded automatically in the baseimages, and `NO_GAMEPAD=true` turns | Port | What | | --- | --- | -| 8082 | The Selkies server (`SELKIES_PORT`, upstream default is 8080, the baseimages set 8082 via `CUSTOM_WS_PORT`). Nginx proxies everything under `/api` to it: the data WebSocket at `/api/websockets`, WebRTC signaling at `/api/webrtc/signaling`, the transport switch, and the file browser at `/api/files/` | -| 8083 | Token control plane for secure sharing mode, never expose it | +| 8082 | The Selkies server (`SELKIES_PORT`, upstream default is 8080, the baseimages set 8082 via `CUSTOM_WS_PORT`). Nginx proxies everything under `/api` to it: the data WebSocket at `/api/websockets`, WebRTC signaling at `/api/webrtc/signaling`, the transport switch, the secure mode token API at `/api/tokens` (master token only), and the file browser at `/api/files/` | | 3000 / 3001 | Nginx HTTP and HTTPS in front of everything ([baseimage](baseimages.md) territory) | ## Relationship to the rest of the stack diff --git a/docs/selkies/developer-guide/architecture.md b/docs/selkies/developer-guide/architecture.md index 827785d4..f98a4b94 100644 --- a/docs/selkies/developer-guide/architecture.md +++ b/docs/selkies/developer-guide/architecture.md @@ -69,7 +69,7 @@ Nginx inside the container is the single front door: it serves the static client ## Sharing and multi user -One session, many sockets. Every connected client gets the same broadcast frames; roles (primary, collab, view only, player N) gate which input messages are honored. In secure mode (used by SealSkin), access requires per user tokens registered through a control plane endpoint on an internal port, and roles can be re assigned live, this is what powers collaboration rooms with granular permissions. +One session, many sockets. Every connected client gets the same broadcast frames; roles (primary, collab, view only, player N) gate which input messages are honored. In secure mode (used by SealSkin), access requires per user tokens registered through the token API (`POST /api/tokens`, gated by the master token), and roles can be re assigned live, this is what powers collaboration rooms with granular permissions. ## Where the orchestration layer plugs in diff --git a/docs/selkies/developer-guide/baseimage-internals.md b/docs/selkies/developer-guide/baseimage-internals.md index 307b743f..de2d5425 100644 --- a/docs/selkies/developer-guide/baseimage-internals.md +++ b/docs/selkies/developer-guide/baseimage-internals.md @@ -68,12 +68,11 @@ One config, two identical server blocks (HTTP 3000, HTTPS 3001): | Location | Purpose | | --- | --- | | `SUBFOLDER` (default `/`) | The web client static files from `/usr/share/selkies/web/` | -| `SUBFOLDERwebsocket` | Proxy to the Selkies data WebSocket on 127.0.0.1:8082 | -| `SUBFOLDERfiles` | fancyindex download listing of `FILE_MANAGER_PATH` (default `/config/Desktop`), removed entirely when downloads are disabled or `HARDEN_DESKTOP` is on | +| `SUBFOLDERapi` | Proxy to the Selkies server on 127.0.0.1:8082: the data WebSocket, WebRTC signaling, the secure mode token API, and the file browser at `api/files/`, refused when `SELKIES_FILE_TRANSFERS` leaves out downloads (`HARDEN_DESKTOP` empties it unless it is set) | | `SUBFOLDERpelorus/` | Proxy to the Pelorus API on 127.0.0.1:5100 | | `/devmode` | Proxy to a Vite dev server, see [Development Environment](development.md) | -All proxy locations use hour long timeouts, no buffering, and a 10MB body cap. Because substitution is plain `sed`, exotic characters in `PASSWORD` or `SUBFOLDER` can break the config, keep them simple. +All proxy locations use hour long timeouts and no buffering; `api` passes request bodies of any size, unbuffered, and the others cap them at 10MB. Because substitution is plain `sed`, exotic characters in `PASSWORD` or `SUBFOLDER` can break the config, keep them simple. ## Internal port map @@ -81,7 +80,6 @@ All proxy locations use hour long timeouts, no buffering, and a 10MB body cap. B | --- | --- | --- | | 3000, 3001 | Nginx | Published, everything user facing | | 8082 | Selkies WebSocket | localhost only, via Nginx | -| 8083 | Selkies token control plane | localhost only, orchestrators call it, never expose | | 5100 | Pelorus API | localhost only, via Nginx at `/pelorus/` | | 5000 | pixelflux Computer Use API | localhost only | | 5173 | Vite dev server | localhost only, via `/devmode` | diff --git a/docs/selkies/developer-guide/protocol.md b/docs/selkies/developer-guide/protocol.md index 2d2831dd..5adec685 100644 --- a/docs/selkies/developer-guide/protocol.md +++ b/docs/selkies/developer-guide/protocol.md @@ -4,10 +4,10 @@ The wire protocol between the Selkies server and the web client, for anyone impl ## Connection and roles -The client connects to `wss://host/websocket`. Role assignment happens one of two ways: +The client connects to `wss://host/api/websockets`. Role assignment happens one of two ways: - **Fragment mode** (default): the URL fragment the page was opened with decides the role, `#shared` (view only), `#collab` (full control), `#player2` through `#player4` (gamepad slot only), `#display2-right` and friends (second monitor surface). No fragment means primary. -- **Token mode** (when the server was started with `SELKIES_MASTER_TOKEN`): the client must present `?token=` in the WebSocket URL. Tokens and their roles are registered by the orchestrator via `POST /tokens` on the internal control port with the master token as a bearer credential. Close codes: `4001` invalid token, `4002` revoked, `4029` reconnecting too fast. +- **Token mode** (when the server was started with `SELKIES_MASTER_TOKEN`): the page is opened with the session token in the fragment, `#token=` (after a role or display fragment: `#display2-right&token=`), or in the query, `?token=`. A fragment token never reaches a request line: the client offers it on the WebSocket as the subprotocol `selkies.token.` beside `selkies`, which the server selects, while a query token rides the WebSocket URL as `?token=`. Tokens and their roles are registered by the orchestrator via `POST /api/tokens` with the master token as a bearer credential (`Authorization`, or `Selkies-Authorization` beside a Basic login). Close codes: `4001` invalid token, `4002` revoked, `4029` reconnecting too fast. On success the server sends `MODE websockets`, an auth confirmation with the assigned role, and a `server_settings` JSON message containing every tunable setting with its value, allowed range or enum, and locked flag, this single message is what renders the sidebar UI, which is why locking a setting server side removes the control everywhere.