Authorization¶
Sapsan protects stream playback and publishing. There are two mechanisms: static tokens in the config and external auth backends the server delegates decisions to.
How the token is passed¶
A token is accepted in two ways (the header takes priority):
- the
Authorization: Bearer <token>header; - the
?token=<token>URL parameter.
For HLS it is enough to open the master playlist with the token — Sapsan appends ?token= to every nested URL itself (variants, segments, parts, init).
Static tokens¶
auth:
play_tokens:
- viewer-secret-1
publish_tokens:
- publisher-secret-1
play_tokens— playback tokens;publish_tokens— publishing tokens.
A request without a valid token is denied. If the auth section exists but neither tokens nor backends matched, access is denied.
External auth backends¶
Decisions can be delegated to HTTP backends:
auth:
upstreams:
main:
url: http://backend.example.com/auth
timeout_ms: 3000
Sapsan makes a POST to the backend's url with a JSON body:
{
"kind": "play", // play or publish
"stream_name": "cam1",
"proto": "hls", // protocol: hls, dash, rtsp, m4f, ...
"user_agent": "Mozilla/5.0 ...", // may be absent
"token": "viewer-secret-1", // may be absent
"session_id": "..." // stable session identifier
}
The decision is made from the HTTP response status (the body is not parsed):
2xx— allow;401or403— deny (the denial is cached — an identical repeat request does not hit the backend);- any other status, unreachability, or exceeding
timeout_ms(default 1000 ms) marks the backend as down; - multiple backends are queried in parallel: one "allow" is enough; only denials → deny; all backends down → a "backend down" error (not a silent deny).
Sessions¶
A viewer session is identified by the quadruple: stream, kind (play/publish), IP, token — repeated requests from the same viewer do not spawn new sessions. Long-lived connections (RTSP, WebRTC) are periodically re-authorized: if the backend revokes access, the session closes. Session counters (opened, denied, authorized) are available in monitoring.
Admin API access¶
The Admin API is protected by a separate api_auth section — see Admin API.