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: Optionally override Oauth Cookie Names #3274

Merged
merged 7 commits into from
May 29, 2024
Merged

feat: Optionally override Oauth Cookie Names #3274

merged 7 commits into from
May 29, 2024

Conversation

sam-burrell
Copy link
Contributor

@sam-burrell sam-burrell commented Apr 25, 2024

What type of PR is this?
Added ability to optionally specify a cookieSuffix in the OIDC spec.

What this PR does / why we need it:
This is necessary to link up with the JWT element of the SecurityPolicy to ultimately make passing claimHeaders from the IdToken upstream for authentication in upstream apps clear and easy.

For example it would be used like this

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: grafana-public-test
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: grafana-public-test
  oidc:
    provider:
      issuer: "FOOO"
    clientID: "BAR"
    clientSecret:
      kind: Secret
      name: internal-app-client-secret
    logoutPath: "/logout"
    redirectURL: https://grafana.com/oauth2/callback
    cookieSuffix: "grafana"
    scopes:
      - openid
      - email
  jwt:
    providers:
      - name: "FOO"
        extractFrom:
          cookies:
           - IdToken-grafana
        claimToHeaders:
          - claim: email
            header: X-Email
          - claim: group
            header: X-Group
        remoteJWKS:
          uri: "https://PROVIDER/.well-known/jwks.json"

@sam-burrell sam-burrell requested a review from a team as a code owner April 25, 2024 16:19
@arkodg
Copy link
Contributor

arkodg commented Apr 25, 2024

this makes a lot of sense
cc @mt-inside @zhaohuabing @missBerg

2 open questions

hoping we rely on work done in the past, to influence naming here

@zhaohuabing
Copy link
Member

zhaohuabing commented Apr 25, 2024

I'd vote to keep the current naming, but allow users to specify a custom suffix. We should also provide guidance in the documentation on how to avoid session name conflicts if users opt for this customization.

A preferable approach would be sending the ID token through an 'x-envoy-gateway-id-token' header, thus preventing users from tampering with cookies. This method requires some work(trival) in Envoy upstream."

@sam-burrell
Copy link
Contributor Author

I am happy to do anything else required to move this forward.

Side note - great work with this we are using envoy gateway successfully as our main ingress in our 300 plus service ecs to eks migration.

@zhaohuabing zhaohuabing self-requested a review May 3, 2024 15:54
@zhaohuabing
Copy link
Member

zhaohuabing commented May 3, 2024

should this be a prefix, suffix or the ability to rewrite entire cookie name ?

I'm inclined to add a suffix or rewrite the entire cookie name. The default cookie name has a digest of the policy UID, it's kind of strange to put a random string as a prefix.

@arkodg
Copy link
Contributor

arkodg commented May 3, 2024

should this be a prefix, suffix or the ability to rewrite entire cookie name ?

I'm inclined to add a suffix because the default one is a digest of the policy UID, it's kind of strange to put a random string as a prefix.

should we just allow the user to set the entire name ?

@zhaohuabing
Copy link
Member

zhaohuabing commented May 3, 2024

should this be a prefix, suffix or the ability to rewrite entire cookie name ?

I'm inclined to add a suffix because the default one is a digest of the policy UID, it's kind of strange to put a random string as a prefix.

should we just allow the user to set the entire name ?

Agree, overwriting the entire name is better, users can easily know the cookie name. @sam-burrell

// The optional cookie suffix to be added to Bearer and IdToken cookies in the
// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
// If not specified, uses a randomly generated suffix
CookieSuffix *string `json:"cookieSuffix,omitempty"`
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
CookieSuffix *string `json:"cookieSuffix,omitempty"`
IdTokenCookieName *string `json:"idTokenCookieName,omitempty"`

// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
// If not specified, uses a randomly generated suffix
CookieSuffix *string `json:"cookieSuffix,omitempty"`

Copy link
Contributor

Choose a reason for hiding this comment

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

or even idTokenName

@zhaohuabing
Copy link
Member

@sam-burrell Could you please address @arkodg 's comment? So we can move on this.

@arkodg arkodg added this to the v1.1.0-rc1 milestone May 13, 2024
@zetaab
Copy link
Contributor

zetaab commented May 16, 2024

ping @sam-burrell could you check the review comments

@denniskniep
Copy link
Contributor

Hi,

this feature is very welcome 👍

I propose additionally to @arkodg´s review comment to make all cookie names configurable (and not only idToken cookie):

CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{
BearerToken: fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),
OauthHmac: fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix),
OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix),
},

  • bearerTokenCookieName
  • oauthHmacCookieName
  • oauthExpiresCookieName
  • idTokenCookieName
  • refreshTokenCookieName

@arkodg
Copy link
Contributor

arkodg commented May 20, 2024

Hi,

this feature is very welcome 👍

I propose additionally to @arkodg´s review comment to make all cookie names configurable (and not only idToken cookie):

CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{
BearerToken: fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),
OauthHmac: fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix),
OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix),
},

  • bearerTokenCookieName
  • oauthHmacCookieName
  • oauthExpiresCookieName
  • idTokenCookieName
  • refreshTokenCookieName

if we need to have predictable names for all the cookies then I'd suggest making the struct a little more tiered

