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

perf(oidc): optimize token creation #7822

Merged
merged 59 commits into from May 16, 2024
Merged

perf(oidc): optimize token creation #7822

merged 59 commits into from May 16, 2024

Conversation

muhlemmer
Copy link
Contributor

@muhlemmer muhlemmer commented Apr 22, 2024

Optimize token creation by managing creation directly through the command package.
This minimizes the amount of calls that need to made to the database. The old implementation made repeated calls through OIDC's Storage interface. In this PR we attempt to resolve all business logic in the command package, with a single query of related write models.

This optimization migrates old repository tokens to the v2 token implementation already used by the OIDC session API. The "old" token repository is kept for now, so that after a zitadel upgrade old tokens can still be refreshed. During a refresh of a "v1" token a "v2" token will now be returned. In theory we should be able to remove the token repository related code for the release after this one.

Users that query the event API to aggregate user activity, eg Daily Active Users, should be aware that there is a new event type user.token.v2.added. The legacy event user.token.added still exists, but new events of this type will no longer be created after ZITADEL is upgraded.

Note that due to some small changes in device authorization events, it is possible that device authorization flows that where started and still in progress during an upgrade, might fail.

Definition of Ready

  • I am happy with the code
  • Short description of the feature/issue is added in the pr description
  • PR is linked to the corresponding user story
  • Acceptance criteria are met
  • All open todos and follow ups are defined in a new ticket and justified
  • Deviations from the acceptance criteria and design are agreed with the PO and documented.
  • No debug or dead code
  • My code has no repetitions
  • Critical parts are tested automatically
  • Where possible E2E tests are implemented
  • Documentation/examples are up-to-date
  • All non-functional requirements are met
  • Functionality of the acceptance criteria is checked manually on the dev system.

Copy link

vercel bot commented Apr 22, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 15, 2024 10:20am

Copy link

codecov bot commented May 13, 2024

Codecov Report

Attention: Patch coverage is 68.76248% with 313 lines in your changes are missing coverage. Please review.

❗ No coverage uploaded for pull request base (main@6cf9ca9). Click here to learn what that means.

❗ Current head b5a05b4 differs from pull request most recent head 4d585a1. Consider uploading reports for the commit 4d585a1 to get more accurate results

Files Patch % Lines
internal/api/oidc/auth_request.go 23.62% 93 Missing and 4 partials ⚠️
internal/api/oidc/token_code.go 35.06% 44 Missing and 6 partials ⚠️
internal/api/oidc/token_refresh.go 30.35% 35 Missing and 4 partials ⚠️
internal/command/oidc_session.go 84.35% 14 Missing and 9 partials ⚠️
internal/api/oidc/token_device.go 0.00% 22 Missing ⚠️
internal/api/oidc/token.go 82.14% 10 Missing and 10 partials ⚠️
internal/api/oidc/token_jwt_profile.go 80.64% 6 Missing and 6 partials ⚠️
internal/domain/browser_info.go 0.00% 9 Missing ⚠️
internal/command/device_auth.go 85.45% 5 Missing and 3 partials ⚠️
internal/api/oidc/token_client_credentials.go 80.64% 3 Missing and 3 partials ⚠️
... and 12 more
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7822   +/-   ##
=======================================
  Coverage        ?   62.75%           
=======================================
  Files           ?     1341           
  Lines           ?   111030           
  Branches        ?        0           
=======================================
  Hits            ?    69679           
  Misses          ?    37426           
  Partials        ?     3925           
Flag Coverage Δ
core-integration-tests-postgres 62.75% <68.76%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@muhlemmer
Copy link
Contributor Author

muhlemmer commented May 13, 2024

Some bugs found during manual tests:

  • Using oidc App example with only password auth, the returned amr is ["pwd","pwd","mfa"]
  • When creating v1 tokens on old zitadel version, upgrade and using the refresh token: works, but the v1 refresh token isn't invalided and can be reused. v2 refresh tokens work as expected and can only be used once.
  • Device auth has a panic after click "approve" in the login UI.

@muhlemmer muhlemmer merged commit 8e0c839 into main May 16, 2024
25 checks passed
@muhlemmer muhlemmer deleted the optimize-token-creation branch May 16, 2024 05:07
muhlemmer added a commit that referenced this pull request May 23, 2024
# Which Problems Are Solved

After #7822 was merged we
discovered that
v2 tokens that where obtained through an IDP using the v1 login, can't
be used for
zitadel API calls.

- Because we used to store the AMR claim on the auth request, but
internally use the domain.UserAuthMethod type. AMR has no notion of an
IDP login, so that "factor" was lost
during conversion. Rendering those v2 tokens invalid on the zitadel API.
- A wrong check on machine user tokens falsly allowed some tokens to be
valid
- The client ID was set to tokens from client credentials and JWT
profile, which made client queries fail in the validation middleware.
The middleware expects client ID unset for machine users.

# How the Problems Are Solved

Store the domain.AuthMethods directly in  the auth requests and session,
instead of using AMR claims with lossy conversion.

- IDPs have seperate auth method, which is not an AMR claim
- Machine users are treated specialy, eg auth methods are not required.
- Do not set the client ID for client credentials and JWT profile

# Additional Changes

Cleaned up mostly unused `oidc.getInfoFromRequest()`.

# Additional Context

- Bugs were introduced in #7822
and not yet part of a release.
- Reported internally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JWT Profile Grant: return id_token if openid scope is set Optimize TokenResponse
2 participants