Skip to content

Commit 193f5f7

Browse files
authored
oidc: set csrf token expiration (envoyproxy#7188)
* set csrf token expiration Signed-off-by: Huabing Zhao <[email protected]> * support configuring CSRF Token TTL in the API Signed-off-by: Huabing Zhao <[email protected]> --------- Signed-off-by: Huabing Zhao <[email protected]>
1 parent 2aca22e commit 193f5f7

File tree

16 files changed

+86
-0
lines changed

16 files changed

+86
-0
lines changed

api/v1alpha1/oidc_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ type OIDC struct {
130130
// +optional
131131
DefaultRefreshTokenTTL *gwapiv1.Duration `json:"defaultRefreshTokenTTL,omitempty"`
132132

133+
// CSRFTokenTTL defines how long the CSRF token generated during the OAuth2 authorization flow remains valid.
134+
//
135+
// This duration determines the lifetime of the CSRF cookie, which is validated against the CSRF token
136+
// in the "state" parameter when the provider redirects back to the callback endpoint.
137+
//
138+
// If omitted, Envoy Gateway defaults the token expiration to 10 minutes.
139+
//
140+
// +optional
141+
CSRFTokenTTL *gwapiv1.Duration `json:"csrfTokenTTL,omitempty"`
142+
133143
// Disable token encryption. When set to true, both the access token and the ID token will be stored in plain text.
134144
// This option should only be used in secure environments where token encryption is not required.
135145
// Default is false (tokens are encrypted).

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,6 +3958,16 @@ spec:
39583958
If not specified, defaults to "IdToken-(randomly generated uid)"
39593959
type: string
39603960
type: object
3961+
csrfTokenTTL:
3962+
description: |-
3963+
CSRFTokenTTL defines how long the CSRF token generated during the OAuth2 authorization flow remains valid.
3964+
3965+
This duration determines the lifetime of the CSRF cookie, which is validated against the CSRF token
3966+
in the "state" parameter when the provider redirects back to the callback endpoint.
3967+
3968+
If omitted, Envoy Gateway defaults the token expiration to 10 minutes.
3969+
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
3970+
type: string
39613971
defaultRefreshTokenTTL:
39623972
description: |-
39633973
DefaultRefreshTokenTTL is the default lifetime of the refresh token.

charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3957,6 +3957,16 @@ spec:
39573957
If not specified, defaults to "IdToken-(randomly generated uid)"
39583958
type: string
39593959
type: object
3960+
csrfTokenTTL:
3961+
description: |-
3962+
CSRFTokenTTL defines how long the CSRF token generated during the OAuth2 authorization flow remains valid.
3963+
3964+
This duration determines the lifetime of the CSRF cookie, which is validated against the CSRF token
3965+
in the "state" parameter when the provider redirects back to the callback endpoint.
3966+
3967+
If omitted, Envoy Gateway defaults the token expiration to 10 minutes.
3968+
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
3969+
type: string
39603970
defaultRefreshTokenTTL:
39613971
description: |-
39623972
DefaultRefreshTokenTTL is the default lifetime of the refresh token.

internal/gatewayapi/securitypolicy.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,12 +1221,24 @@ func (t *Translator) buildOIDC(
12211221
if oidc.DefaultTokenTTL != nil {
12221222
if d, err := time.ParseDuration(string(*oidc.DefaultTokenTTL)); err == nil {
12231223
irOIDC.DefaultTokenTTL = ir.MetaV1DurationPtr(d)
1224+
} else {
1225+
return nil, fmt.Errorf("invalid defaultTokenTTL: %w", err)
12241226
}
12251227
}
12261228

12271229
if oidc.DefaultRefreshTokenTTL != nil {
12281230
if d, err := time.ParseDuration(string(*oidc.DefaultRefreshTokenTTL)); err == nil {
12291231
irOIDC.DefaultRefreshTokenTTL = ir.MetaV1DurationPtr(d)
1232+
} else {
1233+
return nil, fmt.Errorf("invalid defaultRefreshTokenTTL: %w", err)
1234+
}
1235+
}
1236+
1237+
if oidc.CSRFTokenTTL != nil {
1238+
if d, err := time.ParseDuration(string(*oidc.CSRFTokenTTL)); err == nil {
1239+
irOIDC.CSRFTokenTTL = ir.MetaV1DurationPtr(d)
1240+
} else {
1241+
return nil, fmt.Errorf("invalid csrfTokenTTL: %w", err)
12301242
}
12311243
}
12321244

internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ securityPolicies:
9999
defaultTokenTTL: 30m
100100
refreshToken: true
101101
defaultRefreshTokenTTL: 24h
102+
csrfTokenTTL: 35m
102103
- apiVersion: gateway.envoyproxy.io/v1alpha1
103104
kind: SecurityPolicy
104105
metadata:

internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ securityPolicies:
200200
group: null
201201
kind: null
202202
name: client1-secret
203+
csrfTokenTTL: 35m
203204
defaultRefreshTokenTTL: 24h
204205
defaultTokenTTL: 30m
205206
forwardAccessToken: true
@@ -361,6 +362,7 @@ xdsIR:
361362
clientID: client1.apps.googleusercontent.com
362363
clientSecret: '[redacted]'
363364
cookieSuffix: b0a1b740
365+
csrfTokenTTL: 35m0s
364366
defaultRefreshTokenTTL: 24h0m0s
365367
defaultTokenTTL: 30m0s
366368
forwardAccessToken: true

internal/ir/xds.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,9 @@ type OIDC struct {
11411141
// DefaultRefreshTokenTTL is the default lifetime of the refresh token.
11421142
DefaultRefreshTokenTTL *metav1.Duration `json:"defaultRefreshTokenTTL,omitempty"`
11431143

1144+
// CSRFTokenTTL configures the lifetime of the csrf token Envoy stores in the cookie.
1145+
CSRFTokenTTL *metav1.Duration `json:"csrfTokenTTL,omitempty"`
1146+
11441147
// CookieSuffix will be added to the name of the cookies set by the oauth filter.
11451148
// Adding a suffix avoids multiple oauth filters from overwriting each other's cookies.
11461149
// These cookies are set by the oauth filter, including: AccessToken,

internal/ir/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/xds/translator/oidc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ func oauth2Config(securityFeatures *ir.SecurityFeatures) (*oauth2v3.OAuth2, erro
231231
oauth2.Config.EndSessionEndpoint = *oidc.Provider.EndSessionEndpoint
232232
}
233233

234+
if oidc.CSRFTokenTTL != nil {
235+
oauth2.Config.CsrfTokenExpiresIn = durationpb.New(oidc.CSRFTokenTTL.Duration)
236+
}
237+
234238
return oauth2, nil
235239
}
236240

0 commit comments

Comments
 (0)