cookieName:
  idToken:
  ........

@zhaohuabing
Copy link
Member

zhaohuabing commented May 21, 2024

Hi,

this feature is very welcome 👍

I propose additionally to @arkodg´s review comment to make all cookie names configurable (and not only idToken cookie):

CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{
BearerToken: fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),
OauthHmac: fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix),
OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix),
},

  • bearerTokenCookieName
  • oauthHmacCookieName
  • oauthExpiresCookieName
  • idTokenCookieName
  • refreshTokenCookieName

Exposing BearerTokenCookieName and idTokenCookieName to API makes sense to me, but others should not be in the API as they are trivial details of the Envoy OAuth2 filter implementation.

@denniskniep do you need these cookies somewhere?

sam-burrell and others added 3 commits May 22, 2024 13:55
Signed-off-by: sam-burrell <sam.burrell@gmail.com>
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
Co-authored-by: Sam Burrell <sam.burrell@gmail.com>
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
Co-authored-by: Sam Burrell <sam.burrell@gmail.com>
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
@sam-burrell sam-burrell changed the title feat: added ability to optionally specify a cookieSuffix feat: Optionally override Oauth Cookie Names May 22, 2024
@sam-burrell
Copy link
Contributor Author

@zhaohuabing @arkodg

We have refactored this and now made this the ability to optionally overide oauth cookie names.
Is there anything else we can help with?

Copy link

codecov bot commented May 22, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 67.35%. Comparing base (78fe57a) to head (3d28ef9).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3274      +/-   ##
==========================================
- Coverage   67.36%   67.35%   -0.01%     
==========================================
  Files         167      167              
  Lines       19925    19932       +7     
==========================================
+ Hits        13422    13426       +4     
- Misses       5538     5540       +2     
- Partials      965      966       +1     

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

@denniskniep
Copy link
Contributor

Hi,
this feature is very welcome 👍
I propose additionally to @arkodg´s review comment to make all cookie names configurable (and not only idToken cookie):

CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{
BearerToken: fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),
OauthHmac: fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix),
OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix),
},

  • bearerTokenCookieName
  • oauthHmacCookieName
  • oauthExpiresCookieName
  • idTokenCookieName
  • refreshTokenCookieName

Exposing BearerTokenCookieName and idTokenCookieName to API makes sense to me, but others should not be in the API as they are trivial details of the Envoy OAuth2 filter implementation.

@denniskniep do you need these cookies somewhere?

@zhaohuabing BearerTokenCookieName and idTokenCookieName is sufficient for my current use case

@arkodg
Copy link
Contributor

arkodg commented May 22, 2024

hey this diff looks good !
can we add a test in the gateway-api lib and the xds translator lib to avoid any future regressions ? the make testdata target should help generate the o/p data for you once you've written the input config

Co-authored-by: Sam Burrell <sam.burrell@gmail.com>
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
@coro
Copy link
Contributor

coro commented May 23, 2024

@arkodg Added, thanks!

namespace: envoy-gateway
conditions:
- lastTransitionTime: null
message: HMAC secret envoy-gateway-system/envoy-oidc-hmac not found
Copy link
Contributor

Choose a reason for hiding this comment

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

something is off, Accepted=False, you may have forgotten to include the Secret, the security IR field is also empty

// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
// If not specified, defaults to "BearerToken-(randomly generated uid)"
// +optional
BearerToken *string `json:"bearerToken,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

The name BearerToken is confusing in this context. Let's rename it AccessToken to keep consistent with #3423

Suggested change
BearerToken *string `json:"bearerToken,omitempty"`
AccessToken *string `json:"accessToken,omitempty"`


if oidc.CookieNameOverrides != nil &&
oidc.CookieNameOverrides.BearerToken != nil {
oauth2.Config.Credentials.CookieNames.BearerToken = *oidc.CookieNameOverrides.BearerToken
Copy link
Member

@zhaohuabing zhaohuabing May 24, 2024

Choose a reason for hiding this comment

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

Could you please also change the default name for "BearerTokentoAccessToken` ?

Change

BearerToken:  fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),

To

BearerToken:  fmt.Sprintf("AccessToken-%s", oidc.CookieSuffix)

coro added 2 commits May 24, 2024 10:14
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
Signed-off-by: Connor Rogers <23215294+coro@users.noreply.github.com>
@coro
Copy link
Contributor

coro commented May 28, 2024

@arkodg @zhaohuabing Added your changes, thanks!

Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

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

LGTM thanks !

@arkodg arkodg requested review from zhaohuabing and a team May 28, 2024 20:38
Copy link
Member

@zhaohuabing zhaohuabing left a comment

Choose a reason for hiding this comment

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

LGTM thanks!

@arkodg
Copy link
Contributor

arkodg commented May 28, 2024

@coro can you run make testdata again ? looks like some test o/p changed

@coro
Copy link
Contributor

coro commented May 29, 2024

@arkodg I believe that was unrelated to my change - it seems the example certificate used in that particular test with a diff (internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml) had expired May 24th. I've rebased onto the latest commit and it has resolved that diff.

@arkodg arkodg merged commit 44330ef into envoyproxy:main May 29, 2024
24 of 26 checks passed
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.

6 participants