Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for OIDC MTLS binding #45121

Merged
merged 1 commit into from
Dec 21, 2024
Merged

Conversation

sberyozkin
Copy link
Member

@sberyozkin sberyozkin commented Dec 13, 2024

Fixes #4482.

This PR adds support for OIDC MTLS Binding, to support cases where it is absolutely necessary to prove the access token was issued to the client who is presenting it. The client must authenticate over MTLS and the client certificate's thumbprint must match the JWT token or token introspection confirmation thumbprint.

It took a while to deal with this issue, setting up the tests was tricky, but finally, with the help from Keycloak devservice, inclusive authentication, certificate generation, it all got in place.

The actual source update is quite simple - if the access token must be certificate bound then the MTLS certificate thumbprint is stored in the routing context when the bearer access token is about to be verified, and then it is compared to the JWT token or token introspection confirmation cnf x5t#S256 thumbprint.

Docs have been updated and tests added to check:

  • that a thumbprint is present in the JWT token
  • that a thumbprint is present in the token introspection
  • that a client which is configured to use the client secret authenticator in Keycloak can access Quarkus endpoint which does not require a certificate binding over MTLS, but fails to access the endpoints where the certficate binding is enforced

Copy link

github-actions bot commented Dec 13, 2024

🙈 The PR is closed and the preview is expired.

@sberyozkin sberyozkin force-pushed the oidc_mtls_binding branch 4 times, most recently from 2eceece to 06399b9 Compare December 15, 2024 23:15
@sberyozkin sberyozkin force-pushed the oidc_mtls_binding branch 3 times, most recently from 612d582 to d26833d Compare December 16, 2024 16:39
@quarkus-bot quarkus-bot bot added area/docstyle issues related for manual docstyle review area/documentation labels Dec 16, 2024
@sberyozkin sberyozkin marked this pull request as ready for review December 16, 2024 16:41

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

@sberyozkin
Copy link
Member Author

@cescoffier @michalvavrik, would you like to review, comment ? This is an important OIDC/OAuth2 token security hardening feature, but the implementation is really straightforward, with no OIDC logic impact of any kind.

If Quarkus expects bearer access tokens be certificate bound, then the token must have a certificate tumbprint claim which must match the current MTLS client certificate (chain leaf) thumbprint - this is all to it.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

Copy link
Contributor

@pedroigor pedroigor left a comment

Choose a reason for hiding this comment

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

@sberyozkin Nice to see yet another key capability supported.

Are you also updating client registrations as per https://datatracker.ietf.org/doc/html/rfc8705#name-client-registration-metadata-2?

[source,properties]
----
quarkus.oidc.auth-server-url=${your_oidc_provider_url}
quarkus.oidc.token.certificate-bound=true <1>
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to have a specific namespace for sender-constrained tokens such as quarkus.oidc.token.binding and have certificate-bound tokens configured as quarkus.oidc.token.binding.certificate=true?

Thinking about DPoP, for instance, we could use the same namespace to configure it. Something like quarkus.oidc.token.binding.dpop.<properties>.

It could also help to add more capabilities, when needed, for each individual token-binding method.

Not sure, only a suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hi @pedroigor I think you are right, thanks for thinking ahead, we'd want to have dpop configured at the same level. I'll work on encapsulating this configuration as you suggested

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey @pedroigor, I've encapsulated it as token.binding.certificate. So far it is the only properties, but one case I've heard about is about TLS termination so we may want to support a header passing the cert thumbprint internally for those cases, and like you said, other binding customizations will be easier to handle.

I'm not sure yet if we will put dpop inside or next to binding as it is a bit different, and there is also dpop related to the authorization code flow, but we can discuss it in a month or two

thanks

@sberyozkin
Copy link
Member Author

sberyozkin commented Dec 19, 2024

Hi @pedroigor, thanks for the review, approval, and useful feedback - I'll definitely deal with your configuration related suggestion before merging.

Are you also updating client registrations as per https://datatracker.ietf.org/doc/html/rfc8705#name-client-registration-metadata-2?

I've totally missed it, so right now the client is setup in the test realm, it has the OAuth2 MTLS Certificate Bound option enabled and its authenticator is setup as X509 Certificate with Subject DN configured.

So another option would be to register a client dynamically using our new quarkus-oidc-client-registration extension, and use tls_client_certificate_bound_access_tokens=true registration metadata - but I don't know if it is enough to have Keycloak to enable the X509 Certificate authenticator for the newly registered client be able to access Keycloak over MTLS.

I'll keep this option in mind and open an issue to investigate - may be we can work with the Keycloak team to use tls_client_certificate_bound_access_tokens=true alongside the Keycloak specific metadata to have a complete dynamic client setup, that would be awesome... See #45210

@sberyozkin
Copy link
Member Author

@michalvavrik Thanks for your comments as well

@sberyozkin sberyozkin force-pushed the oidc_mtls_binding branch 2 times, most recently from 1f75202 to f7a8946 Compare December 20, 2024 19:31
Copy link

quarkus-bot bot commented Dec 20, 2024

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit f7a8946.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

This comment has been minimized.

@sberyozkin
Copy link
Member Author

Some strange native test build failure, fine on my machine, rerunning the job

Copy link

quarkus-bot bot commented Dec 21, 2024

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit f7a8946.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@sberyozkin sberyozkin merged commit 1b8f5c3 into quarkusio:main Dec 21, 2024
26 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.18 - main milestone Dec 21, 2024
@quarkus-bot quarkus-bot bot added the kind/enhancement New feature or request label Dec 21, 2024
@sberyozkin sberyozkin deleted the oidc_mtls_binding branch December 21, 2024 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support the access token binding to the client MTLS authentication
3 participants