Skip to content

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_KEY is 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_ORIGINS is 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.

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.env endpoint 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.