jitsi / jitsi-meet

Jitsi Meet - Secure, Simple and Scalable Video Conferences that you use as a standalone app or embed in your web application.
https://jitsi.org/meet
Apache License 2.0
23.27k stars 6.76k forks source link

Support fetching JWT keys in JWKS format #15182

Open micolous opened 1 month ago

micolous commented 1 month ago

What problem are you trying to solve?

I'm trying to authenticate users with a JWT, signed by an identity provider which supports distributing public keys in JWKS format (RFC 7517 section 5).

Jitsi Meet currently accepts multiple methods for JWT verification, and currently has an asap_key_server parameter. That expects a URL base path, where keys can be looked up by fetching asap_key_server + "/" + sha256(kid) + ".pem", and it expects all keys to be in PEM format.

The ASAP protocol (Atlassian S2S Authentication Protcool) spec actually defines key discovery slightly differently: it expects keys to be referenced as asap_key_server + "/" + kid, but also served in PEM format.

What solution would you like to see?

Jitsi Meet should be able to accept a JWKS URL to validate keys. This is a standardised format, and already implemented by many identity providers as part of OIDC.

One advantage of JWKS is that it's easier to automatically rotate and expire keys without having to track every key individually:

  1. User authenticates with a JWT (which uses a KID which may or may not be cached by Jitsi Meet).
  2. Jitsi Meet checks an internal rate limit (or HTTP expiry headers) for whether it should fetch the JWKS again. If it's rate limited, then skip step 3 (re-fetching).
  3. Jitsi Meet fetches a JWKS from the identity provider. On success, it replaces its entire key cache with the new JWKS, revoking all old keys in the process.
  4. Jitsi Meet checks against the cached list, and allows / rejects authentication.

The ASAP spec defines that a client should follow HTTP caching rules for determining key lifetimes, but Jitsi Meet's plugin doesn't seem to implement that – keys are only ever added, and are only flushed on Prosody restart.

Is there an alternative?

Every identity provider implements an endpoint to support the Jitsi-specific version of Atlassian's key format; and is unable to expire old keys in the process.

damencho commented 2 weeks ago

Most of the stuff is already implemented, instead of using asap_key_server you can use cache_keys_url which supports using firebase tokens with jitsi-meet (https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com). https://github.com/jitsi/jitsi-meet/blob/1a3dd699b7746a0d1f9063d537c9577ac58b64fc/resources/prosody-plugins/token/util.lib.lua#L143

The caching control and everything is already implemented. https://github.com/jitsi/jitsi-meet/blob/1a3dd699b7746a0d1f9063d537c9577ac58b64fc/resources/prosody-plugins/token/util.lib.lua#L165

The missing part is implementing the jwks part and extracting the public key from there and using it instead of the existing extraction from the certificates from the link above.

So most of the parts are there, the rest can be done behind a flag. Any PRs are welcome.