gravitational / teleport

The easiest, and most secure way to access and protect all of your infrastructure.
https://goteleport.com
GNU Affero General Public License v3.0
16.98k stars 1.71k forks source link

App Access JWT tokens cannot be validated using `/.well-known/openid-configuration` #43306

Open pschisa opened 2 weeks ago

pschisa commented 2 weeks ago

The openid configuration document hosted at https://example.teleport.sh/.well-known/openid-configuration (per the standard) gives this URL as the jwks_uri: https://example.teleport.sh/.well-known/jwks-oidc

Our documentation states https://example.teleport.sh/.well-known/jwks.json is the correct endpoint for JWT token validation and this is the one that actually works.

This is a violation of the OpenID Connect Core specification. See Sections 3 and 4.2 of the specification here for details: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse

Based on internal discussions, this arises from having two different JWT CAs within Teleport.

Bug details:

strideynet commented 2 weeks ago

Just to clarify based on our discussion internally.

In the beginning, we had a single JWT CA that issued JWTs for Application Access. We exposed the public key for this via the /.well-known/jwks.json path. The JWTs were issued with a "iss" field of [CLUSTER_NAME].

We never published a OpenID configuration document, and from what I can tell, we never intended these tokens to be OIDC compliant.

Later, for the integration with AWS, we introduced a new JWT CA (. This would only be used for integrating with AWS, and was required to be OIDC compliant. We made a bit of a mistake here in also issuing these tokens with an "iss" field of [CLUSTER_NAME]. What we probably should've done is had an issuer field of "[CLUSTER_NAME]/aws-oidc" which would've yielded an OpenID config path of "/aws-oidc/.well-known/openid-configuration".

I think really - it's a case of expectations. We are non-compliant with the OIDC spec for the App Access JWTs, but, I don't think we were intending to be. Regardless, people clearly expect us to be compliant with the OIDC spec - and this allows the use of a bunch of libraries intended for use with OIDC IDTokens. I don't think it's unreasonable to expect that these JWTs would be OIDC IDTokens.

We probably have a few options forward:

  1. Migrate one of the issuers to use a subpath - or both. This'll be fairly involved and could break consumers.
  2. Do nothing - and explicitly document that the JWT CA does not issue OIDC compatible tokens.
  3. Deprecate the JWT CA and start issuing from the OIDC CA for App Access. We may need to add some claims fields into the IDTokens we issue from the OIDC CA for feature parity.
scottjreece commented 1 week ago

You might also be able to add the jwks.json keys to the jwks-oidc json listing (so all keys would be provided there together), and use the "kid" (key id) field in the JWT header to clarify which key was used to sign the JWTs. That may have other downsides, but it could be worth considering. I'm not sure if this goes against the specification or not.