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

Switch to using a single JWT library and unify api package #119

Merged
merged 3 commits into from
Sep 21, 2022

Conversation

sethvargo
Copy link
Contributor

@sethvargo sethvargo commented Sep 21, 2022

The current implementation uses two JWT packages: github.com/golang-jwt/jwt and github.com/lestrrat-go/jwx/v2/jwt. These packages have very different APIs and developer surfaces. This PR standardizes everything on github.com/lestrrat-go/jwx/v2/jwt since we need to the jwx package anyway for jwk parsing and jws signing.

Because github.com/lestrrat-go/jwx/v2/jwt uses an interface to store claims, this PR introduces new top-level functions for getting/setting justifications on a token. This is significantly less error-prone than relying on "justs" to be populated in the JSON and enforces a structure. The downside is that it requires an extra option during parsing, but that is abstracted away into helpers. These helpers are important because the previous implementation had some extremely rough edges because slices are passed by reference. This caused data races and extremely-difficult-to-debug side-effects. The helpers make a copy of slices to ensure this doesn't happen.

One of the major downsides of the github.com/lestrrat-go/jwx/v2/jwt package is that there is no way to create "unsigned" tokens. github.com/golang-jwt/jwt has a "SigningString()" function for this purpose, but that does not exist in the new package. In retrospect, I'm not convinced that using the ".NOT_SIGNED" suffix is the right solution for breakglass, and I think we should explore using HMAC-signed keys instead. That being said, I was able to preserve backwards-compatibility with the existing implementation by signing the key, stripping off the signature, and appending ".NOT_SIGNED". This is less than ideal, but I think any refactors to the breakglass semantics should be done in a separate PR and discussion.

This PR also has some general code cleanup, such as being consistent with the name of the jvsapis/v0 package import.

Closes #116

apis/v0/jwt.go Show resolved Hide resolved
apis/v0/jwt.go Show resolved Hide resolved
apis/v0/jwt.go Show resolved Hide resolved
apis/v0/jwt.go Outdated Show resolved Hide resolved
pkg/cli/token.go Show resolved Hide resolved
client-lib/go/client/jvs_config.go Show resolved Hide resolved
The current implementation uses two JWT packages: github.com/golang-jwt/jwt and github.com/lestrrat-go/jwx/v2/jwt. These packages have very different APIs and developer surfaces. This PR standardizes everything on github.com/lestrrat-go/jwx/v2/jwt since we need to the jwx package anyway for jwk parsing and jws signing.

Because github.com/lestrrat-go/jwx/v2/jwt uses an interface to store claims, this PR introduces new top-level functions for getting/setting justifications on a token. This is significantly less error-prone than relying on "justs" to be populated in the JSON and enforces a structure. The downside is that it requires an extra option during parsing, but that is abstracted away into helpers. These helpers are important because the previous implementation had some extremely rough edges because slices are passed by reference. This caused data races and extremely-difficult-to-debug side-effects. The helpers make a copy of slices to ensure this doesn't happen.

One of the major downsides of the github.com/lestrrat-go/jwx/v2/jwt package is that there is no way to create "unsigned" tokens. github.com/golang-jwt/jwt has a "SigningString()" function for this purpose, but that does not exist in the new package. In retrospect, I'm not convinced that using the ".NOT_SIGNED" suffix is the right solution for breakglass, and I think we should explore using HMAC-signed keys instead. That being said, I was able to preserve backwards-compatibility with the existing implementation by signing the key, stripping off the signature, and appending ".NOT_SIGNED". This is less than ideal, but I think any refactors to the breakglass semantics should be done in a separate PR and discussion.

This PR also has some general code cleanup, such as being consistent with the name of the jvsapis/v0 package import.
Copy link
Contributor

@yolocs yolocs left a comment

Choose a reason for hiding this comment

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

This is super to make things consistent! Immense thanks!

