Skip to content

Use scoped tokens to load <audio> urls instead of JWT

Agate requested to merge 1108-stream-token into develop

Part of #1108 (closed)

Rationale

We sometimes need to embed a token in the <audio src=""> URL, as we cannot override the Authorization header there (the browser handles the request for us). As a workaround, we supported providing the jwt param in the querysting, which worked great but wasn't really great in terms of security: if you share the download URL, or shared some browser logs in a chat, everyone could access your account.

This proposal mitigates this by:

  1. Allowing the generation of scoped tokens (tokens with a restricted set of capabilites) on server side
  2. Extend the JSON payload returned by /api/v1/users/me to include a new property, "tokens": {"listen": "<token>"}
  3. Using this token in the querystring instead of the JWT token
  4. Expiring scoped tokens after 3 days

The listen token can only be used to access the /api/v1/listen endpoint, meaning in the worst case scenario, if a token is leaked, someone will be able to listen to some tracks on behalf of you (assuming they also know the corresponding track and upload uuid) for a period of 3 days.

If a user changes their password (which triggers an update of user.secret_key), all their existing tokens are invalidated.

In the UI, we call /users/me every few hours to ensure we always have a valid token (and refresh the user profile, as well).

I plan to implement something similar for websockets, by adding a new oauth scope for websockets, and include a new token for this scope in the tokens returned by /users/me.

Note that this change is fully backward compatible (nothing was removed on the API regarding JWT).

Edited by Agate

Merge request reports