Repository navigation
feat: Add an option to send the OIDC ID token instead of the access token - #197
Conversation
…oken After an OIDC login the dashboard sent the access token to the backend as the bearer token. The Kubernetes API server, and an OIDC proxy such as kube-oidc-proxy in front of it, only verify signed JWTs. Some providers issue access tokens they cannot verify: NetIQ/SIAM, for instance, returns an encrypted JWT (JWE), so every request was refused with a 401 even though the login succeeded. The ID token is a signed JWT and is the token Kubernetes tooling such as kubelogin authenticates with. The new setting oidcTokenType chooses which token is sent: access_token, the default, so nothing changes for existing setups, or id_token. A single function picks the token for both the login callback and the silent token renewal. When id_token is set and the provider returns no ID token, the user is sent back to the login page with "Unauthorized". What needs to be set: Helm chart (dashboard): auth.oidc.tokenType: id_token Container environment: OIDC_TOKEN_TYPE=id_token Local development: VITE_OIDC_TOKEN_TYPE=id_token Set it when the access token returned by the provider is not a signed JWT, that is when ui-backend reports a token it cannot verify, or when the OIDC proxy logs auth_method none for a user who logged in successfully. The provider has to return an ID token, so the "openid" scope must be requested, which it is by default. The ID token lifetime should cover a session: token renewal is driven by the access token's expiry. The value is passed to the dashboard through the OIDC_TOKEN_TYPE variable of the runtime config (scripts/config.template.js and docker-entrypoint.sh). The dashboard Helm chart option is added in the helm-charts repository. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks for this, it matches what we ran into. We use Okta with only the org authorization server (no custom authorization servers). Its access tokens are meant for Okta's own APIs and can't be validated by the Kubernetes API server, but the ID token works fine, the same way kubelogin uses it. Without this option our only workaround was running Dex as a broker. Sending the ID token would let us drop that entirely. Happy to help test once it's released. |
|
Thanks @matthewgreenwaldagility I released dashboard helm chart v1.16.1 with this. let me know if you get a chance to test this and there are issues. Thank you! |
|
@gianlucam76 What was the design decision for dashboard that led to using |
|
@gianlucam76 I opened this issue: projectsveltos/ui-backend#189 |
|
Thank you so much @matthewgreenwaldagility. I was just reading that. Will work on it and will try to have something in the next few days. I might bug with some questions (if you use slack please fell free to join the projectsveltos channel). Regarding current implementation it came from an explicit request from a large company using sveltos. While they don't use kube-oidc-proxy i used it to come up with a scenario I can test against that was close to what they have. |
After an OIDC login the dashboard sent the access token to the backend as the bearer token. The Kubernetes API server, and an OIDC proxy such as kube-oidc-proxy in front of it, only verify signed JWTs. Some providers issue access tokens they cannot verify: NetIQ/SIAM, for instance, returns an encrypted JWT (JWE), so every request was refused with a 401 even though the login succeeded. The ID token is a signed JWT and is the token Kubernetes tooling such as kubelogin authenticates with.
The new setting oidcTokenType chooses which token is sent: access_token, the default, so nothing changes for existing setups, or id_token. A single function picks the token for both the login callback and the silent token renewal. When id_token is set and the provider returns no ID token, the user is sent back to the login page with "Unauthorized".
What needs to be set:
Helm chart (dashboard): auth.oidc.tokenType: id_token
Container environment: OIDC_TOKEN_TYPE=id_token
Local development: VITE_OIDC_TOKEN_TYPE=id_token
Set it when the access token returned by the provider is not a signed JWT, that is when ui-backend reports a token it cannot verify, or when the OIDC proxy logs auth_method none for a user who logged in successfully. The provider has to return an ID token, so the "openid" scope must be requested, which it is by default. The ID token lifetime should cover a session: token renewal is driven by the access token's expiry.
The value is passed to the dashboard through the OIDC_TOKEN_TYPE variable of the runtime config (scripts/config.template.js and docker-entrypoint.sh). The dashboard Helm chart option is added in the helm-charts repository.