diff --git a/kubernetes/customresourcedefinitions.gen.yaml b/kubernetes/customresourcedefinitions.gen.yaml index dcde14a27f..ea6ed09355 100644 --- a/kubernetes/customresourcedefinitions.gen.yaml +++ b/kubernetes/customresourcedefinitions.gen.yaml @@ -17229,6 +17229,10 @@ spec: description: This field specifies the header name to output a successfully verified JWT payload to the backend. type: string + required: + description: If set to true, the JWT token must be present in + the request. + type: boolean spaceDelimitedClaims: description: List of JWT claim names that should be treated as space-delimited strings. @@ -17518,6 +17522,10 @@ spec: description: This field specifies the header name to output a successfully verified JWT payload to the backend. type: string + required: + description: If set to true, the JWT token must be present in + the request. + type: boolean spaceDelimitedClaims: description: List of JWT claim names that should be treated as space-delimited strings. diff --git a/releasenotes/notes/jwt-required-field.yaml b/releasenotes/notes/jwt-required-field.yaml new file mode 100644 index 0000000000..b0191be046 --- /dev/null +++ b/releasenotes/notes/jwt-required-field.yaml @@ -0,0 +1,11 @@ +apiVersion: release-notes/v2 +kind: feature +area: security +issue: + - https://github.com/istio/istio/issues/60823 + +releaseNotes: + - | + **Added** `required` field in `RequestAuthentication` under `spec.jwtRules`. + When set to `true`, the JWT token for that rule must be present and valid. + This allows multiple JWT rules to require all configured tokens simultaneously. Defaults to `false`. diff --git a/security/v1beta1/request_authentication.pb.go b/security/v1beta1/request_authentication.pb.go index 0e3b1d932e..50b85c01fc 100644 --- a/security/v1beta1/request_authentication.pb.go +++ b/security/v1beta1/request_authentication.pb.go @@ -549,8 +549,14 @@ type JWTRule struct { // +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 + // If set to true, the JWT token must be present in the request. Requests + // without this token will be rejected with 401 even if other JWT rules are + // satisfied. When false (the default), a missing token is allowed as long as + // no invalid token is present. This is useful when multiple JWT rules are + // configured and all tokens must be present and valid simultaneously. + Required bool `protobuf:"varint,15,opt,name=required,proto3" json:"required,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *JWTRule) Reset() { @@ -667,6 +673,13 @@ func (x *JWTRule) GetSpaceDelimitedClaims() []string { return nil } +func (x *JWTRule) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + // This message specifies a header location to extract JWT token. type JWTHeader struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -795,7 +808,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\"\xb0\x04\n" + + "\tjwt_rules\x18\x02 \x03(\v2\x1f.istio.security.v1beta1.JWTRuleR\bjwtRules\"\xcc\x04\n" + "\aJWTRule\x12\x16\n" + "\x06issuer\x18\x01 \x01(\tR\x06issuer\x12\x1c\n" + "\taudiences\x18\x02 \x03(\tR\taudiences\x12\x19\n" + @@ -810,7 +823,8 @@ const file_security_v1beta1_request_authentication_proto_rawDesc = "" + "\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\x124\n" + - "\x16space_delimited_claims\x18\x0e \x03(\tR\x14spaceDelimitedClaims\"=\n" + + "\x16space_delimited_claims\x18\x0e \x03(\tR\x14spaceDelimitedClaims\x12\x1a\n" + + "\brequired\x18\x0f \x01(\bR\brequired\"=\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" + diff --git a/security/v1beta1/request_authentication.pb.html b/security/v1beta1/request_authentication.pb.html index 31d08f6a64..d86f2833de 100644 --- a/security/v1beta1/request_authentication.pb.html +++ b/security/v1beta1/request_authentication.pb.html @@ -479,6 +479,19 @@

JWTRule

Note: The default claims ‘scope’ and ‘permission’ are always treated as space-delimited regardless of this setting.

+ + + +
required
+
bool
+
+ +

If set to true, the JWT token must be present in the request. Requests +without this token will be rejected with 401 even if other JWT rules are +satisfied. When false (the default), a missing token is allowed as long as +no invalid token is present. This is useful when multiple JWT rules are +configured and all tokens must be present and valid simultaneously.

+ diff --git a/security/v1beta1/request_authentication.proto b/security/v1beta1/request_authentication.proto index 4bef6a2251..5fc95f1ada 100644 --- a/security/v1beta1/request_authentication.proto +++ b/security/v1beta1/request_authentication.proto @@ -487,8 +487,15 @@ message JWTRule { // +kubebuilder:validation:MaxItems=64 repeated string space_delimited_claims = 14; + // If set to true, the JWT token must be present in the request. Requests + // without this token will be rejected with 401 even if other JWT rules are + // satisfied. When false (the default), a missing token is allowed as long as + // no invalid token is present. This is useful when multiple JWT rules are + // configured and all tokens must be present and valid simultaneously. + bool required = 15; + // $hide_from_docs - // Next available field number: 15 + // Next available field number: 16 } // This message specifies a header location to extract JWT token.