From a270dd8a34add83b976d2111d0ce9af279715ca6 Mon Sep 17 00:00:00 2001 From: jaynis Date: Thu, 28 Mar 2024 04:53:32 +0100 Subject: [PATCH] feat: added option to specify resources on the OIDC security policy (#3030) added option to specify resources on the OIDC filter Signed-off-by: jaynis Co-authored-by: Huabing Zhao --- api/v1alpha1/oidc_types.go | 5 +++++ api/v1alpha1/zz_generated.deepcopy.go | 5 +++++ .../generated/gateway.envoyproxy.io_securitypolicies.yaml | 6 ++++++ internal/gatewayapi/securitypolicy.go | 1 + .../gatewayapi/testdata/securitypolicy-with-oidc.in.yaml | 1 + .../gatewayapi/testdata/securitypolicy-with-oidc.out.yaml | 4 ++++ internal/ir/xds.go | 4 ++++ internal/ir/zz_generated.deepcopy.go | 5 +++++ internal/xds/translator/oidc.go | 1 + internal/xds/translator/testdata/in/xds-ir/oidc.yaml | 4 ++++ .../xds/translator/testdata/out/xds-ir/oidc.listeners.yaml | 4 ++++ site/content/en/latest/api/extension_types.md | 1 + 12 files changed, 41 insertions(+) diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index 391ea71425b..ecce7957627 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -37,6 +37,11 @@ type OIDC struct { // +optional Scopes []string `json:"scopes,omitempty"` + // The OIDC resources to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // +optional + Resources []string `json:"resources,omitempty"` + // The redirect URL to be used in the OIDC // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). // If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 41a8e22eb72..435d17c07be 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -2502,6 +2502,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.RedirectURL != nil { in, out := &in.RedirectURL, &out.RedirectURL *out = new(string) diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 65df396eb7b..40d0f731550 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -592,6 +592,12 @@ spec: Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" type: string + resources: + description: The OIDC resources to be used in the [Authentication + Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + items: + type: string + type: array scopes: description: The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 0b82fd46926..67bf2314bef 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -644,6 +644,7 @@ func (t *Translator) buildOIDC( ClientID: oidc.ClientID, ClientSecret: clientSecretBytes, Scopes: scopes, + Resources: oidc.Resources, RedirectURL: redirectURL, RedirectPath: redirectPath, LogoutPath: logoutPath, diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml index 31fb6ee9bb8..9ebcd924698 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml @@ -123,5 +123,6 @@ securityPolicies: clientSecret: name: "client2-secret" scopes: ["openid", "email", "profile"] + resources: ["api"] redirectURL: "https://www.example.com/foo/oauth2/callback" logoutPath: "/foo/logout" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index dfd4a9f6073..b0cff9eac83 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -153,6 +153,8 @@ securityPolicies: issuer: https://oauth.foo.com tokenEndpoint: https://oauth.foo.com/token redirectURL: https://www.example.com/foo/oauth2/callback + resources: + - api scopes: - openid - email @@ -263,6 +265,8 @@ xdsIR: tokenEndpoint: https://oauth.foo.com/token redirectPath: /foo/oauth2/callback redirectURL: https://www.example.com/foo/oauth2/callback + resources: + - api scopes: - openid - email diff --git a/internal/ir/xds.go b/internal/ir/xds.go index ae89ed94cd9..86664e59567 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -544,6 +544,10 @@ type OIDC struct { // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). Scopes []string `json:"scopes,omitempty" yaml:"scopes,omitempty"` + // The OIDC resources to be used in the + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"` + // The redirect URL to be used in the OIDC // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). RedirectURL string `json:"redirectURL,omitempty"` diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index e1290759206..b1035316c36 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1388,6 +1388,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC. diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 503d59e5f89..1910da4fb69 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -170,6 +170,7 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) { // every OIDC provider supports basic auth AuthType: oauth2v3.OAuth2Config_BASIC_AUTH, AuthScopes: oidc.Scopes, + Resources: oidc.Resources, }, } return oauth2, nil diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml index fabdbfc9195..e2ef1ca7a0f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml @@ -30,6 +30,8 @@ http: - openid - email - profile + resources: + - api redirectURL: "https://www.example.com/foo/oauth2/callback" redirectPath: "/foo/oauth2/callback" logoutPath: "/foo/logout" @@ -56,6 +58,8 @@ http: - openid - email - profile + resources: + - api redirectURL: "https://www.example.com/bar/oauth2/callback" redirectPath: "/bar/oauth2/callback" logoutPath: "/bar/logout" diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml index 1d7cf7ba34b..95e075f047e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml @@ -48,6 +48,8 @@ path: exact: /foo/oauth2/callback redirectUri: https://www.example.com/foo/oauth2/callback + resources: + - api signoutPath: path: exact: /foo/logout @@ -89,6 +91,8 @@ path: exact: /bar/oauth2/callback redirectUri: https://www.example.com/bar/oauth2/callback + resources: + - api signoutPath: path: exact: /bar/logout diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 9ff59b95a79..7e9839e70da 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1704,6 +1704,7 @@ _Appears in:_ | `clientID` | _string_ | true | The client ID to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the OIDC client secret to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).

This is an Opaque secret. The client secret should be stored in the key "client-secret". | | `scopes` | _string array_ | false | The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The "openid" scope is always added to the list of scopes if not already specified. | +| `resources` | _string array_ | false | The OIDC resources to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `redirectURL` | _string_ | true | The redirect URL to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" | | `logoutPath` | _string_ | true | The path to log a user out, clearing their credential cookies. If not specified, uses a default logout path "/logout" |