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

sso: add OIDC login RPC, HTTP, and CLI workflow #15764

Merged
merged 7 commits into from
Jan 18, 2023

Conversation

jrasell
Copy link
Member

@jrasell jrasell commented Jan 12, 2023

Each commit targets a different section of the code and attempts to make reviewing easier.

Raising in draft initially so I can perform some additional local testing in parallel.

Related: #13120

Copy link
Member

@tgross tgross left a comment

Choose a reason for hiding this comment

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

@jrasell I've taken an initial pass over this and it's looking good so far. I really appreciate the solid comments you've left on some of the gritty bits so that folks coming along later can orient themselves.

The double-forwarding in the RPC handler seems unfortunate but given that we need to query the state to know whether we need to forward to the authoritative region I don't really see any way around it unless AuthMethod was assumed immutable, which as I understand it isn't the case.

lib/auth/oidc/provider.go Outdated Show resolved Hide resolved
Comment on lines +57 to +67
// Create a context, so a server that is shutting down can correctly
// shut down the cache loop and OIDC provider background processes.
ctx, cancel := context.WithCancel(context.Background())

result := &ProviderCache{
providers: map[string]*oidc.Provider{},
cancel: cancel,
}

// Start the cleanup timer
go result.runCleanupLoop(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

IMO this is a bug in cap: the NewProvider method doesn't take a context, and uses the background context (ref provider.go#L70 at least in the config we pass in. Obviously we have to deal with that for now in this PR but it'd be worth pushing back on that upstream with whomever maintains that library (or submitting a PR and seeing what happens). It'd cut out a lot of complexity in this cache.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh that is a great shout. I have a list of items to raise against cap and ultimately try and add. I'll add this item to the list, thanks.

lib/auth/oidc/server.go Outdated Show resolved Hide resolved
Comment on lines +55 to +56
// TODO(jrasell) find a way to test the full login flow from the CLI
// perspective.
Copy link
Member

Choose a reason for hiding this comment

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

It's probably a huge chore but useful for E2E if we could spin up a dummy OIDC provider server. Does cap have something like that already?

Copy link
Member Author

Choose a reason for hiding this comment

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

Cap does have a local test provider we can use. I think I have figured out the other blocker I had, so will look into adding that to this PR. Apologies for not doing it sooner, my initial aim with this PR was to allow us to manually run full e2e tests using multiple real providers.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry, I didn't mean to suggest we had to block this PR on that. If we've manually tested this already it seems totally reasonable to add automated E2E in a separate PR!

lib/auth/oidc/provider.go Outdated Show resolved Hide resolved
Comment on lines +157 to +159
// duration. This ensures that we force refresh our provider info periodically
// in case anything changes.
func (c *ProviderCache) runCleanupLoop(ctx context.Context) {
Copy link
Member

Choose a reason for hiding this comment

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

We don't need to do it in this PR but we might want to consider whether the RPC handlers can/should force a cache flush of the provider if they hit errors that are caused by the upstream provider (ex. this is a very long lived HTTP client and I don't know how cap has its TCP connections configured to handle a DNS change at the provider; ref golang/go#23427)

Copy link
Member Author

Choose a reason for hiding this comment

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

Great shout; I'll note this for future thought and raise as a followup issue.

nomad/acl_endpoint.go Outdated Show resolved Hide resolved
This adds new OIDC endpoints on the RPC endpoint. These two RPCs
handle generating the OIDC provider URL and then completing the
login by exchanging the provider token with an internal Nomad
token.

The RPC endpoints both do double forwarding. The initial forward
is to ensure we are talking to the regional leader; the second
then takes into account whether the auth method generates local or
global tokens. If it creates global tokens, we must then forward
onto the federated regional leader.
The OIDC provider cache is used by the RPC handler as the OIDC
implementation keeps long lived processes running. These process
include connections to the remote OIDC provider.

The Callback server is used by the CLI and starts when the login
command is triggered. This callback server includes success HTML
which is displayed when the user successfully logs into the remote
OIDC provider.
Copy link
Contributor

@pkazmierczak pkazmierczak left a comment

Choose a reason for hiding this comment

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

This looks good @jrasell! I couldn't find anything but it is a pretty large PR and even though it has neat commits that separate by functionality (🙏), it's still a lot of code and at some point fatigue kicks in and I might've missed something. This being said, I did quite some testing of this code using vault as oidc provider and it seems to be working exactly as expected.

* Updated UI to handle OIDC method changes

* Remove redundant store unload call
@github-actions
Copy link

Ember Asset Size action

As of d57b805

Files that got Bigger 🚨:

File raw gzip
nomad-ui.js +302 B +69 B

Files that stayed the same size 🤷‍:

File raw gzip
vendor.js 0 B 0 B
nomad-ui.css 0 B 0 B
vendor.css 0 B 0 B

@github-actions
Copy link

Ember Test Audit comparison

sso/gh-13120-oidc-login d57b805 change
passes 1452 1452 0
failures 0 0 0
flaky 0 0 0
duration 11m 37s 851ms 10m 50s 785ms -47s 066ms

@jrasell jrasell merged commit ca753cf into sso/gh-13120-oidc-login Jan 18, 2023
@jrasell jrasell deleted the jrasell/gh-13120-oidc-login branch January 18, 2023 09:38
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.

4 participants