Skip to content

Per-request short-lived RTSP credentials for live stream URLs #507

Description

@badbread

Follow-up to #506, deliberately parked.

Today. GET /cameras/:id/streams returns RTSP URLs with the server's single
global go2rtc restreamer username/password embedded in the authority
(rtsp://user:pass@host:18554/<name>). That credential pair is server-wide,
covers every stream go2rtc serves, and does not expire. #506 narrows who can
ask for it (a full login session only, no scoped media token), which is the
right minimum for v0.2.0, but the credential handed out is still broader and
more durable than the request that earned it.

The fuller fix. Mint a short-lived, per-request RTSP credential scoped to the
one stream the caller asked for, so the response body carries nothing durable and
the "what you get back matches what you proved" property holds structurally
rather than by careful endpoint-by-endpoint review.

Why it is not in the v0.2.0 change. It is a real design task, not an
extractor swap:

  • go2rtc's auth model needs investigating — whether per-stream or ephemeral
    credentials can be expressed at all without Crumb hand-managing
    go2rtc.yaml, which the reconcile loop owns (see AGENTS.md, "go2rtc streams
    are managed at runtime").
  • Credential lifetime has to outlive a long-running live view, or the desktop
    and mobile walls drop streams mid-session. That likely means a renewal path in
    three clients, not just a server change.
  • It touches the live-view path on every client, so it wants its own testing
    pass rather than riding along with a hardening PR.

Revisit triggers. Any of: go2rtc gains a usable per-stream or token auth
mechanism; Crumb grows a deployment mode where the RTSP endpoint is reachable
beyond the LAN; or another endpoint is found returning a credential broader than
its caller's proof, making the one-off extractor gate feel like the wrong shape.

Rationale and the accepted trade-off are recorded in docs/DECISIONS.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiBackend HTTP API (services/api)deferredValid work, parked/backlog until its trigger firesenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions