mirror of https://github.com/istio/api.git
feat: add spaceDelimitedClaims field to RequestAuthentication API (#3547)
Signed-off-by: Francisco Herrera <fjglira@gmail.com>
This commit is contained in:
parent
4f6a6c5edb
commit
87475465cd
|
|
@ -16360,6 +16360,14 @@ spec:
|
|||
description: This field specifies the header name to output
|
||||
a successfully verified JWT payload to the backend.
|
||||
type: string
|
||||
spaceDelimitedClaims:
|
||||
description: List of JWT claim names that should be treated
|
||||
as space-delimited strings.
|
||||
items:
|
||||
minLength: 1
|
||||
type: string
|
||||
maxItems: 64
|
||||
type: array
|
||||
timeout:
|
||||
description: The maximum amount of time that the resolver, determined
|
||||
by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable,
|
||||
|
|
@ -16641,6 +16649,14 @@ spec:
|
|||
description: This field specifies the header name to output
|
||||
a successfully verified JWT payload to the backend.
|
||||
type: string
|
||||
spaceDelimitedClaims:
|
||||
description: List of JWT claim names that should be treated
|
||||
as space-delimited strings.
|
||||
items:
|
||||
minLength: 1
|
||||
type: string
|
||||
maxItems: 64
|
||||
type: array
|
||||
timeout:
|
||||
description: The maximum amount of time that the resolver, determined
|
||||
by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: release-notes/v2
|
||||
kind: feature
|
||||
area: security
|
||||
issue:
|
||||
- https://github.com/istio/istio/issues/56873
|
||||
|
||||
releaseNotes:
|
||||
- |
|
||||
**Added** `spaceDelimitedClaims` field in `RequestAuthentication` under `spec.jwtRules.` to configure custom JWT claims
|
||||
that should be treated as space-delimited strings.
|
||||
This allows authorization policies to match individual values within space-separated claim strings,
|
||||
extending beyond the default `scope` and `permission` claims.
|
||||
This addresses compatibility issues when upgrading from older Istio versions with custom space-delimited JWT claim fields.
|
||||
|
|
@ -53,6 +53,21 @@ type RequestAuthentication = v1beta1.RequestAuthentication
|
|||
// fromHeaders:
|
||||
// - "x-goog-iap-jwt-assertion"
|
||||
// ```
|
||||
//
|
||||
// This example shows how to configure custom claims to be treated as space-delimited strings.
|
||||
// This is useful when JWT tokens contain custom claims with multiple space-separated values
|
||||
// that should be available for individual matching in authorization policies.
|
||||
//
|
||||
// ```yaml
|
||||
// issuer: https://example.com
|
||||
// spaceDelimitedClaims:
|
||||
// - "custom_scope"
|
||||
// - "provider.login.scope"
|
||||
// - "roles"
|
||||
// ```
|
||||
//
|
||||
// With this configuration, a JWT containing `"custom_scope": "read write admin"` will allow
|
||||
// authorization policies to match against individual values like "read", "write", or "admin".
|
||||
// +kubebuilder:validation:XValidation:message="only one of jwks or jwksUri can be set",rule="oneof(self.jwksUri, self.jwks_uri, self.jwks)"
|
||||
type JWTRule = v1beta1.JWTRule
|
||||
|
||||
|
|
|
|||
|
|
@ -395,6 +395,21 @@ func (x *RequestAuthentication) GetJwtRules() []*JWTRule {
|
|||
// fromHeaders:
|
||||
// - "x-goog-iap-jwt-assertion"
|
||||
// ```
|
||||
//
|
||||
// This example shows how to configure custom claims to be treated as space-delimited strings.
|
||||
// This is useful when JWT tokens contain custom claims with multiple space-separated values
|
||||
// that should be available for individual matching in authorization policies.
|
||||
//
|
||||
// ```yaml
|
||||
// issuer: https://example.com
|
||||
// spaceDelimitedClaims:
|
||||
// - "custom_scope"
|
||||
// - "provider.login.scope"
|
||||
// - "roles"
|
||||
// ```
|
||||
//
|
||||
// With this configuration, a JWT containing `"custom_scope": "read write admin"` will allow
|
||||
// authorization policies to match against individual values like "read", "write", or "admin".
|
||||
// +kubebuilder:validation:XValidation:message="only one of jwks or jwksUri can be set",rule="oneof(self.jwksUri, self.jwks_uri, self.jwks)"
|
||||
type JWTRule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
|
|
@ -512,9 +527,30 @@ type JWTRule struct {
|
|||
OutputClaimToHeaders []*ClaimToHeader `protobuf:"bytes,11,rep,name=output_claim_to_headers,json=outputClaimToHeaders,proto3" json:"output_claim_to_headers,omitempty"` // [TODO:Update the status whenever this feature is promoted.]
|
||||
// The maximum amount of time that the resolver, determined by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable,
|
||||
// will spend waiting for the JWKS to be fetched. Default is 5s.
|
||||
Timeout *duration.Duration `protobuf:"bytes,13,opt,name=timeout,proto3" json:"timeout,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
Timeout *duration.Duration `protobuf:"bytes,13,opt,name=timeout,proto3" json:"timeout,omitempty"`
|
||||
// List of JWT claim names that should be treated as space-delimited strings.
|
||||
// These claims will be split on whitespace and each individual value will be available
|
||||
// for matching in authorization policies. This extends the default behavior that only
|
||||
// treats 'scope' and 'permission' claims as space-delimited.
|
||||
//
|
||||
// Example usage for custom claims:
|
||||
// ```yaml
|
||||
// spaceDelimitedClaims:
|
||||
// - "custom_scope"
|
||||
// - "provider.login.scope"
|
||||
// - "roles"
|
||||
// ```
|
||||
//
|
||||
// This allows authorization policies to match individual values within space-separated
|
||||
// claim strings, maintaining compatibility with existing JWT token formats.
|
||||
//
|
||||
// Note: The default claims 'scope' and 'permission' are always treated as space-delimited
|
||||
// regardless of this setting.
|
||||
// +protoc-gen-crd:list-value-validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxItems=64
|
||||
SpaceDelimitedClaims []string `protobuf:"bytes,14,rep,name=space_delimited_claims,json=spaceDelimitedClaims,proto3" json:"space_delimited_claims,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JWTRule) Reset() {
|
||||
|
|
@ -624,6 +660,13 @@ func (x *JWTRule) GetTimeout() *duration.Duration {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *JWTRule) GetSpaceDelimitedClaims() []string {
|
||||
if x != nil {
|
||||
return x.SpaceDelimitedClaims
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This message specifies a header location to extract JWT token.
|
||||
type JWTHeader struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
|
|
@ -752,7 +795,7 @@ const file_security_v1beta1_request_authentication_proto_rawDesc = "" +
|
|||
"\n" +
|
||||
"targetRefs\x18\x04 \x03(\v2).istio.type.v1beta1.PolicyTargetReferenceR\n" +
|
||||
"targetRefs\x12<\n" +
|
||||
"\tjwt_rules\x18\x02 \x03(\v2\x1f.istio.security.v1beta1.JWTRuleR\bjwtRules\"\xfa\x03\n" +
|
||||
"\tjwt_rules\x18\x02 \x03(\v2\x1f.istio.security.v1beta1.JWTRuleR\bjwtRules\"\xb0\x04\n" +
|
||||
"\aJWTRule\x12\x16\n" +
|
||||
"\x06issuer\x18\x01 \x01(\tR\x06issuer\x12\x1c\n" +
|
||||
"\taudiences\x18\x02 \x03(\tR\taudiences\x12\x19\n" +
|
||||
|
|
@ -766,7 +809,8 @@ const file_security_v1beta1_request_authentication_proto_rawDesc = "" +
|
|||
"\ffrom_cookies\x18\f \x03(\tR\vfromCookies\x124\n" +
|
||||
"\x16forward_original_token\x18\t \x01(\bR\x14forwardOriginalToken\x12\\\n" +
|
||||
"\x17output_claim_to_headers\x18\v \x03(\v2%.istio.security.v1beta1.ClaimToHeaderR\x14outputClaimToHeaders\x123\n" +
|
||||
"\atimeout\x18\r \x01(\v2\x19.google.protobuf.DurationR\atimeout\"=\n" +
|
||||
"\atimeout\x18\r \x01(\v2\x19.google.protobuf.DurationR\atimeout\x124\n" +
|
||||
"\x16space_delimited_claims\x18\x0e \x03(\tR\x14spaceDelimitedClaims\"=\n" +
|
||||
"\tJWTHeader\x12\x18\n" +
|
||||
"\x04name\x18\x01 \x01(\tB\x04\xe2A\x01\x02R\x04name\x12\x16\n" +
|
||||
"\x06prefix\x18\x02 \x01(\tR\x06prefix\"I\n" +
|
||||
|
|
|
|||
|
|
@ -283,6 +283,17 @@ jwksUri: https://example.com/.secret/jwks.json
|
|||
fromHeaders:
|
||||
- "x-goog-iap-jwt-assertion"
|
||||
</code></pre>
|
||||
<p>This example shows how to configure custom claims to be treated as space-delimited strings.
|
||||
This is useful when JWT tokens contain custom claims with multiple space-separated values
|
||||
that should be available for individual matching in authorization policies.</p>
|
||||
<pre><code class="language-yaml">issuer: https://example.com
|
||||
spaceDelimitedClaims:
|
||||
- "custom_scope"
|
||||
- "provider.login.scope"
|
||||
- "roles"
|
||||
</code></pre>
|
||||
<p>With this configuration, a JWT containing <code>"custom_scope": "read write admin"</code> will allow
|
||||
authorization policies to match against individual values like “read”, “write”, or “admin”.</p>
|
||||
|
||||
<table class="message-fields">
|
||||
<thead>
|
||||
|
|
@ -446,6 +457,28 @@ The header specified in each operation in the list must be unique. Nested claims
|
|||
<p>The maximum amount of time that the resolver, determined by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable,
|
||||
will spend waiting for the JWKS to be fetched. Default is 5s.</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="JWTRule-space_delimited_claims">
|
||||
<td><div class="field"><div class="name"><code><a href="#JWTRule-space_delimited_claims">spaceDelimitedClaims</a></code></div>
|
||||
<div class="type">string[]</div>
|
||||
</div></td>
|
||||
<td>
|
||||
<p>List of JWT claim names that should be treated as space-delimited strings.
|
||||
These claims will be split on whitespace and each individual value will be available
|
||||
for matching in authorization policies. This extends the default behavior that only
|
||||
treats ‘scope’ and ‘permission’ claims as space-delimited.</p>
|
||||
<p>Example usage for custom claims:</p>
|
||||
<pre><code class="language-yaml">spaceDelimitedClaims:
|
||||
- "custom_scope"
|
||||
- "provider.login.scope"
|
||||
- "roles"
|
||||
</code></pre>
|
||||
<p>This allows authorization policies to match individual values within space-separated
|
||||
claim strings, maintaining compatibility with existing JWT token formats.</p>
|
||||
<p>Note: The default claims ‘scope’ and ‘permission’ are always treated as space-delimited
|
||||
regardless of this setting.</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -318,6 +318,21 @@ message RequestAuthentication {
|
|||
// fromHeaders:
|
||||
// - "x-goog-iap-jwt-assertion"
|
||||
// ```
|
||||
//
|
||||
// This example shows how to configure custom claims to be treated as space-delimited strings.
|
||||
// This is useful when JWT tokens contain custom claims with multiple space-separated values
|
||||
// that should be available for individual matching in authorization policies.
|
||||
//
|
||||
// ```yaml
|
||||
// issuer: https://example.com
|
||||
// spaceDelimitedClaims:
|
||||
// - "custom_scope"
|
||||
// - "provider.login.scope"
|
||||
// - "roles"
|
||||
// ```
|
||||
//
|
||||
// With this configuration, a JWT containing `"custom_scope": "read write admin"` will allow
|
||||
// authorization policies to match against individual values like "read", "write", or "admin".
|
||||
// +kubebuilder:validation:XValidation:message="only one of jwks or jwksUri can be set",rule="oneof(self.jwksUri, self.jwks_uri, self.jwks)"
|
||||
message JWTRule {
|
||||
// Identifies the issuer that issued the JWT. See
|
||||
|
|
@ -450,8 +465,30 @@ message JWTRule {
|
|||
// will spend waiting for the JWKS to be fetched. Default is 5s.
|
||||
google.protobuf.Duration timeout = 13;
|
||||
|
||||
// List of JWT claim names that should be treated as space-delimited strings.
|
||||
// These claims will be split on whitespace and each individual value will be available
|
||||
// for matching in authorization policies. This extends the default behavior that only
|
||||
// treats 'scope' and 'permission' claims as space-delimited.
|
||||
//
|
||||
// Example usage for custom claims:
|
||||
// ```yaml
|
||||
// spaceDelimitedClaims:
|
||||
// - "custom_scope"
|
||||
// - "provider.login.scope"
|
||||
// - "roles"
|
||||
// ```
|
||||
//
|
||||
// This allows authorization policies to match individual values within space-separated
|
||||
// claim strings, maintaining compatibility with existing JWT token formats.
|
||||
//
|
||||
// Note: The default claims 'scope' and 'permission' are always treated as space-delimited
|
||||
// regardless of this setting.
|
||||
// +protoc-gen-crd:list-value-validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxItems=64
|
||||
repeated string space_delimited_claims = 14;
|
||||
|
||||
// $hide_from_docs
|
||||
// Next available field number: 14
|
||||
// Next available field number: 15
|
||||
}
|
||||
|
||||
// This message specifies a header location to extract JWT token.
|
||||
|
|
|
|||
|
|
@ -210,3 +210,14 @@ spec:
|
|||
- issuer: example
|
||||
timeout: "apple"
|
||||
---
|
||||
_err: 'spaceDelimitedClaims[0] in body should be at least 1 chars long'
|
||||
apiVersion: security.istio.io/v1
|
||||
kind: RequestAuthentication
|
||||
metadata:
|
||||
name: invalid-space-delimited-claims
|
||||
spec:
|
||||
jwtRules:
|
||||
- issuer: example
|
||||
spaceDelimitedClaims:
|
||||
- ""
|
||||
---
|
||||
|
|
|
|||
|
|
@ -20,3 +20,6 @@ spec:
|
|||
header: def
|
||||
timeout: 5s
|
||||
outputPayloadToHeader: header
|
||||
spaceDelimitedClaims:
|
||||
- "custom_scope"
|
||||
- "provider.login.scope"
|
||||
|
|
|
|||
Loading…
Reference in New Issue