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

adding support for JWKS #813

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

broncha
Copy link

@broncha broncha commented Oct 1, 2023

Adds support for JWKS in Mercure. With this update, you would simply configure the JWKS URL and Mercure would validate the subscriber and publisher JWT based on the Key ID and the keys in the JWKS.
Still a work in progress, as most tests that look for JWT need to be duplicated to test JWKS

@CLAassistant
Copy link

CLAassistant commented Oct 1, 2023

CLA assistant check
All committers have signed the CLA.

Copy link
Owner

@dunglas dunglas left a comment

Choose a reason for hiding this comment

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

Thank you very much for working on this, this is a very needed feature.

authorization.go Outdated
func validateJWT(encodedToken string, jwtConfig *jwtConfig, jwksURL string) (*claims, error) {
var keyFunc jwt.Keyfunc

if jwksURL != "" {
Copy link
Owner

Choose a reason for hiding this comment

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

nitpicking: I would invert the test to avoid the negation as there is an else.

Copy link
Author

Choose a reason for hiding this comment

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

The reason I did that is to prioritize jwks when both jwks and jwt config are present. Do you see a way we could combine these?

authorization.go Outdated
if jwksURL != "" {
jwks, err := keyfunc.Get(jwksURL, keyfunc.Options{})
if err != nil {
return nil, fmt.Errorf("failed to get the JWKS from the given URL.\nError: %w", err)
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
return nil, fmt.Errorf("failed to get the JWKS from the given URL.\nError: %w", err)
return nil, fmt.Errorf("failed to get the JWKS from the given URL: %w", err)

authorization.go Outdated

keyFunc = jwks.Keyfunc
} else {
keyFunc = func(token *jwt.Token) (interface{}, error) {
Copy link
Owner

Choose a reason for hiding this comment

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

Maybe could you use a real symbol instead of an anonymous function to ease testing?

hub.go Outdated
@@ -146,6 +146,22 @@ func WithSubscriberJWT(key []byte, alg string) Option {
}
}

func WithSubscriberJWKS(jwks string) Option {
Copy link
Owner

Choose a reason for hiding this comment

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

It could be cool to support all methods supported by the underlying lib (URL, JSON, and raw key). WDYT?

Copy link
Author

Choose a reason for hiding this comment

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

As far as I have worked with JWKS, I have always worked with a URL. I think using JSON and raw key defeats the purpose of using the JWKS support as you would need to update those and restart the services in the event of key rotation. I would like to support the keyfunc.Options though. What would you suggest for those options in Caddy config? I was thinking of a nested block.

Copy link
Owner

Choose a reason for hiding this comment

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

Nested blocks looks great. I'm pretty sure that some advanced users will want to use other options so we should support both yet. For instance, advanced CI/CD pipelines may want to bundle the trusted keys.

@broncha
Copy link
Author

broncha commented Nov 2, 2023

@dunglas Finallly had some time to come back to this again. It now supports URL, json or key as jwks config.

@broncha broncha marked this pull request as ready for review November 2, 2023 06:35
@broncha broncha changed the title WIP adding support for JWKS adding support for JWKS Nov 9, 2023
Copy link

stale bot commented Mar 13, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Mar 13, 2024
@dunglas dunglas added pinned The issue must not be marked as stale and removed wontfix This will not be worked on labels Mar 13, 2024
@dvv
Copy link

dvv commented Mar 14, 2024

Please consider applying.

@dunglas
Copy link
Owner

dunglas commented Mar 18, 2024

We cannot merge the path as-is because it uses the deprecated version of keyfunc and jwt.
I rebased and slightly adjusted this patch (https://github.com/dunglas/mercure/compare/jwks_support) but there is more work to do.

Edit: upgrade to github.com/golang-jwt/jwt/v5 done in #883

@broncha
Copy link
Author

broncha commented Mar 18, 2024

I might have some time to work on #851 in coming weeks.

@dunglas
Copy link
Owner

dunglas commented Mar 18, 2024

@broncha just rebasing on top of #822 and upgrading to the latest version of keyfunc should be enough. The latest version seems to provide a simplified API, so we just need a new option to provide the server JWKS server URL and that should be enough.

@dunglas
Copy link
Owner

dunglas commented Mar 18, 2024

@broncha btw, do you mind if I force-push my rebase in your branch (I squashed all the commits)?

@broncha
Copy link
Author

broncha commented Mar 18, 2024

@dunglas Please go ahead. Ill pick it up from there.

@broncha
Copy link
Author

broncha commented Mar 18, 2024

I would also like to unify the jwt and jwks configs too. But I am not sure about the current status of the configs. Ill check those when I get a change to look at this.

@broncha
Copy link
Author

broncha commented Mar 18, 2024

Also for the record, one issue have been repeatedly facing is clock skew, where jwt creation and validation happens almost at the same time. It would be good to be able to support, which landed in golang-jwt v5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pinned The issue must not be marked as stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants