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

feat: add jwks access type to external token handler #24681

Merged
merged 13 commits into from
May 22, 2024

Conversation

ryan-hanchett
Copy link
Contributor

Hey, I just made a Pull Request!

Re-opening from #24679 after I got into some trouble with git.

This pull request builds on BEP-07 to expand the ExternalTokenHandler to support a configured JWKS auth strategy. This allows external callers to use 3rd party authentication via JWKS, enabling greater flexibility in providing ways to auth with Backstage via signed tokens.

A potential area of improvement for future PRs would be to move the TokenFactory used in the tests into the backend-test-utils plugin, since it is used with near-identical patterns in the jwks.test.ts file, as well as plugins/auth-node/src/identity/DefaultIdentityClient.test.ts, and plugins/auth-node/src/identity/IdentityClient.test.ts.

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)
  • All your commits have a Signed-off-by line in the message. (more info)

Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
@ryan-hanchett ryan-hanchett requested review from a team as code owners May 7, 2024 22:08
@github-actions github-actions bot added the documentation Improvements or additions to documentation label May 7, 2024
@backstage-goalie
Copy link
Contributor

backstage-goalie bot commented May 7, 2024

Changed Packages

Package Name Package Path Changeset Bump Current Version
@backstage/backend-app-api packages/backend-app-api patch v0.7.3

Copy link
Member

@Rugvip Rugvip 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! 🎉

Couple of early thoughts

@freben
Copy link
Member

freben commented May 8, 2024

@Rugvip a thought about naming/targeting - should it be

  • named oidc or openid
  • expect a BASE auth server url instead of directly to jwks
  • look up /.well-known/openid-configuration and the JWKS uri from there automatically

That's sort of the actual use case being targeted right? Feels like an end user would appreciate the framing of that, and knowing how to ask for and insert the common auth server url rather than the more technical implementation dependant JWKS?

@Rugvip
Copy link
Member

Rugvip commented May 8, 2024

@freben hmm, JWKS endpoints are used for more than just OIDC. I'm thinking that we consider that as an addition, but as a base feature set I think the existing structure makes sense?

Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
…config

Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
@ryan-hanchett
Copy link
Contributor Author

@freben I like the idea of calculating the jwks endpoint based on the openid-configuration. Perhaps we could add an additional config where users could provide the base server or the direct JWKS url, or we could add an additional token handler so we have both jwks and oidc to give users flexibility but keep them separate.

Happy to do that as a follow-up PR or to make the changes here, whatever makes the most sense.

@freben
Copy link
Member

freben commented May 8, 2024

Yep so if the given url doesn't contain ".well-known", do A, otherwise do B. There's possibilities for future smarts as additions to the basic feature as followups

@ryan-hanchett ryan-hanchett requested a review from Rugvip May 8, 2024 17:20
@Rugvip
Copy link
Member

Rugvip commented May 8, 2024

Prolly need to be a bit more explicit though, JWKS endpoints don't always contain .well-known, e.g. https://login.microsoftonline.com/common/discovery/v2.0/keys

@freben
Copy link
Member

freben commented May 8, 2024

Alright, makes sense then to keep this one explicit, thanks!

@ryan-hanchett
Copy link
Contributor Author

Any other changes/improvements ya'll want me to make on this existing PR?

@Rugvip Rugvip added the merge-after-release This is a bit too scary to merge until after the next release label May 13, 2024
@ryan-hanchett
Copy link
Contributor Author

Was the merge-after-release added for ^1.27.0? Or is there another release we're waiting for that I can communicate back to my team?

@freben
Copy link
Member

freben commented May 17, 2024

It was, yes, we've just been busy.

@ryan-hanchett
Copy link
Contributor Author

Understood, no worries! Thanks for getting back to me so quickly!

docs/auth/service-to-service-auth.md Outdated Show resolved Hide resolved
const issuers = options.getOptionalStringArray('issuers');
const audiences = options.getOptionalStringArray('audiences');
const subjectPrefix = options.getOptionalString('subjectPrefix');
const url = new URL(options.getString('url'));
Copy link
Member

Choose a reason for hiding this comment

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

Could you add all of this to the config.d.ts file in this package? It's important to keep the config schema in check :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I always forget about the config.d.ts 🤦

Yes I can update it with the new fields

async verifyToken(token: string) {
for (const entry of this.#entries) {
try {
const jwks = createRemoteJWKSet(entry.url);
Copy link
Member

Choose a reason for hiding this comment

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

Oh you don't want to create one of these for every single token verification. You'll lose all TTL based caching benefits and it'll hammer the remote key set relentlessly if this is in a high volume application :) You can create it in add above and keep it as part of the entry.

return { subject: `external:${sub}` };
}
} catch {
continue;
Copy link
Member

Choose a reason for hiding this comment

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

Hm. As a future enhancement (no action now), we may want to look at what the actual error thrown was, so that we can discern between hard faults (the token was ok but we refused the aud), soft errors (there was a problem speaking to the jwks endpoint, log and continue), expected situations (some other jwks signed this token so let's move on silently) etc.

The legacy handler for example, checks if (e.code !== 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') and rethrows if that's the case, because that means that the token had actual hard errors like TTL expired etc and the caller wants that error thrown to them so they can log it or show it to the user.

But for now, feel free to leave as-is.

freben and others added 3 commits May 21, 2024 09:23
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
… step

Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
Signed-off-by: Ryan Hanchett <ryan.hanchett@invitae.com>
@ryan-hanchett ryan-hanchett requested a review from freben May 21, 2024 17:05
Copy link
Member

@freben freben left a comment

Choose a reason for hiding this comment

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

Looks good!

@freben freben merged commit 8ed28ff into backstage:master May 22, 2024
29 checks passed
Copy link
Contributor

Thank you for contributing to Backstage! The changes in this pull request will be part of the 1.28.0 release, scheduled for Tue, 18 Jun 2024.

Copy link
Contributor

Uffizzi Cluster pr-24681 was deleted.

@freben
Copy link
Member

freben commented May 22, 2024

kept working on this one a bit since we have a hackweek and i am poking around in the vicinity of that code right now :)

#24874

@ryan-hanchett ryan-hanchett deleted the feat/add-jwks-access-type-1 branch May 22, 2024 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation merge-after-release This is a bit too scary to merge until after the next release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants