dexidp / dex

OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
https://dexidp.io
Apache License 2.0
9.23k stars 1.67k forks source link

Get OIDC token issued by Dex using a token issued by one of the connectors. #2657

Open shankerwangmiao opened 1 year ago

shankerwangmiao commented 1 year ago

Preflight Checklist

Problem Description

In some scenarios, there can only be one OIDC provider, e.g. kube-apiserver. Dex can serve this role well by providing various connectors. However, when it comes to a program which has been issued an OIDC token from another issuer, it cannot be used to exchange for a Dex issued token programmingly.

Proposed Solution

OIDC connectors can be configured as ``passive", which will be hidden to the interactive users.

An api interface can be added to Dex, say /token. When a POST request like below is received, the token from the Authorization header will be extracted and verified against each configured passive OIDC connector. If one of them get passed, the client will be issued an OIDC token issued by Dex.

POST /token HTTP/1.1
Host: server.example.com
Authorization: Bearer <OIDC_Token_issued_by_a_connector_goes_here>
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=<foo_client>

Alternatives Considered

No response

Additional Information

The use case is, I would like a Kubernetes cluster can be accessed by both interactive normal users and programmingly CI jobs. CI jobs running on gitlab runners are issued an OIDC token by the gitlab instance via an environment variable. If this is implemented, then the CI job can get a token issued by Dex using this OIDC token, which can then be used to access the kubernetes cluster.

This function is previously mentioned in https://github.com/dexidp/dex/issues/1484#issuecomment-514163788, but the topic for that issue is totally different.

iamnoah commented 1 year ago

RFC8693 defines a token-exchange grant_type that accepts a token for authentication. Dex could accept this grant type in on the token endpoint for an OIDC connector, validate the token via JWKS, and issue a new token using the claimMapping.

blairdrummond commented 1 year ago

I would love to see this implemented. My use case is I use ArgoCD with Dex on Azure with AzureAD. Users are using AAD no problem, but I want my pipelines to be able to access ArgoCD's API with a JWT (avoiding local accounts). The pipeline easily gets a sts.windows.net JWT from the machine identity/service principal in the pipeline, so if I could exchange that AAD token for a Dex token then machine access would be very smooth.

blairdrummond commented 1 year ago

I think the token exchange flow that was merged in #2806 should solve this. I am able to exchange github-actions JWTs for Dex JWTs, and there's an example curl command for that here. (Note: there's no release containing this code yet, but it works on images built off of main)

churrascats commented 3 months ago

I'm trying to implement token exchange with AzureAD and I'm getting an "unsupported_grant_type", is it only available for Github Actions?

nabokihms commented 3 months ago

@churrascats No, it is not. This is a generic feature that works with all oidc providers.

Which version of Dex do you use?

churrascats commented 3 months ago

I'm using dex:v2.37.0

Here is my dex config... Really appreciate your support.

issuer: http://localhost:8000/dex

storage: type: sqlite3 config: file: /var/dex/dex.db

web: http: 0.0.0.0:5556

oauth2: grantTypes:

staticClients:

connectors: