Skip to content

Conversation

@xtremerui
Copy link

so client can get access to Dex resources e.g. forwarding auth request and performing token exchange while handling callback from Dex.

@karunchennuri
Copy link

@xtremerui I've been evaluating Dex as SP front ending Okta IdP. One of the use cases, I was looking at is support for client_credentials grant type. In a way, I want client application to use static client id and secret, configured at the time of Dex connector configuration, to retrieve id_token, refresh_token, access_token, code from Dex.

This PR is going to support that? The connector type 'am exploring is OIDC.

@xtremerui
Copy link
Author

@karunchennuri yes we have similar use case thus we implemented this in our fork https://github.com/concourse/dex. Not sure how it is gonna be in upstream.

@karunchennuri
Copy link

karunchennuri commented Jun 10, 2020 via email

@karunchennuri
Copy link

@xtremerui I tested this PR on the master branch of dex. Worked perfectly fine.
Somehow I had difficulty running local tests on the https://github.com/concourse/dex. That's the reason just cherry picked your PR. Thanks a lot for putting this together, I was reading some older posts on the reluctance to support client_credentials grant type, there must be a reason, I would be interested in knowing more on that from others on this thread.

@xtremerui
Copy link
Author

@karunchennuri glad it works. The test could be ran using the Makefile

dex/Makefile

Lines 44 to 45 in 2ca992e

test: bin/test/kube-apiserver bin/test/etcd
@go test -v ./...

make test

@mvdkleijn
Copy link
Contributor

@xtremerui Would you be open to update this PR since it has conflicts?

@xtremerui
Copy link
Author

@mvdkleijn absolutely. Most of my PRs got conflicts I will update all of them. Thank you!

@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 2 times, most recently from d06e60b to 37225ee Compare August 4, 2020 19:13
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 3 times, most recently from 579a1de to 133d9b6 Compare September 28, 2020 19:39
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 3 times, most recently from 47d4519 to b648030 Compare October 5, 2020 17:39
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from b648030 to 00c37b6 Compare October 16, 2020 16:43
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 2 times, most recently from 5b265dd to 12421b2 Compare November 5, 2020 04:19
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 12421b2 to 378e4c2 Compare December 15, 2020 15:54
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 2 times, most recently from 4530e4b to 1eeff38 Compare March 16, 2021 16:15
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 1eeff38 to 93b8d35 Compare March 20, 2021 20:06
@xtremerui xtremerui closed this Nov 10, 2021
@xtremerui xtremerui reopened this Nov 10, 2021
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from e84cf0e to dbb4f3e Compare November 10, 2021 19:44
@xtremerui
Copy link
Author

@sagikazarmark could I get some feedback on this PR please?

@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 2 times, most recently from a031678 to 73f1657 Compare September 16, 2022 05:28
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch 2 times, most recently from 1905f8f to 4e3fe5b Compare October 4, 2022 10:34
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 4e3fe5b to 895f3b2 Compare October 31, 2022 15:02
@RealHarshThakur
Copy link

Hey folks, is there anything I can do to help this PR move forward?

@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 895f3b2 to 7a07880 Compare March 20, 2023 13:31
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 7a07880 to 3f0f531 Compare June 30, 2023 14:13
@cloudmarius
Copy link

Hi there, any intention still to merge this feature?

@jarrettprosser
Copy link

jarrettprosser commented Sep 13, 2023

I've tested the fork this change is based on and found that in the case of a public client, Dex will issue client credentials for the public client if I provide the client ID and leave out the secret value (or set it to null). This is an issue for our use; simply knowing the client ID (which is sent in plaintext by the UI when getting a token) is enough to get an access token. Not sure if that has been resolved in this PR though.

We've ended up using the Device Code Flow with a staticClient and staticPassword as an alternative, but having full support for the Client Credentials Grant would be better.

@nabokihms
Copy link
Member

With the allowedGrants, I think now we can add the support for client credentials grant and make it not enabled by default.

@sagikazarmark what do you think?

@smehboub
Copy link

smehboub commented Jun 9, 2024

Hello,

Thank you very much for your work.
Any news on progress ?

Thanks in advance :-)
Rgs

@taylorsilva taylorsilva force-pushed the pr/client-credentials-grant-sync branch from 3f0f531 to f72d7eb Compare January 16, 2025 18:41
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from f72d7eb to 08844c6 Compare February 19, 2025 13:20
@nabokihms nabokihms added the release-note/new-feature Release note: Exciting New Features label Feb 25, 2025
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from 08844c6 to ce3617b Compare July 22, 2025 17:21
Rui Yang and others added 3 commits September 1, 2025 13:24
Signed-off-by: Rui Yang <ruiya@vmware.com>
This fixes two issues in the existing client credentials change:

- client_credentials was not listed as a supported grant type
- access tokens are not the storage ID

Signed-off-by: Michael Kelly <mkelly@arista.com>
Signed-off-by: Rui Yang <ruiya@vmware.com>
@xtremerui xtremerui force-pushed the pr/client-credentials-grant-sync branch from ce3617b to 3925296 Compare September 1, 2025 13:24
@cardoe
Copy link
Contributor

cardoe commented Sep 11, 2025

@sagikazarmark and @nabokihms wanted to re-raise what you mentioned about including this and leaving it disabled by default. What would you think?

Reason I ask is that I know folks are using this for robot / machine accounts. It might also be acceptable to add the ability to have the hidden connectors that robot / machine accounts utilize without having that prompt users.

@testinfected
Copy link

testinfected commented Dec 8, 2025

@sagikazarmark We have exactly the same issue as @xtremerui and @kellyma2 with Flyte. Flyte deploys in a Kubernetes env and has a concept of a worker which needs to authenticate to the Flyte control plane. We can only setup a single OIDC/OAuth2 server, and we use Dex for it (Okta connector). Flyte uses client credentials grant for the worker.

As per @nabokihms @cardoe suggestions, would it be fine to disable it by default. Also, would need to add verification of the client secret as well. Currently only the ID is checked.

Thanks

@sagikazarmark
Copy link
Member

I'm inclined to accept this given the popular demand.

Unfortunately I have limited time, so if someone could run some tests, it would be immensely helpful.

The code change itself is relatively small, so once we have confirmation it works as expected, we should be able to get this merged relatively quickly.

(I'm constantly flooded by GitHub emails, so keep pinging me if I don't respond. Thanks! 🙏 )

cardoe added a commit to cardoe/dex that referenced this pull request Dec 9, 2025
@cardoe
Copy link
Contributor

cardoe commented Dec 9, 2025

To further this along, I've pulled this PR into build that I made at https://github.com/cardoe/dex/releases/tag/v2.44.90 You can grab the container to test with at ghcr.io/cardoe/dex:v2.44.90 and report back on this PR.

@testinfected
Copy link

I pulled this PR as well on my side and have tested it against Flyte (our use case). Works without issues. I have reviewed the code which looks alright (although I'm new to the codebase).

My 2 cents
Thanks guys

Copy link
Member

@sagikazarmark sagikazarmark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really hate to be the gatekeeper (especially since @xtremerui has been rebasing this PR for years now), but I had some comments, one of them is potentially a blocker.

w.Write(claims)
}

func (s *Server) handleClientCredentialsGrant(w http.ResponseWriter, r *http.Request, client storage.Client) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong, but client credentials grant isn't supposed to work with public clients, is it?

Shouldn't there be some sort of check here?

Technically, withClientFromStorage checks the secret, but public clients have empty secret, so it will always match.

If I'm right, this is a rather serious vulnerability.

@cardoe any chance you could give this a try in your build?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it would probably be a good idea to cover at least the happy path with tests.


claims := storage.Claims{UserID: client.ID}

accessToken, _, err := s.newAccessToken(r.Context(), client.ID, claims, scopes, nonce, "client")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is generating an access token always necessary? Shouldn't it be returned based on the requested scopes?

accessToken, _, err := s.newAccessToken(r.Context(), client.ID, claims, scopes, nonce, "client")
if err != nil {
s.logger.ErrorContext(r.Context(), "failed to create new access token", "err", err)
s.tokenErrHelper(w, errServerError, err.Error(), http.StatusInternalServerError)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've just merged #4457 removing internal error messages from responses. I think a generic error message should be returned here.

See the linked PR.


idToken, expiry, err := s.newIDToken(r.Context(), client.ID, claims, scopes, nonce, accessToken, "", "client")
if err != nil {
s.tokenErrHelper(w, errServerError, fmt.Sprintf("failed to create ID token: %v", err), http.StatusInternalServerError)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

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

Labels

release-note/new-feature Release note: Exciting New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.