apis/v0/jwt.go Show resolved Hide resolved
apis/v0/jwt.go Show resolved Hide resolved
apis/v0/jwt.go Outdated Show resolved Hide resolved
apis/v0/jwt_test.go Show resolved Hide resolved
apis/v0/jwt_test.go Outdated Show resolved Hide resolved
pkg/cli/token.go Show resolved Hide resolved
pkg/cli/token.go Show resolved Hide resolved
pkg/cli/token.go Show resolved Hide resolved
apis/v0/jwt.go Show resolved Hide resolved
@sethvargo sethvargo merged commit 4d54c90 into main Sep 21, 2022
@sethvargo sethvargo deleted the sethvargo/jwt branch September 21, 2022 19:13
sqin2019 pushed a commit that referenced this pull request Apr 6, 2023
* Switch to using a single JWT library and unify api package

The current implementation uses two JWT packages: github.com/golang-jwt/jwt and github.com/lestrrat-go/jwx/v2/jwt. These packages have very different APIs and developer surfaces. This PR standardizes everything on github.com/lestrrat-go/jwx/v2/jwt since we need to the jwx package anyway for jwk parsing and jws signing.

Because github.com/lestrrat-go/jwx/v2/jwt uses an interface to store claims, this PR introduces new top-level functions for getting/setting justifications on a token. This is significantly less error-prone than relying on "justs" to be populated in the JSON and enforces a structure. The downside is that it requires an extra option during parsing, but that is abstracted away into helpers. These helpers are important because the previous implementation had some extremely rough edges because slices are passed by reference. This caused data races and extremely-difficult-to-debug side-effects. The helpers make a copy of slices to ensure this doesn't happen.

One of the major downsides of the github.com/lestrrat-go/jwx/v2/jwt package is that there is no way to create "unsigned" tokens. github.com/golang-jwt/jwt has a "SigningString()" function for this purpose, but that does not exist in the new package. In retrospect, I'm not convinced that using the ".NOT_SIGNED" suffix is the right solution for breakglass, and I think we should explore using HMAC-signed keys instead. That being said, I was able to preserve backwards-compatibility with the existing implementation by signing the key, stripping off the signature, and appending ".NOT_SIGNED". This is less than ideal, but I think any refactors to the breakglass semantics should be done in a separate PR and discussion.

This PR also has some general code cleanup, such as being consistent with the name of the jvsapis/v0 package import.

* Process review feedback

* Add more defense about unmarshalling bad types
verbanicm pushed a commit that referenced this pull request Jun 14, 2023
* Switch to using a single JWT library and unify api package

The current implementation uses two JWT packages: github.com/golang-jwt/jwt and github.com/lestrrat-go/jwx/v2/jwt. These packages have very different APIs and developer surfaces. This PR standardizes everything on github.com/lestrrat-go/jwx/v2/jwt since we need to the jwx package anyway for jwk parsing and jws signing.

Because github.com/lestrrat-go/jwx/v2/jwt uses an interface to store claims, this PR introduces new top-level functions for getting/setting justifications on a token. This is significantly less error-prone than relying on "justs" to be populated in the JSON and enforces a structure. The downside is that it requires an extra option during parsing, but that is abstracted away into helpers. These helpers are important because the previous implementation had some extremely rough edges because slices are passed by reference. This caused data races and extremely-difficult-to-debug side-effects. The helpers make a copy of slices to ensure this doesn't happen.

One of the major downsides of the github.com/lestrrat-go/jwx/v2/jwt package is that there is no way to create "unsigned" tokens. github.com/golang-jwt/jwt has a "SigningString()" function for this purpose, but that does not exist in the new package. In retrospect, I'm not convinced that using the ".NOT_SIGNED" suffix is the right solution for breakglass, and I think we should explore using HMAC-signed keys instead. That being said, I was able to preserve backwards-compatibility with the existing implementation by signing the key, stripping off the signature, and appending ".NOT_SIGNED". This is less than ideal, but I think any refactors to the breakglass semantics should be done in a separate PR and discussion.

This PR also has some general code cleanup, such as being consistent with the name of the jvsapis/v0 package import.

* Process review feedback

* Add more defense about unmarshalling bad types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Two jwt libraries
2 participants