Skip to content

Conversation

@thomaspurchas
Copy link

Kubernetes supports the use of OIDC tokens for user authentication by sending the OIDC ID Tokens as the bearer token in requests. So returning access forbidden errors because someone has a OIDC token that doesn't map to Kargo's internal role system doesn't mean they're not authorised to interact with the underlying Kargo CRDs.

By allowing people who have authenticated with an OIDC token to fall through to k8s bearerToken auth, it makes it possible for people to use the same OIDC issuer for both their k8s authentication, and Kargo authentication, then rely solely on k8s RBAC to manage authorisation for both the k8s cluster and Kargo, regardless of the interface the user chooses (Kargo UI/CLI, Kubectl).

Kubernetes supports the use of OIDC tokens for user authentication by
sending the OIDC ID Tokens as the bearer token in requests. So returning
access forbidden errors because someone has a OIDC token that doesn't
map to Kargo's internal role system doesn't mean they're not authorised
to interact with the underlying Kargo CRDs.

By allowing people who have authenticated with an OIDC token to fall
through to k8s bearerToken auth, it makes it possible for people to use
the same OIDC issuer for both their k8s authentication, and Kargo
authentication, then rely solely on k8s RBAC to manage authorisation for
both the k8s cluster and Kargo, regardless of the interface the user
chooses (Kargo UI/CLI, Kubectl).

Signed-off-by: Thomas Purchas <purchas@apple.com>
@thomaspurchas thomaspurchas requested a review from a team as a code owner May 22, 2025 15:13
@netlify
Copy link

netlify bot commented May 22, 2025

Deploy Preview for docs-kargo-io ready!

Name Link
🔨 Latest commit bd94fbb
🔍 Latest deploy log https://app.netlify.com/projects/docs-kargo-io/deploys/682f3f26b8e1790008d43f14
😎 Deploy Preview https://deploy-preview-4197.docs.kargo.io
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@krancour krancour self-assigned this May 22, 2025
@krancour krancour added the area/security Has security implications and needs to be handled with great caution label May 22, 2025
@krancour
Copy link
Member

The feature you're trying to implement already (mostly) exists.

If you were logging in via the Kargo CLI, there is a --kubeconfig option that will use whatever token is in your kubeconfig. (If it has a token, that is. This does not work when authentication is done using a client certificate.)

If our authentication filter cannot validate that the token it receives was issued by Kargo's IDP, it assumes it may have been issued by Kubernetes' IDP. It stashes that token in the request-bound user info object, and when it comes time to authorize an operation, literally three lines down from the change you're proposing, you will see where we do a self subject access review using that token.

I'm not really a front-end guy, but I'm fairly certain that the browser cannot read your kubeconfig, which unfortunately means that login via the UI has no analog to the CLI's --kubeconfig flag. For the UI to get a token would thus require Kargo to be registered as a client with the same IDP your cluster is using and execute the authorization code flow itself. The problem with this is the token that the IDP issues will have Kargo as the audience and if you use that to try to talk to the Kubernetes API server, Kubernetes isn't going to trust it.

I'm open to any ideas that could make the feature you are looking for a reality, but this change you've proposed isn't going to accomplish it.

@krancour
Copy link
Member

Closing in favor of #4195

@krancour krancour closed this May 22, 2025
@thomaspurchas
Copy link
Author

Hi @krancour, our cluster and Kargo do share an IDP. #4195 gives us the ability to issue tokens to the browser that contain both the Kargo OIDC audience and the cluster audience, which makes the token valid for authentication against the underlying cluster.

If our authentication filter cannot validate that the token it receives was issued by Kargo's IDP, it assumes it may have been issued by Kubernetes' IDP.

This is not quite true. That rule doesn’t apply to JWTs. The filter currently assumes that it’s impossible for a JWT to be valid against both the cluster and the Kargo UI, which is an incorrect assumption, and also an unnecessary assumption. If the JWT isn’t valid for use against the cluster, then as you say, the section below will reject it once it attempts perform a subject self-access review with the token.

All my change does is ensure that check is always attempted, regardless of type of token that was passed to Kargo.

Admittedly this change requires #4195 to work in any sensible system (there’s not technically preventing a cluster accepting a JWT with the Kargo audience, Kubernetes will accept any audience you ask it to accept, it would just be a poor security decision). But we currently have this working internally just fine, and have been using for a couple of months now.

@krancour
Copy link
Member

krancour commented May 23, 2025

The filter currently assumes that it’s impossible for a JWT to be valid against both the cluster and the Kargo UI, which is an incorrect assumption

Without #4195, this assumption is correct and you've indicated yourself that this change requires #4195. I've indicated I'm receptive to #4195, so please let's disregard this one-line PR and keep iterating on #4195 and make whatever other changes are necessary over there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Has security implications and needs to be handled with great caution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants