Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

[Breaking] OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC #minor #168

Merged
merged 42 commits into from
Apr 30, 2021

Conversation

EngHabu
Copy link
Contributor

@EngHabu EngHabu commented Mar 25, 2021

Signed-off-by: Haytham Abuelfutuh haytham@afutuh.com

TL;DR

This PR completes the implementation of OAuth2 and OpenID Connected started in Admin. The notable changes are:

  1. Implement OAuth2 Authorization Server so Admin can issue OAuth2 for PKCE and Client_Credentials flows.
  2. Separate OpenID Connect and OAuth2 configs to make it configurable to work with pure OpenID Connect services (e.g. Google Idp) as well as more advanced ones (e.g. KeyCloak and Okta).
  3. Breaking: Parts of the prior Auth config section have been moved up into a separate config section.
  4. Refactoring of the auth package to make it standalone and reusable in other services in flyte.
  5. Added a command line to issue and store secrets to make it easier to turn on Auth in basic scenarios.
  6. Overhaul auth config to simplify required fields for enabling auth.

Type

  • Bug Fix
  • Feature
  • Plugin

Are all requirements met?

  • Code completed
  • Smoke tested
  • Unit tests added
  • Code documentation added
  • Any pending items have an associated Issue

Tracking Issue

flyteorg/flyte#925

handler.HandleFunc(jsonWebKeysUrl.String(), GetJSONWebKeysEndpoint(authCtx))
} else {
// The metadata endpoint is an RFC-defined constant, but we need a leading / for the handler to pattern match correctly.
handler.HandleFunc(fmt.Sprintf("/%s", auth.OAuth2MetadataEndpoint), GetMetadataRedirect(authCtx))
Copy link
Contributor

Choose a reason for hiding this comment

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

The else can be eliminated and L30 can be removed from the if block.

},
"flytepropeller": {
ID: "flytepropeller",
Secret: []byte(`$2a$10$IxMdI6d.LIRZPpSfEwNoeu4rY3FhDREsxFJXikcgdRRAStxUlsuEO`), // = "foobar"
Copy link
Contributor

Choose a reason for hiding this comment

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

I am assuming this would be fed in to the app through a secrets engine and not be in the code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

to flytepropeller for example? yes, I'm going to add it to the sandbox deployment so that flytepropeller has it already deployed... and then in the guide we should tell people how to change it...

"code token",
},
GrantTypesSupported: supportedGrantTypes,
ScopesSupported: []string{auth.ScopeAll},
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs offline scope for refresh token to work

@pmahindrakar-oss
Copy link
Contributor

There is one refresh token issue which we spoke about where the expiry is incorrect.
This is log from the flytectl app where it refreshes the token but gets incorrect expiry for new one.

got a response from the refresh grant for old expiry 2021-04-09 18:39:35.990869 +0530 IST with new expiry 0001-01-01 00:00:00 +0000 UTC

Other than that i see my changes working from flytectl.

go.mod Outdated Show resolved Hide resolved
@kumare3
Copy link
Contributor

kumare3 commented Apr 15, 2021

@EngHabu something seems off here, this is a huge PR, Does every open source product have to implement this? Should this be a separate service?

@tnsetting
Copy link
Contributor

One question here: If we have a none flyteconsole web app which wants to access flyteadmin, does it require still require a cookie in the header, or we can pass the id/access token in authorization from web app directly which is similar to the grpc one?

@EngHabu
Copy link
Contributor Author

EngHabu commented Apr 19, 2021 via email

@tnsetting
Copy link
Contributor

tnsetting commented Apr 22, 2021

It can pass access tokens it acquires through OAuth2 2 or 3 legged flows....
On Mon, Apr 19, 2021 at 4:37 AM tnsetting @.***> wrote: One question here: If we have a none flyteconsole web app which wants to access flyteadmin, does it require still require a cookie in the header, or we can pass the id/access token in authorization from web app directly which is similar to the grpc one? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#168 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAGUF4SCHSXWFIRUPXMK23TJQIX7ANCNFSM4ZYKG5RA .
-- Thanks, Haytham Abuelfutuh.

@EngHabu Thanks for your reply. I just check a bit about the ID token and access token. In our case we want to use the ID token since the ID token contains user information and we need this information. The other issue with the google access token is that google access token only has two parts and does not comply with JWT token format.

@tnsetting
Copy link
Contributor

@EngHabu Also we want to try this PR out, but is it possible to provide a sample configuration for GCP so we can try it as the config section for auth has been changed a lot? Thanks.

@EngHabu
Copy link
Contributor Author

EngHabu commented Apr 22, 2021

@tnsetting, please checkout the new docs here With an example for Google IdP

auth/config/config.go Outdated Show resolved Hide resolved
auth/config/config.go Outdated Show resolved Hide resolved
}

func getJwksForIssuer(ctx context.Context, issuerBaseURL url.URL) (oidc.KeySet, error) {
u, err := url.Parse(auth.OAuth2MetadataEndpoint)
Copy link
Contributor

Choose a reason for hiding this comment

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

In case of using google as the idp, the link https://accounts.google.com/.well-known/oauth-authorization-server does not exist so the getJwksForIssuer is failing when configured the baseUrl as https://accounts.google.com. Can we fall back to use OIdCMetadataEndpoint when this is failing? So this link does exist https://accounts.google.com/.well-known/openid-configuration

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Google can't be used as the external OAuth2 Authorization Server... their server only protects other Google Endpoints. You can setup/use GCP Identity Platform instead (I do not have instructions for how to do that)...
If you follow the guide here, it takes you through setting up Google Idp just for OpenID Connect while continuing to use FlyteAdmin's own certs to act as the OAuth2 Authorization Server

Copy link
Contributor

Choose a reason for hiding this comment

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

We actually need to use Google as authentication server because of gcloud service accounts. What want to do for authentication is just to verify who is actually who based on ID token. Regarding authorisation, when we know what the user it is we can fetch custom roles from google (it is possible to add custom role) and implement a very thin layer of access control. In this way we don't need have a separate service to store access policies.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's exactly what the guide takes you through... setting up OpenID Connect with Google IdP... have you tried that?
Let's chat over slack (@haytham) and I would be happy to help you debug and get it up and running

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks. I managed to get it running but it required me to make some code changes (hack). I will create a PR for these changes.

return nil, fmt.Errorf("expected exactly one granted audience. found [%v]", len(claims.Audience))
}

if claims.Audience[0] != expectedAudience {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if claims.Audience[0] != expectedAudience {
if !strings.Contains(expectedAudience, claims.Audience[0]) {

It looks the code will always prepend http/https to the url but in our case the audience[0] does not have that prefix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you use as an Authorization Server? Okta? KeyCloak? if so, you can configure them to issue tokens with a specific audience...

EngHabu and others added 16 commits April 26, 2021 16:17
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Prafulla Mahindrakar <prafulla.mahindrakar@gmail.com>

Co-authored-by: Prafulla Mahindrakar <prafulla.mahindrakar@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
yindia and others added 10 commits April 26, 2021 16:17
* wip: added version pkg

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: resolve conflict

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: added version in rpc

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: small fixes

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: Added panic cache in get version service

Signed-off-by: yuvraj <evalsocket@gmail.com>

* Added flytestdlib for version package

Signed-off-by: yuvraj <evalsocket@gmail.com>

* Added version service test

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: added ldflags in goreleaser

Signed-off-by: yuvraj <evalsocket@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
EngHabu added 7 commits April 26, 2021 16:22
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
@EngHabu EngHabu marked this pull request as ready for review April 30, 2021 21:59
@EngHabu EngHabu changed the title wip: OAuth2 Support OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC Apr 30, 2021
@EngHabu EngHabu changed the title OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC #minor Apr 30, 2021
@EngHabu EngHabu changed the title OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC #minor [Breaking] OAuth2 Authorization Server implementation, Separate OpenID and OAuth2 configs, OAuth2 Metadata over gRPC #minor Apr 30, 2021
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
@codecov
Copy link

codecov bot commented Apr 30, 2021

Codecov Report

Merging #168 (03fde57) into master (63b7676) will decrease coverage by 2.14%.
The diff coverage is 34.81%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #168      +/-   ##
==========================================
- Coverage   63.93%   61.79%   -2.15%     
==========================================
  Files         105      120      +15     
  Lines        7353     8087     +734     
==========================================
+ Hits         4701     4997     +296     
- Misses       2072     2463     +391     
- Partials      580      627      +47     
Flag Coverage Δ
unittests 61.79% <34.81%> (-2.15%) ⬇️

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

Impacted Files Coverage Δ
auth/auth_context.go 0.00% <0.00%> (ø)
auth/config/authorizationservertype_enumer.go 0.00% <0.00%> (ø)
auth/config/third_party_config.go 0.00% <0.00%> (ø)
auth/identity_context.go 0.00% <0.00%> (ø)
auth/init_secrets.go 0.00% <0.00%> (ø)
auth/token.go 0.00% <0.00%> (ø)
auth/user_info_provider.go 0.00% <0.00%> (ø)
pkg/config/config.go 14.28% <0.00%> (-2.39%) ⬇️
auth/cookie_manager.go 48.86% <11.11%> (ø)
auth/handlers.go 15.16% <15.16%> (ø)
... and 36 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 63b7676...03fde57. Read the comment docs.

@EngHabu EngHabu merged commit 611a85f into master Apr 30, 2021
eapolinario pushed a commit that referenced this pull request Sep 6, 2023
…D and OAuth2 configs, OAuth2 Metadata over gRPC #minor (#168)

* wip: OAuth2 Support

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* wip

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* wip

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* tighten security of generated tokens

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Support storing form post values in auth code JWT

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* save secrets to k8s secrets

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Expose metadata endpoints over gRPC

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* trim OpenID Connect config further

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Selectively authenticate gRPC endpoints

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Support external oauth2 server and Okta Config

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* update config

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Fix nil secrets data map

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Fixed the pointer overwrite issue in oauthServer metadata (#183)

Signed-off-by: Prafulla Mahindrakar <prafulla.mahindrakar@gmail.com>

Co-authored-by: Prafulla Mahindrakar <prafulla.mahindrakar@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Unit tests

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Unit tests

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Simplify config further and move auth package up

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Fix clusterresource Project and domain(#167)

* Fix clusterresource Project

Signed-off-by: Anand Swaminathan <aswaminathan@lyft.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Bump flyteidl version to pick up auth role field number fix (#169)

Signed-off-by: Katrina Rogan <katroganGH@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Add option to use project name as namespace for the task pods (#166)

* Add option to use project name as namespace for the task pods

Signed-off-by: Jeev B <jeev.balakrishnan@freenome.com>

* rename

Signed-off-by: Jeev B <jeev.balakrishnan@freenome.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* GetExecution performance improvements (#171)

Signed-off-by: Katrina Rogan <katroganGH@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Add exists check for workflow & node executions (#172)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Remove legacy fetch for workflow execution inputs (#173)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Added release workflow (#170)

Signed-off-by: yuvraj <evalsocket@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Update Flyteidl version (#175)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Added version in flyteadmin (#154)

* wip: added version pkg

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: resolve conflict

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: added version in rpc

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: small fixes

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: Added panic cache in get version service

Signed-off-by: yuvraj <evalsocket@gmail.com>

* Added flytestdlib for version package

Signed-off-by: yuvraj <evalsocket@gmail.com>

* Added version service test

Signed-off-by: yuvraj <evalsocket@gmail.com>

* wip: added ldflags in goreleaser

Signed-off-by: yuvraj <evalsocket@gmail.com>
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Propagate nesting and principal for child executions (#177)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Write workflow and node execution events asynchronously (#174)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Add sensible flyteadmin config defaults (#179)

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Lint

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* further cleanup

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Only register authserver when auth is enabled

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Update to latest flyteidl and separate auth interfaces

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* dead code

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* PR Comments

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* merge master

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Move to authorizedUris

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Update to released flyteidl

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Fix response expiry and add unit tests

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* Update go mod

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

* fix unit tests that broke because of identity changes

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>

Co-authored-by: pmahindrakar-oss <77798312+pmahindrakar-oss@users.noreply.github.com>
Co-authored-by: Prafulla Mahindrakar <prafulla.mahindrakar@gmail.com>
Co-authored-by: Anand Swaminathan <aswaminathan@lyft.com>
Co-authored-by: Katrina Rogan <katrina@nuclyde.io>
Co-authored-by: Jeev B <jeevb@users.noreply.github.com>
Co-authored-by: Yuvraj <10830562+evalsocket@users.noreply.github.com>
Co-authored-by: Flyte Bot <admin@flyte.org>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants