Access and sharing¶
Who this is for: hosters (sysadmins).
This page explains who can reach each service, how a producer proves they are allowed in, and how to hand out editor and audience links safely. It applies to both supported deployments: Deploy with Docker Compose and Deploy with Co-op Cloud. Access control rests on the service access token for the speech service, the room read/write tokens for the relay, and optional HTTP Basic Auth. If a word is new, see the glossary.
Published over HTTPS¶
In both deployments an edge router publishes the services over HTTPS: Traefik in the Compose stack, and Co-op Cloud's own Traefik in the recipe. Each service is reached by hostname, and the router terminates TLS, so tokens and captions are never sent in the clear.
| Service | Public address | Purpose |
|---|---|---|
Speech service (caption-local) |
https://caption.local.example.org |
Recognition and the capture page |
| Relay | wss://relay.example.org |
WebSocket caption forwarding |
| Web UI | https://ui.example.org |
Editor and audience overlays |
Behind the router, the application ports bind to loopback on the host. That is an internal detail of the deployment, not an access method: users always connect through the HTTPS hostnames above. See Configuration for setting the hostnames.
Never publish the raw speech-service port
The speech service is designed to sit behind the TLS router. Do not bind
caption-local to 0.0.0.0 or expose its port directly to the internet.
Public traffic belongs behind the edge router described in
Deploy with Docker Compose or
Deploy with Co-op Cloud.
The service access token¶
When no token is set, anything that can reach the speech service may use its API. That is fine for one trusted operator, but when several trusted producers share a deployment, set a service access token so the API requires proof.
For the Compose stack, create secrets/caption-local.env (the secrets/
directory is git-ignored) with the token and the exact origins allowed to call the
service:
CAPTION_API_KEY=<at least 24 ASCII characters, no whitespace>
CAPTION_ALLOWED_ORIGINS=https://ui.example.com,https://caption.local.example.com
The Co-op Cloud recipe carries the same two values in its app configuration; see Deploy with Co-op Cloud.
CAPTION_API_KEYis a local service token, not a Google, Gemini or OpenAI account key. Use a random value of at least 24 ASCII characters with no whitespace.- When the token is set, every API route requires an
Authorization: Bearer <token>header. CAPTION_ALLOWED_ORIGINSis required together with the token, and must list the exact HTTPS origins that may call the service.- The token gates health, model listing, inference and session deletion. The static UI and capture page stay loadable so users can enter it.
- The capture page keeps the token in tab memory only; it is cleared on reload and is never forwarded to the relay.
- To rotate it, restart the speech service with a new token. Save any pending captions first, because a restart loses in-memory retry caches.
This shared token is access control for trusted producers: it does not provide individual accounts, per-user quotas, tenant separation or TLS, and it does not turn the service into a public endpoint. The full setting list is in Configuration.
Optional HTTP Basic Auth¶
Either deployment can add an extra lock in front of the pages: HTTP Basic Auth, a username-and-password prompt served by the router. In the Compose stack it is an opt-in overlay (see Deploy with Docker Compose); in the Co-op Cloud recipe it is part of the app configuration. Basic Auth protects the whole site, while the service access token and the room tokens still gate the API and the relay.
Sharing capture, editor and overlay links¶
Caption sharing uses two rooms on the relay: source holds the raw captions, and
output holds the reviewed captions. Each room has a read and a write room
token. See Relay and rooms for the room model.
The capture page builds ready-made links once secrets/relay-tokens.env is
configured (see Configuration):
| Link | Carries | Give it to |
|---|---|---|
| Open caption editor | Source read token and output write token | A producer who reviews captions |
| Open audience overlay | Output read token only | The audience or OBS/streaming software |
| Open source overlay | Source read token only | A monitor that bypasses review |
A safe way to share them:
- Send the audience overlay link, which carries only a viewing token. It cannot change captions.
- Send the editor link only to the producer you trust to edit and publish. It can write to the audience room.
- Treat the source overlay as a private monitor: it shows unedited speech.
- Hand out room tokens privately. Anyone holding a write token can publish to that room, and anyone holding a read token can read it.
- The
relay-tokens.envendpoint is served to anyone holding the service access token, so leave the output write token out of that file if capture operators should not be able to publish to the audience room without going through the editor.
Origins: the relay's other gate¶
The relay rejects any WebSocket upgrade whose browser origin is not listed in its
private JSON origins. The capture page and the overlays/editor usually live on
different hosts, so list every exact origin (scheme included, no trailing slash).
A missing capture origin makes publishing fail with HTTP 403 and the overlay
appear empty. See Relay and rooms for the
configuration file and how to recreate the relay after editing it.
Tip
Set the service access token, the relay origins and any Basic Auth before an event, and test each link you plan to hand out. Rotate tokens between events if the links were shared widely.