From f238b48245cd9b14866d69d54f66d2c2268cec4b Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 10:56:45 -0400 Subject: [PATCH 01/21] internal: allow multiple SANs in upstream validation Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 10 +++ .../v1/zz_generated.deepcopy.go | 9 ++- .../v1alpha1/zz_generated.deepcopy.go | 2 +- examples/contour/01-crds.yaml | 67 ++++++++++++++++++- examples/render/contour-deployment.yaml | 67 ++++++++++++++++++- .../render/contour-gateway-provisioner.yaml | 67 ++++++++++++++++++- examples/render/contour-gateway.yaml | 67 ++++++++++++++++++- examples/render/contour.yaml | 67 ++++++++++++++++++- internal/dag/cache.go | 2 + internal/dag/dag.go | 19 ++++++ internal/envoy/v3/auth.go | 17 ++--- .../docs/main/config/api-reference.html | 17 ++++- 12 files changed, 394 insertions(+), 17 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index 498be837a8b..a3d35af905e 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1306,6 +1306,7 @@ type HeaderValue struct { } // UpstreamValidation defines how to verify the backend service's certificate +// +kubebuilder:validation:XValidation:message="subjectNames[0] must equal subjectName if set",rule="has(self.subjectNames) ? self.subjectNames[0] == self.subjectName : true" type UpstreamValidation struct { // Name or namespaced name of the Kubernetes secret used to validate the certificate presented by the backend. // The secret must contain key named ca.crt. @@ -1313,7 +1314,16 @@ type UpstreamValidation struct { // When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. CACertificate string `json:"caSecret"` // Key which is expected to be present in the 'subjectAltName' of the presented certificate. + // Deprecated, migrate to using the plural field subjectNames. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256 SubjectName string `json:"subjectName"` + // List of keys, of which at least one is expected to be present in the 'subjectAltName of the + // presented certificate. + // +optional + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=8 + SubjectNames []string `json:"subjectNames"` } // DownstreamValidation defines how to verify the client certificate. diff --git a/apis/projectcontour/v1/zz_generated.deepcopy.go b/apis/projectcontour/v1/zz_generated.deepcopy.go index 3c3537ef24e..3207fef641a 100644 --- a/apis/projectcontour/v1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1/zz_generated.deepcopy.go @@ -919,7 +919,7 @@ func (in *RemoteJWKS) DeepCopyInto(out *RemoteJWKS) { if in.UpstreamValidation != nil { in, out := &in.UpstreamValidation, &out.UpstreamValidation *out = new(UpstreamValidation) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -1155,7 +1155,7 @@ func (in *Service) DeepCopyInto(out *Service) { if in.UpstreamValidation != nil { in, out := &in.UpstreamValidation, &out.UpstreamValidation *out = new(UpstreamValidation) - **out = **in + (*in).DeepCopyInto(*out) } if in.RequestHeadersPolicy != nil { in, out := &in.RequestHeadersPolicy, &out.RequestHeadersPolicy @@ -1434,6 +1434,11 @@ func (in *TimeoutPolicy) DeepCopy() *TimeoutPolicy { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UpstreamValidation) DeepCopyInto(out *UpstreamValidation) { *out = *in + if in.SubjectNames != nil { + in, out := &in.SubjectNames, &out.SubjectNames + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamValidation. diff --git a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go index 1727df16bd9..125d9949fe9 100644 --- a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go @@ -786,7 +786,7 @@ func (in *ExtensionServiceSpec) DeepCopyInto(out *ExtensionServiceSpec) { if in.UpstreamValidation != nil { in, out := &in.UpstreamValidation, &out.UpstreamValidation *out = new(v1.UpstreamValidation) - **out = **in + (*in).DeepCopyInto(*out) } if in.Protocol != nil { in, out := &in.Protocol, &out.Protocol diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 6f3f1f4aa65..89da66c21f5 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5037,12 +5037,27 @@ spec: type: string subjectName: description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. + of the presented certificate. Deprecated, migrate to using the + plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is expected to + be present in the 'subjectAltName of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == self.subjectName + : true' required: - services type: object @@ -6669,11 +6684,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of + the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7064,11 +7095,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of the + presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == + self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7386,11 +7433,29 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field + subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one + is expected to be present in the 'subjectAltName + of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if + set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' required: - uri type: object diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 5acc615ffaa..cf11149781e 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5256,12 +5256,27 @@ spec: type: string subjectName: description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. + of the presented certificate. Deprecated, migrate to using the + plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is expected to + be present in the 'subjectAltName of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == self.subjectName + : true' required: - services type: object @@ -6888,11 +6903,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of + the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7283,11 +7314,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of the + presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == + self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7605,11 +7652,29 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field + subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one + is expected to be present in the 'subjectAltName + of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if + set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' required: - uri type: object diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 526c7b2ba5a..74880d4f708 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5048,12 +5048,27 @@ spec: type: string subjectName: description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. + of the presented certificate. Deprecated, migrate to using the + plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is expected to + be present in the 'subjectAltName of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == self.subjectName + : true' required: - services type: object @@ -6680,11 +6695,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of + the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7075,11 +7106,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of the + presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == + self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7397,11 +7444,29 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field + subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one + is expected to be present in the 'subjectAltName + of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if + set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' required: - uri type: object diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 8b16a4a46a1..59fcbc13f7c 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5259,12 +5259,27 @@ spec: type: string subjectName: description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. + of the presented certificate. Deprecated, migrate to using the + plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is expected to + be present in the 'subjectAltName of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == self.subjectName + : true' required: - services type: object @@ -6891,11 +6906,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of + the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7286,11 +7317,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of the + presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == + self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7608,11 +7655,29 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field + subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one + is expected to be present in the 'subjectAltName + of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if + set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' required: - uri type: object diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index c7dc925b86d..521ba397dd3 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5256,12 +5256,27 @@ spec: type: string subjectName: description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. + of the presented certificate. Deprecated, migrate to using the + plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is expected to + be present in the 'subjectAltName of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == self.subjectName + : true' required: - services type: object @@ -6888,11 +6903,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of + the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7283,11 +7314,27 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one is + expected to be present in the 'subjectAltName of the + presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if set + rule: 'has(self.subjectNames) ? self.subjectNames[0] == + self.subjectName : true' weight: description: Weight defines percentage of traffic to balance traffic @@ -7605,11 +7652,29 @@ spec: subjectName: description: Key which is expected to be present in the 'subjectAltName' of the presented certificate. + Deprecated, migrate to using the plural field + subjectNames. + maxLength: 256 + minLength: 1 type: string + subjectNames: + description: List of keys, of which at least one + is expected to be present in the 'subjectAltName + of the presented certificate. + items: + type: string + maxItems: 8 + minItems: 1 + type: array required: - caSecret - subjectName type: object + x-kubernetes-validations: + - message: subjectNames[0] must equal subjectName if + set + rule: 'has(self.subjectNames) ? self.subjectNames[0] + == self.subjectName : true' required: - uri type: object diff --git a/internal/dag/cache.go b/internal/dag/cache.go index 132df4cf9fd..f64bec50c3d 100644 --- a/internal/dag/cache.go +++ b/internal/dag/cache.go @@ -675,6 +675,7 @@ func (kc *KubernetesCache) LookupUpstreamValidation(uv *contour_api_v1.UpstreamV return nil, fmt.Errorf("invalid CA Secret %q: %s", caCertificate, err) } + // CEL validation should enforce that SubjectName must be set if SubjectNames is used. So, SubjectName will always be present. if uv.SubjectName == "" { // UpstreamValidation is requested, but SAN is not provided return nil, errors.New("missing subject alternative name") @@ -683,6 +684,7 @@ func (kc *KubernetesCache) LookupUpstreamValidation(uv *contour_api_v1.UpstreamV return &PeerValidationContext{ CACertificate: cacert, SubjectName: uv.SubjectName, + SubjectNames: uv.SubjectNames, }, nil } diff --git a/internal/dag/dag.go b/internal/dag/dag.go index e9e5d7e734f..1e9555fc2ff 100644 --- a/internal/dag/dag.go +++ b/internal/dag/dag.go @@ -672,6 +672,9 @@ type PeerValidationContext struct { // SubjectName holds an optional subject name which Envoy will check against the // certificate presented by the upstream. SubjectName string + // SubjectNames holds optional subject names which Envoy will check against the + // certificate presented by the upstream. The first entry must match the value of SubjectName + SubjectNames []string // SkipClientCertValidation when set to true will ensure Envoy requests but // does not verify peer certificates. SkipClientCertValidation bool @@ -704,9 +707,25 @@ func (pvc *PeerValidationContext) GetSubjectName() string { // No validation required. return "" } + return pvc.SubjectName } +// GetSubjectName returns the SubjectNames from PeerValidationContext. +func (pvc *PeerValidationContext) GetSubjectNames() []string { + if pvc == nil { + // No validation required. + return []string{} + } + + // CEL validation should enforce that if SubjectNames is used, the first entry must match the value of SubjectName. + if len(pvc.SubjectNames) > 0 { + return pvc.SubjectNames + } + + return []string{pvc.SubjectName} +} + // GetCRL returns the Certificate Revocation List. func (pvc *PeerValidationContext) GetCRL() []byte { if pvc == nil || pvc.CRL == nil { diff --git a/internal/envoy/v3/auth.go b/internal/envoy/v3/auth.go index 411e9060462..63eb15721ab 100644 --- a/internal/envoy/v3/auth.go +++ b/internal/envoy/v3/auth.go @@ -57,7 +57,7 @@ func UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni st // directly into this field boxes the nil into the unexported // type of this grpc OneOf field which causes proto marshaling // to explode later on. - vc := validationContext(peerValidationContext.GetCACertificate(), peerValidationContext.GetSubjectName(), false, nil, false) + vc := validationContext(peerValidationContext.GetCACertificate(), peerValidationContext.GetSubjectNames(), false, nil, false) if vc != nil { // TODO: update this for SDS (CommonTlsContext_ValidationContextSdsSecretConfig) instead of inlining it. context.CommonTlsContext.ValidationContextType = vc @@ -68,7 +68,7 @@ func UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni st } // TODO: update this for SDS (CommonTlsContext_ValidationContextSdsSecretConfig) instead of inlining it. -func validationContext(ca []byte, subjectName string, skipVerifyPeerCert bool, crl []byte, onlyVerifyLeafCertCrl bool) *envoy_v3_tls.CommonTlsContext_ValidationContext { +func validationContext(ca []byte, subjectNames []string, skipVerifyPeerCert bool, crl []byte, onlyVerifyLeafCertCrl bool) *envoy_v3_tls.CommonTlsContext_ValidationContext { vc := &envoy_v3_tls.CommonTlsContext_ValidationContext{ ValidationContext: &envoy_v3_tls.CertificateValidationContext{ TrustChainVerification: envoy_v3_tls.CertificateValidationContext_VERIFY_TRUST_CHAIN, @@ -87,17 +87,18 @@ func validationContext(ca []byte, subjectName string, skipVerifyPeerCert bool, c } } - if len(subjectName) > 0 { - vc.ValidationContext.MatchTypedSubjectAltNames = []*envoy_v3_tls.SubjectAltNameMatcher{ - { + for _, san := range subjectNames { + vc.ValidationContext.MatchTypedSubjectAltNames = append( + vc.ValidationContext.MatchTypedSubjectAltNames, + &envoy_v3_tls.SubjectAltNameMatcher{ SanType: envoy_v3_tls.SubjectAltNameMatcher_DNS, Matcher: &matcher.StringMatcher{ MatchPattern: &matcher.StringMatcher_Exact{ - Exact: subjectName, + Exact: san, }, }, }, - } + ) } if len(crl) > 0 { @@ -129,7 +130,7 @@ func DownstreamTLSContext(serverSecret *dag.Secret, tlsMinProtoVersion, tlsMaxPr }, } if peerValidationContext != nil { - vc := validationContext(peerValidationContext.GetCACertificate(), "", peerValidationContext.SkipClientCertValidation, + vc := validationContext(peerValidationContext.GetCACertificate(), []string{}, peerValidationContext.SkipClientCertValidation, peerValidationContext.GetCRL(), peerValidationContext.OnlyVerifyLeafCertCrl) if vc != nil { context.CommonTlsContext.ValidationContextType = vc diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index a78277849ba..2d6522e6937 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -4706,7 +4706,22 @@

UpstreamValidation -

Key which is expected to be present in the ‘subjectAltName’ of the presented certificate.

+

Key which is expected to be present in the ‘subjectAltName’ of the presented certificate. +Deprecated, migrate to using the plural field subjectNames.

+ + + + +subjectNames +
+ +[]string + + + +(Optional) +

List of keys, of which at least one is expected to be present in the ‘subjectAltName of the +presented certificate.

From bb9143819d179346dcd72b5e53b8f8d1e13368c2 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 11:55:18 -0400 Subject: [PATCH 02/21] docs: add changelog Signed-off-by: Clay Kauzlaric --- changelogs/unreleased/5849-KauzClay-minor.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/unreleased/5849-KauzClay-minor.md diff --git a/changelogs/unreleased/5849-KauzClay-minor.md b/changelogs/unreleased/5849-KauzClay-minor.md new file mode 100644 index 00000000000..70aa93d3e3a --- /dev/null +++ b/changelogs/unreleased/5849-KauzClay-minor.md @@ -0,0 +1,3 @@ +## Allow Multiple SANs in Upstream Validation section of HTTPProxy + +Allow multiple SANs in Upstream Validation by adding a new field `subjectNames` to the UpstreamValidtion block. This will exist side by side with the previous `subjectName` field. Using CEL validation, we can enforce that when both are present, the first entry in `subjectNames` must match the value of `subjectName`. \ No newline at end of file From 55d8ca08db374912b2f8bb62873aeb7783b568b7 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 14:24:27 -0400 Subject: [PATCH 03/21] api: fix deprecated comment Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index a3d35af905e..3f9975113be 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1314,7 +1314,7 @@ type UpstreamValidation struct { // When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. CACertificate string `json:"caSecret"` // Key which is expected to be present in the 'subjectAltName' of the presented certificate. - // Deprecated, migrate to using the plural field subjectNames. + // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=256 SubjectName string `json:"subjectName"` From ea42eb2f29899b5b99b6a2740e7868e7179b1387 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 17:22:50 -0400 Subject: [PATCH 04/21] update generated code Signed-off-by: Clay Kauzlaric --- examples/contour/01-crds.yaml | 26 +++++++++---------- examples/render/contour-deployment.yaml | 26 +++++++++---------- .../render/contour-gateway-provisioner.yaml | 26 +++++++++---------- examples/render/contour-gateway.yaml | 26 +++++++++---------- examples/render/contour.yaml | 26 +++++++++---------- .../docs/main/config/api-reference.html | 2 +- 6 files changed, 66 insertions(+), 66 deletions(-) diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 89da66c21f5..fbb50e29572 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5036,9 +5036,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. Deprecated, migrate to using the - plural field subjectNames. + description: 'Key which is expected to be present in the ''subjectAltName'' + of the presented certificate. Deprecated: migrate to using the + plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -6682,9 +6682,9 @@ spec: secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7093,9 +7093,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present in + the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7431,10 +7431,10 @@ spec: the secret. type: string subjectName: - description: Key which is expected to be present - in the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field - subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field + subjectNames.' maxLength: 256 minLength: 1 type: string diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index cf11149781e..eee52ab615a 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5255,9 +5255,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. Deprecated, migrate to using the - plural field subjectNames. + description: 'Key which is expected to be present in the ''subjectAltName'' + of the presented certificate. Deprecated: migrate to using the + plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -6901,9 +6901,9 @@ spec: secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7312,9 +7312,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present in + the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7650,10 +7650,10 @@ spec: the secret. type: string subjectName: - description: Key which is expected to be present - in the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field - subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field + subjectNames.' maxLength: 256 minLength: 1 type: string diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 74880d4f708..422f33fffa2 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5047,9 +5047,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. Deprecated, migrate to using the - plural field subjectNames. + description: 'Key which is expected to be present in the ''subjectAltName'' + of the presented certificate. Deprecated: migrate to using the + plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -6693,9 +6693,9 @@ spec: secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7104,9 +7104,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present in + the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7442,10 +7442,10 @@ spec: the secret. type: string subjectName: - description: Key which is expected to be present - in the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field - subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field + subjectNames.' maxLength: 256 minLength: 1 type: string diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 59fcbc13f7c..65d89fa3ba9 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5258,9 +5258,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. Deprecated, migrate to using the - plural field subjectNames. + description: 'Key which is expected to be present in the ''subjectAltName'' + of the presented certificate. Deprecated: migrate to using the + plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -6904,9 +6904,9 @@ spec: secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7315,9 +7315,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present in + the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7653,10 +7653,10 @@ spec: the secret. type: string subjectName: - description: Key which is expected to be present - in the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field - subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field + subjectNames.' maxLength: 256 minLength: 1 type: string diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 521ba397dd3..08e5c5a45d2 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5255,9 +5255,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in the 'subjectAltName' - of the presented certificate. Deprecated, migrate to using the - plural field subjectNames. + description: 'Key which is expected to be present in the ''subjectAltName'' + of the presented certificate. Deprecated: migrate to using the + plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -6901,9 +6901,9 @@ spec: secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7312,9 +7312,9 @@ spec: in the namespace to grant access to the secret. type: string subjectName: - description: Key which is expected to be present in - the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field subjectNames. + description: 'Key which is expected to be present in + the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field subjectNames.' maxLength: 256 minLength: 1 type: string @@ -7650,10 +7650,10 @@ spec: the secret. type: string subjectName: - description: Key which is expected to be present - in the 'subjectAltName' of the presented certificate. - Deprecated, migrate to using the plural field - subjectNames. + description: 'Key which is expected to be present + in the ''subjectAltName'' of the presented certificate. + Deprecated: migrate to using the plural field + subjectNames.' maxLength: 256 minLength: 1 type: string diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index 2d6522e6937..39c08bd0822 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -4707,7 +4707,7 @@

UpstreamValidation

Key which is expected to be present in the ‘subjectAltName’ of the presented certificate. -Deprecated, migrate to using the plural field subjectNames.

+Deprecated: migrate to using the plural field subjectNames.

From 75efa449b1990aba59829e9b25a60a2af2c8bdc7 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 17:31:09 -0400 Subject: [PATCH 05/21] add deprecation changelog Signed-off-by: Clay Kauzlaric --- changelogs/unreleased/5849-KauzClay-deprecation.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelogs/unreleased/5849-KauzClay-deprecation.md diff --git a/changelogs/unreleased/5849-KauzClay-deprecation.md b/changelogs/unreleased/5849-KauzClay-deprecation.md new file mode 100644 index 00000000000..c4266be7d80 --- /dev/null +++ b/changelogs/unreleased/5849-KauzClay-deprecation.md @@ -0,0 +1,6 @@ +## Deprecate `subjectName` field on UpstreamValidation + +The `subjectName` field is being deprecated in favor of `subjectNames`, which is +an list of subjectNames. `subjectName` will continue to behave as it has. If +using `subjectNames`, the first entry in `subjectNames` must match the value of +`subjectName`. this will be enforced by CEL validation. \ No newline at end of file From 6d855ec84f9842ef27853ba7781151f19f3d71d8 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 13 Oct 2023 17:45:00 -0400 Subject: [PATCH 06/21] internal: add happypath test for multiple sans on upstream tls context Signed-off-by: Clay Kauzlaric --- internal/envoy/v3/auth_test.go | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/internal/envoy/v3/auth_test.go b/internal/envoy/v3/auth_test.go index 43987273b44..39121fd423b 100644 --- a/internal/envoy/v3/auth_test.go +++ b/internal/envoy/v3/auth_test.go @@ -123,6 +123,47 @@ func TestUpstreamTLSContext(t *testing.T) { }, }, }, + "multiple subjectnames": { + validation: &dag.PeerValidationContext{ + CACertificate: secret, + SubjectName: "foo.com", + SubjectNames: []string{ + "foo.com", + "bar.com", + }, + }, + want: &envoy_v3_tls.UpstreamTlsContext{ + CommonTlsContext: &envoy_v3_tls.CommonTlsContext{ + ValidationContextType: &envoy_v3_tls.CommonTlsContext_ValidationContext{ + ValidationContext: &envoy_v3_tls.CertificateValidationContext{ + TrustedCa: &envoy_api_v3_core.DataSource{ + Specifier: &envoy_api_v3_core.DataSource_InlineBytes{ + InlineBytes: []byte("ca"), + }, + }, + MatchTypedSubjectAltNames: []*envoy_v3_tls.SubjectAltNameMatcher{ + { + SanType: envoy_v3_tls.SubjectAltNameMatcher_DNS, + Matcher: &matcher.StringMatcher{ + MatchPattern: &matcher.StringMatcher_Exact{ + Exact: "foo.com", + }, + }, + }, + { + SanType: envoy_v3_tls.SubjectAltNameMatcher_DNS, + Matcher: &matcher.StringMatcher{ + MatchPattern: &matcher.StringMatcher_Exact{ + Exact: "bar.com", + }, + }, + }, + }, + }, + }, + }, + }, + }, } for name, tc := range tests { From b716c6b804e5deed6c97de003d6c9768c3a7a76e Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 17 Nov 2023 12:34:06 -0500 Subject: [PATCH 07/21] add limitations to all fields in upstream validation Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index 3f9975113be..e6bb66d9ec3 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1312,6 +1312,8 @@ type UpstreamValidation struct { // The secret must contain key named ca.crt. // The name can be optionally prefixed with namespace "namespace/name". // When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256 CACertificate string `json:"caSecret"` // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. From 455aee2e567acea378b4070563c64b2b0a442370 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 17 Nov 2023 12:34:37 -0500 Subject: [PATCH 08/21] update examples Signed-off-by: Clay Kauzlaric --- examples/contour/01-crds.yaml | 8 ++++++++ examples/render/contour-deployment.yaml | 8 ++++++++ examples/render/contour-gateway-provisioner.yaml | 8 ++++++++ examples/render/contour-gateway.yaml | 8 ++++++++ examples/render/contour.yaml | 8 ++++++++ 5 files changed, 40 insertions(+) diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index fbb50e29572..5aba883ad2e 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5034,6 +5034,8 @@ spec: prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' @@ -6680,6 +6682,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present @@ -7091,6 +7095,8 @@ spec: "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in @@ -7429,6 +7435,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index eee52ab615a..15614e3517e 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5253,6 +5253,8 @@ spec: prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' @@ -6899,6 +6901,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present @@ -7310,6 +7314,8 @@ spec: "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in @@ -7648,6 +7654,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 422f33fffa2..62c54cb6103 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5045,6 +5045,8 @@ spec: prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' @@ -6691,6 +6693,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present @@ -7102,6 +7106,8 @@ spec: "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in @@ -7440,6 +7446,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 65d89fa3ba9..e98215a92be 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5256,6 +5256,8 @@ spec: prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' @@ -6902,6 +6904,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present @@ -7313,6 +7317,8 @@ spec: "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in @@ -7651,6 +7657,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 08e5c5a45d2..83e0a38e4c0 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5253,6 +5253,8 @@ spec: prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' @@ -6899,6 +6901,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present @@ -7310,6 +7314,8 @@ spec: "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present in @@ -7648,6 +7654,8 @@ spec: reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + maxLength: 256 + minLength: 1 type: string subjectName: description: 'Key which is expected to be present From 457ff9cf2e7b7b3215fa501ccd3064fc388305c4 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 15 Dec 2023 16:58:42 -0500 Subject: [PATCH 09/21] api: limit length of subject name to 100 in upstream validation * allows the CEL validation rule to get a passing score Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 +- examples/contour/01-crds.yaml | 8 ++++---- examples/render/contour-deployment.yaml | 8 ++++---- examples/render/contour-gateway-provisioner.yaml | 8 ++++---- examples/render/contour-gateway.yaml | 8 ++++---- examples/render/contour.yaml | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index e6bb66d9ec3..d8a563b5af5 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1318,7 +1318,7 @@ type UpstreamValidation struct { // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:MaxLength=100 SubjectName string `json:"subjectName"` // List of keys, of which at least one is expected to be present in the 'subjectAltName of the // presented certificate. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 5aba883ad2e..5412590594b 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5041,7 +5041,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -6689,7 +6689,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7102,7 +7102,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7443,7 +7443,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 15614e3517e..49102165ba1 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5260,7 +5260,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -6908,7 +6908,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7321,7 +7321,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7662,7 +7662,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 62c54cb6103..191324282dc 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5052,7 +5052,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -6700,7 +6700,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7113,7 +7113,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7454,7 +7454,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index e98215a92be..62f47ae90fa 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5263,7 +5263,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7324,7 +7324,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7665,7 +7665,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 83e0a38e4c0..4e119a7ddcb 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5260,7 +5260,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -6908,7 +6908,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7321,7 +7321,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: @@ -7662,7 +7662,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 100 minLength: 1 type: string subjectNames: From a3ac00b15381a7a3ed384275bd0ad07f8d557d09 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Tue, 2 Jan 2024 16:29:46 -0500 Subject: [PATCH 10/21] docs: update changelog to call out new limit Signed-off-by: Clay Kauzlaric --- changelogs/unreleased/5849-KauzClay-minor.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/unreleased/5849-KauzClay-minor.md b/changelogs/unreleased/5849-KauzClay-minor.md index 70aa93d3e3a..7cb42336e7b 100644 --- a/changelogs/unreleased/5849-KauzClay-minor.md +++ b/changelogs/unreleased/5849-KauzClay-minor.md @@ -1,3 +1,5 @@ ## Allow Multiple SANs in Upstream Validation section of HTTPProxy +This change introduces a max length of 100 characters to the field `subjectName` in the UpstreamValidation block. + Allow multiple SANs in Upstream Validation by adding a new field `subjectNames` to the UpstreamValidtion block. This will exist side by side with the previous `subjectName` field. Using CEL validation, we can enforce that when both are present, the first entry in `subjectNames` must match the value of `subjectName`. \ No newline at end of file From fdf5c362b9592cda2d2bff95ff46895a75375131 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 16:40:42 -0500 Subject: [PATCH 11/21] docs: update upstream tls docs * include reference to deprecation and new field Signed-off-by: Clay Kauzlaric --- site/content/docs/main/config/upstream-tls.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/site/content/docs/main/config/upstream-tls.md b/site/content/docs/main/config/upstream-tls.md index 72c83062391..29b02a2f419 100644 --- a/site/content/docs/main/config/upstream-tls.md +++ b/site/content/docs/main/config/upstream-tls.md @@ -5,7 +5,11 @@ Applying the `projectcontour.io/upstream-protocol.tls` annotation to a Service o The same configuration can be specified by setting the protocol name in the `spec.routes.services[].protocol` field on the HTTPProxy object. If both the annotation and the protocol field are specified, the protocol field takes precedence. By default, the upstream TLS server certificate will not be validated, but validation can be requested by setting the `spec.routes.services[].validation` field. -This field has mandatory `caSecret` and `subjectName` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name. +This field has mandatory `caSecret`, `subjectName`, and `subjectNames` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name(s). + +_**Note:** +The `subjectName` field is deprecated in favor of `subjectNames`. When using `subjectNames`, the first entry must match the value for `subjectName`. The `subjectName` field also has a limit of TODO(KauzClay) characters._ + The `caSecret` can be a namespaced name of the form `/`. If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][4] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. _**Note:** @@ -60,7 +64,10 @@ Status: ## Upstream Validation When defining upstream services on a route, it's possible to configure the connection from Envoy to the backend endpoint to communicate over TLS. -Two configuration items are required, a CA certificate and a `SubjectName` which are both used to verify the backend endpoint's identity. + +A CA certificate and a Subject Name must be provided, which are both used to verify the backend endpoint's identity. + +If specifying multiple Subject Names, `SubjectNames` and `SubjectName` must be configured such that `SubjectNames[0] == SubjectName`. The CA certificate bundle for the backend service should be supplied in a Kubernetes Secret. The referenced Secret must be of type "Opaque" and have a data key named `ca.crt`. @@ -84,6 +91,9 @@ spec: validation: caSecret: foo-ca-cert subjectName: foo.marketing + subjectNames: + - foo.marketing + - bar.marketing ``` ## Envoy Client Certificate From 9e833257299a81d4ed6083f19f0e5366d765f067 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 16:42:13 -0500 Subject: [PATCH 12/21] increase length limits * for cacert and subjectname Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 5 +-- examples/contour/01-crds.yaml | 31 ++++++++++++------- examples/render/contour-deployment.yaml | 31 ++++++++++++------- .../render/contour-gateway-provisioner.yaml | 31 ++++++++++++------- examples/render/contour-gateway.yaml | 31 ++++++++++++------- examples/render/contour.yaml | 31 ++++++++++++------- .../docs/main/config/api-reference.html | 3 +- 7 files changed, 100 insertions(+), 63 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index d8a563b5af5..a42a5f11a71 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1312,13 +1312,14 @@ type UpstreamValidation struct { // The secret must contain key named ca.crt. // The name can be optionally prefixed with namespace "namespace/name". // When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. + // Max length should be the actual max possible length of a namespaced name (63 + 253 + 1 = 317) // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:MaxLength=317 CACertificate string `json:"caSecret"` // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=100 + // +kubebuilder:validation:MaxLength=150 SubjectName string `json:"subjectName"` // List of keys, of which at least one is expected to be present in the 'subjectAltName of the // presented certificate. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 5412590594b..6eb759169dd 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5033,15 +5033,17 @@ spec: secret must contain key named ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max length should + be the actual max possible length of a namespaced name (63 + + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -6681,15 +6683,16 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the - secret. - maxLength: 256 + secret. Max length should be the actual max possible + length of a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7094,15 +7097,17 @@ spec: ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max + length should be the actual max possible length of + a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7434,8 +7439,10 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to - the secret. - maxLength: 256 + the secret. Max length should be the actual max + possible length of a namespaced name (63 + 253 + + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: @@ -7443,7 +7450,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 49102165ba1..5b22b9beee4 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5252,15 +5252,17 @@ spec: secret must contain key named ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max length should + be the actual max possible length of a namespaced name (63 + + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -6900,15 +6902,16 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the - secret. - maxLength: 256 + secret. Max length should be the actual max possible + length of a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7313,15 +7316,17 @@ spec: ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max + length should be the actual max possible length of + a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7653,8 +7658,10 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to - the secret. - maxLength: 256 + the secret. Max length should be the actual max + possible length of a namespaced name (63 + 253 + + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: @@ -7662,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 191324282dc..1cda92e387e 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5044,15 +5044,17 @@ spec: secret must contain key named ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max length should + be the actual max possible length of a namespaced name (63 + + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -6692,15 +6694,16 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the - secret. - maxLength: 256 + secret. Max length should be the actual max possible + length of a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7105,15 +7108,17 @@ spec: ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max + length should be the actual max possible length of + a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7445,8 +7450,10 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to - the secret. - maxLength: 256 + the secret. Max length should be the actual max + possible length of a namespaced name (63 + 253 + + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: @@ -7454,7 +7461,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 62f47ae90fa..bbbb370be9d 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5255,15 +5255,17 @@ spec: secret must contain key named ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max length should + be the actual max possible length of a namespaced name (63 + + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -6903,15 +6905,16 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the - secret. - maxLength: 256 + secret. Max length should be the actual max possible + length of a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7316,15 +7319,17 @@ spec: ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max + length should be the actual max possible length of + a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7656,8 +7661,10 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to - the secret. - maxLength: 256 + the secret. Max length should be the actual max + possible length of a namespaced name (63 + 253 + + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: @@ -7665,7 +7672,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 4e119a7ddcb..2a3b78ba35c 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5252,15 +5252,17 @@ spec: secret must contain key named ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max length should + be the actual max possible length of a namespaced name (63 + + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -6900,15 +6902,16 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the - secret. - maxLength: 256 + secret. Max length should be the actual max possible + length of a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7313,15 +7316,17 @@ spec: ca.crt. The name can be optionally prefixed with namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist - in the namespace to grant access to the secret. - maxLength: 256 + in the namespace to grant access to the secret. Max + length should be the actual max possible length of + a namespaced name (63 + 253 + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: @@ -7653,8 +7658,10 @@ spec: namespace "namespace/name". When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to - the secret. - maxLength: 256 + the secret. Max length should be the actual max + possible length of a namespaced name (63 + 253 + + 1 = 317) + maxLength: 317 minLength: 1 type: string subjectName: @@ -7662,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 100 + maxLength: 150 minLength: 1 type: string subjectNames: diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index 39c08bd0822..76babb39d14 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -4694,7 +4694,8 @@

UpstreamValidation

Name or namespaced name of the Kubernetes secret used to validate the certificate presented by the backend. The secret must contain key named ca.crt. The name can be optionally prefixed with namespace “namespace/name”. -When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. +Max length should be the actual max possible length of a namespaced name (63 + 253 + 1 = 317)

From 4cb1fc28f3b4b37fe80fe690d7566fdd3af17d46 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 17:14:57 -0500 Subject: [PATCH 13/21] increase subjectname max length Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 +- examples/contour/01-crds.yaml | 8 ++++---- examples/render/contour-deployment.yaml | 8 ++++---- examples/render/contour-gateway-provisioner.yaml | 8 ++++---- examples/render/contour-gateway.yaml | 8 ++++---- examples/render/contour.yaml | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index a42a5f11a71..b55313dcfc7 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1319,7 +1319,7 @@ type UpstreamValidation struct { // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=150 + // +kubebuilder:validation:MaxLength=256 SubjectName string `json:"subjectName"` // List of keys, of which at least one is expected to be present in the 'subjectAltName of the // presented certificate. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 6eb759169dd..b6e5230a2c0 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5043,7 +5043,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -6692,7 +6692,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7107,7 +7107,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7450,7 +7450,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 5b22b9beee4..24b44b7012f 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 1cda92e387e..a2229646bb2 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5054,7 +5054,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -6703,7 +6703,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7118,7 +7118,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7461,7 +7461,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index bbbb370be9d..37ad283d7f9 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5265,7 +5265,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -6914,7 +6914,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7329,7 +7329,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7672,7 +7672,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 2a3b78ba35c..74e2cee4bb5 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 150 + maxLength: 256 minLength: 1 type: string subjectNames: From dad53b35d6140d2dafb338645bcace6beee51535 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 17:24:39 -0500 Subject: [PATCH 14/21] decrease subjectname max length Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 +- examples/contour/01-crds.yaml | 8 ++++---- examples/render/contour-deployment.yaml | 8 ++++---- examples/render/contour-gateway-provisioner.yaml | 8 ++++---- examples/render/contour-gateway.yaml | 8 ++++---- examples/render/contour.yaml | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index b55313dcfc7..fdce51b5ce4 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1319,7 +1319,7 @@ type UpstreamValidation struct { // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:MaxLength=200 SubjectName string `json:"subjectName"` // List of keys, of which at least one is expected to be present in the 'subjectAltName of the // presented certificate. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index b6e5230a2c0..741b15140d5 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5043,7 +5043,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -6692,7 +6692,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7107,7 +7107,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7450,7 +7450,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 24b44b7012f..5f239aa94c0 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index a2229646bb2..4733f4199f1 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5054,7 +5054,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -6703,7 +6703,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7118,7 +7118,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7461,7 +7461,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index 37ad283d7f9..e8c64c044d2 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5265,7 +5265,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -6914,7 +6914,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7329,7 +7329,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7672,7 +7672,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 74e2cee4bb5..0e3b329e525 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 256 + maxLength: 200 minLength: 1 type: string subjectNames: From b998cc16ad2c8624259ae206296522375211dc0a Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 17:40:54 -0500 Subject: [PATCH 15/21] increase max length again, but not as high Signed-off-by: Clay Kauzlaric --- apis/projectcontour/v1/httpproxy.go | 2 +- examples/contour/01-crds.yaml | 8 ++++---- examples/render/contour-deployment.yaml | 8 ++++---- examples/render/contour-gateway-provisioner.yaml | 8 ++++---- examples/render/contour-gateway.yaml | 8 ++++---- examples/render/contour.yaml | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index fdce51b5ce4..107c44ca4e9 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -1319,7 +1319,7 @@ type UpstreamValidation struct { // Key which is expected to be present in the 'subjectAltName' of the presented certificate. // Deprecated: migrate to using the plural field subjectNames. // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=200 + // +kubebuilder:validation:MaxLength=250 SubjectName string `json:"subjectName"` // List of keys, of which at least one is expected to be present in the 'subjectAltName of the // presented certificate. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 741b15140d5..1e4531f61fb 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -5043,7 +5043,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -6692,7 +6692,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7107,7 +7107,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7450,7 +7450,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 5f239aa94c0..f605afb88f6 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 4733f4199f1..b812326a588 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -5054,7 +5054,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -6703,7 +6703,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7118,7 +7118,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7461,7 +7461,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index e8c64c044d2..fde77fce0fc 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -5265,7 +5265,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -6914,7 +6914,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7329,7 +7329,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7672,7 +7672,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 0e3b329e525..37ce84b15e0 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -5262,7 +5262,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -6911,7 +6911,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7326,7 +7326,7 @@ spec: description: 'Key which is expected to be present in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: @@ -7669,7 +7669,7 @@ spec: in the ''subjectAltName'' of the presented certificate. Deprecated: migrate to using the plural field subjectNames.' - maxLength: 200 + maxLength: 250 minLength: 1 type: string subjectNames: From 319c8c68d5c552641733d396f8300b10e1115cf6 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Thu, 4 Jan 2024 17:54:02 -0500 Subject: [PATCH 16/21] dag: consolidate into subjectNames * only use SubjectNames in dag, take SubjectName and make single item slice when present Signed-off-by: Clay Kauzlaric --- internal/dag/builder_test.go | 6 ++--- internal/dag/cache.go | 19 +++++++++++----- internal/dag/cache_test.go | 1 + internal/dag/dag.go | 22 ++----------------- internal/dag/dag_test.go | 8 +++---- internal/dag/extension_processor.go | 2 +- internal/envoy/cluster.go | 2 +- internal/envoy/v3/auth.go | 2 +- internal/envoy/v3/auth_test.go | 5 ++--- internal/envoy/v3/cluster_test.go | 14 ++++++------ internal/envoy/v3/listener_test.go | 4 ++-- .../featuretests/v3/backendclientauth_test.go | 2 +- internal/featuretests/v3/envoy.go | 2 +- 13 files changed, 39 insertions(+), 50 deletions(-) diff --git a/internal/dag/builder_test.go b/internal/dag/builder_test.go index fb4b435059c..d123ac923a4 100644 --- a/internal/dag/builder_test.go +++ b/internal/dag/builder_test.go @@ -11347,7 +11347,7 @@ func TestDAGInsert(t *testing.T) { Protocol: "tls", UpstreamValidation: &PeerValidationContext{ CACertificate: caSecret(cert1), - SubjectName: "example.com", + SubjectNames: []string{"example.com"}, }, }, ), @@ -11380,7 +11380,7 @@ func TestDAGInsert(t *testing.T) { Protocol: "h2", UpstreamValidation: &PeerValidationContext{ CACertificate: caSecret(cert1), - SubjectName: "example.com", + SubjectNames: []string{"example.com"}, }, }, ), @@ -11455,7 +11455,7 @@ func TestDAGInsert(t *testing.T) { Protocol: "tls", UpstreamValidation: &PeerValidationContext{ CACertificate: caSecret(cert2), - SubjectName: "example.com", + SubjectNames: []string{"example.com"}, }, }, ), diff --git a/internal/dag/cache.go b/internal/dag/cache.go index f64bec50c3d..1256dbd7dfa 100644 --- a/internal/dag/cache.go +++ b/internal/dag/cache.go @@ -667,6 +667,8 @@ func (kc *KubernetesCache) LookupUpstreamValidation(uv *contour_api_v1.UpstreamV return nil, nil } + pvc := &PeerValidationContext{} + cacert, err := kc.LookupCASecret(caCertificate, targetNamespace) if err != nil { if _, ok := err.(DelegationNotPermittedError); ok { @@ -674,18 +676,23 @@ func (kc *KubernetesCache) LookupUpstreamValidation(uv *contour_api_v1.UpstreamV } return nil, fmt.Errorf("invalid CA Secret %q: %s", caCertificate, err) } + pvc.CACertificate = cacert // CEL validation should enforce that SubjectName must be set if SubjectNames is used. So, SubjectName will always be present. if uv.SubjectName == "" { - // UpstreamValidation is requested, but SAN is not provided return nil, errors.New("missing subject alternative name") } - return &PeerValidationContext{ - CACertificate: cacert, - SubjectName: uv.SubjectName, - SubjectNames: uv.SubjectNames, - }, nil + switch l := len(uv.SubjectNames); { + case l == 0: + // UpstreamValidation was using old SubjectName field only, can internally move that into SubjectNames + pvc.SubjectNames = []string{uv.SubjectName} + case l > 0: + // UpstreamValidation is using new SubjectNames field, can use it directly. CEL validation should enforce that SubjectName is contained in SubjectNames + pvc.SubjectNames = uv.SubjectNames + } + + return pvc, nil } // LookupTLSSecretInsecure returns Secret with TLS certificate and private key from cache. diff --git a/internal/dag/cache_test.go b/internal/dag/cache_test.go index 540885c17ba..24227826558 100644 --- a/internal/dag/cache_test.go +++ b/internal/dag/cache_test.go @@ -36,6 +36,7 @@ import ( gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" ) +// TODO(KauzClay): test that lookup peervalidation works func TestKubernetesCacheInsert(t *testing.T) { tests := map[string]struct { cacheGateway *types.NamespacedName diff --git a/internal/dag/dag.go b/internal/dag/dag.go index 1e9555fc2ff..987bbaabb2c 100644 --- a/internal/dag/dag.go +++ b/internal/dag/dag.go @@ -669,9 +669,6 @@ type PeerValidationContext struct { // CACertificate holds a reference to the Secret containing the CA to be used to // verify the upstream connection. CACertificate *Secret - // SubjectName holds an optional subject name which Envoy will check against the - // certificate presented by the upstream. - SubjectName string // SubjectNames holds optional subject names which Envoy will check against the // certificate presented by the upstream. The first entry must match the value of SubjectName SubjectNames []string @@ -701,29 +698,14 @@ func (pvc *PeerValidationContext) GetCACertificate() []byte { return pvc.CACertificate.Object.Data[CACertificateKey] } -// GetSubjectName returns the SubjectName from PeerValidationContext. -func (pvc *PeerValidationContext) GetSubjectName() string { - if pvc == nil { - // No validation required. - return "" - } - - return pvc.SubjectName -} - // GetSubjectName returns the SubjectNames from PeerValidationContext. func (pvc *PeerValidationContext) GetSubjectNames() []string { if pvc == nil { // No validation required. - return []string{} - } - - // CEL validation should enforce that if SubjectNames is used, the first entry must match the value of SubjectName. - if len(pvc.SubjectNames) > 0 { - return pvc.SubjectNames + return nil } - return []string{pvc.SubjectName} + return pvc.SubjectNames } // GetCRL returns the Certificate Revocation List. diff --git a/internal/dag/dag_test.go b/internal/dag/dag_test.go index a7ee4def4b9..72d4aca5a48 100644 --- a/internal/dag/dag_test.go +++ b/internal/dag/dag_test.go @@ -84,16 +84,16 @@ func TestPeerValidationContext(t *testing.T) { }, }, }, - SubjectName: "subject", + SubjectNames: []string{"subject"}, } pvc2 := PeerValidationContext{} var pvc3 *PeerValidationContext - assert.Equal(t, pvc1.GetSubjectName(), "subject") + assert.Equal(t, pvc1.GetSubjectNames()[0], "subject") assert.Equal(t, pvc1.GetCACertificate(), []byte("cacert")) - assert.Equal(t, pvc2.GetSubjectName(), "") + assert.Equal(t, pvc2.GetSubjectNames(), nil) assert.Equal(t, pvc2.GetCACertificate(), []byte(nil)) - assert.Equal(t, pvc3.GetSubjectName(), "") + assert.Equal(t, pvc3.GetSubjectNames(), nil) assert.Equal(t, pvc3.GetCACertificate(), []byte(nil)) } diff --git a/internal/dag/extension_processor.go b/internal/dag/extension_processor.go index 0f97cb12713..1ccd293662e 100644 --- a/internal/dag/extension_processor.go +++ b/internal/dag/extension_processor.go @@ -174,7 +174,7 @@ func (p *ExtensionServiceProcessor) buildExtensionService( // future. // // TODO(jpeach): expose SNI in the API, https://github.com/projectcontour/contour/issues/2893. - extension.SNI = uv.SubjectName + extension.SNI = uv.SubjectNames[0] if extension.Protocol != "h2" { validCondition.AddErrorf(contour_api_v1.ConditionTypeSpecError, "InconsistentProtocol", diff --git a/internal/envoy/cluster.go b/internal/envoy/cluster.go index e6d4bf94fbe..7d5218df95a 100644 --- a/internal/envoy/cluster.go +++ b/internal/envoy/cluster.go @@ -48,7 +48,7 @@ func Clustername(cluster *dag.Cluster) string { } if uv := cluster.UpstreamValidation; uv != nil { buf += uv.CACertificate.Object.ObjectMeta.Name - buf += uv.SubjectName + buf += uv.SubjectNames[0] } buf += cluster.Protocol + cluster.SNI if !cluster.TimeoutPolicy.IdleConnectionTimeout.UseDefault() { diff --git a/internal/envoy/v3/auth.go b/internal/envoy/v3/auth.go index 63eb15721ab..de8d188c40c 100644 --- a/internal/envoy/v3/auth.go +++ b/internal/envoy/v3/auth.go @@ -50,7 +50,7 @@ func UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni st } } - if peerValidationContext.GetCACertificate() != nil && len(peerValidationContext.GetSubjectName()) > 0 { + if peerValidationContext.GetCACertificate() != nil && len(peerValidationContext.GetSubjectNames()) > 0 { // We have to explicitly assign the value from validationContext // to context.CommonTlsContext.ValidationContextType because the // latter is an interface. Returning nil from validationContext diff --git a/internal/envoy/v3/auth_test.go b/internal/envoy/v3/auth_test.go index 39121fd423b..6ddd906a61e 100644 --- a/internal/envoy/v3/auth_test.go +++ b/internal/envoy/v3/auth_test.go @@ -67,7 +67,7 @@ func TestUpstreamTLSContext(t *testing.T) { }, "no alpn, missing ca": { validation: &dag.PeerValidationContext{ - SubjectName: "www.example.com", + SubjectNames: []string{"www.example.com"}, }, want: &envoy_v3_tls.UpstreamTlsContext{ CommonTlsContext: &envoy_v3_tls.CommonTlsContext{}, @@ -76,7 +76,7 @@ func TestUpstreamTLSContext(t *testing.T) { "no alpn, ca and altname": { validation: &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "www.example.com", + SubjectNames: []string{"www.example.com"}, }, want: &envoy_v3_tls.UpstreamTlsContext{ CommonTlsContext: &envoy_v3_tls.CommonTlsContext{ @@ -126,7 +126,6 @@ func TestUpstreamTLSContext(t *testing.T) { "multiple subjectnames": { validation: &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "foo.com", SubjectNames: []string{ "foo.com", "bar.com", diff --git a/internal/envoy/v3/cluster_test.go b/internal/envoy/v3/cluster_test.go index 92d2593bdc8..58ce5ec3eb2 100644 --- a/internal/envoy/v3/cluster_test.go +++ b/internal/envoy/v3/cluster_test.go @@ -300,7 +300,7 @@ func TestCluster(t *testing.T) { Protocol: "tls", UpstreamValidation: &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "foo.bar.io", + SubjectNames: []string{"foo.bar.io"}, }, }, want: &envoy_cluster_v3.Cluster{ @@ -315,7 +315,7 @@ func TestCluster(t *testing.T) { UpstreamTLSContext( &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "foo.bar.io", + SubjectNames: []string{"foo.bar.io"}, }, "", nil, @@ -329,7 +329,7 @@ func TestCluster(t *testing.T) { Protocol: "tls", UpstreamValidation: &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "foo.bar.io", + SubjectNames: []string{"foo.bar.io"}, }, UpstreamTLS: &dag.UpstreamTLS{ MinimumProtocolVersion: "1.3", @@ -348,7 +348,7 @@ func TestCluster(t *testing.T) { UpstreamTLSContext( &dag.PeerValidationContext{ CACertificate: secret, - SubjectName: "foo.bar.io", + SubjectNames: []string{"foo.bar.io"}, }, "", nil, @@ -909,7 +909,7 @@ func TestDNSNameCluster(t *testing.T) { }, }, }, - SubjectName: "foo.projectcontour.io", + SubjectNames: []string{"foo.projectcontour.io"}, }, }, want: &envoy_cluster_v3.Cluster{ @@ -940,7 +940,7 @@ func TestDNSNameCluster(t *testing.T) { }, }, }, - SubjectName: "foo.projectcontour.io", + SubjectNames: []string{"foo.projectcontour.io"}, }, "foo.projectcontour.io", nil, nil)), }, }, @@ -1071,7 +1071,7 @@ func TestClustername(t *testing.T) { }, }, }, - SubjectName: "foo.com", + SubjectNames: []string{"foo.com"}, }, } diff --git a/internal/envoy/v3/listener_test.go b/internal/envoy/v3/listener_test.go index 023ef43f149..c8bfa83e28f 100644 --- a/internal/envoy/v3/listener_test.go +++ b/internal/envoy/v3/listener_test.go @@ -241,7 +241,7 @@ func TestSocketAddress(t *testing.T) { } func TestDownstreamTLSContext(t *testing.T) { - const subjectName = "client-subject-name" + subjectNames := []string{"client-subject-name"} ca := []byte("client-ca-cert") crl := []byte("crl-data") @@ -328,7 +328,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, }, - SubjectName: subjectName, + SubjectNames: subjectNames, } peerValidationContextSkipClientCertValidation := &dag.PeerValidationContext{ diff --git a/internal/featuretests/v3/backendclientauth_test.go b/internal/featuretests/v3/backendclientauth_test.go index b686c676de7..0cbe4d28e90 100644 --- a/internal/featuretests/v3/backendclientauth_test.go +++ b/internal/featuretests/v3/backendclientauth_test.go @@ -211,7 +211,7 @@ func TestBackendClientAuthenticationWithExtensionService(t *testing.T) { Type: "kubernetes.io/tls", Data: map[string][]byte{dag.CACertificateKey: []byte(featuretests.CERTIFICATE)}, }}, - SubjectName: "subjname"}, + SubjectNames: []string{"subjname"}}, "subjname", &dag.Secret{Object: sec1}, nil, diff --git a/internal/featuretests/v3/envoy.go b/internal/featuretests/v3/envoy.go index cf0a0814b71..139a8c18803 100644 --- a/internal/featuretests/v3/envoy.go +++ b/internal/featuretests/v3/envoy.go @@ -201,7 +201,7 @@ func tlsCluster(c *envoy_cluster_v3.Cluster, ca []byte, subjectName string, sni Type: "kubernetes.io/tls", Data: map[string][]byte{dag.CACertificateKey: ca}, }}, - SubjectName: subjectName}, + SubjectNames: []string{subjectName}}, sni, secret, upstreamTLS, From 4ec72ee646ad890ef836a696e6c417f6ddba9a57 Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 5 Jan 2024 10:03:39 -0500 Subject: [PATCH 17/21] dag: fix test Signed-off-by: Clay Kauzlaric --- internal/dag/dag_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/dag/dag_test.go b/internal/dag/dag_test.go index 72d4aca5a48..bb7e1ed5015 100644 --- a/internal/dag/dag_test.go +++ b/internal/dag/dag_test.go @@ -91,9 +91,9 @@ func TestPeerValidationContext(t *testing.T) { assert.Equal(t, pvc1.GetSubjectNames()[0], "subject") assert.Equal(t, pvc1.GetCACertificate(), []byte("cacert")) - assert.Equal(t, pvc2.GetSubjectNames(), nil) + assert.Equal(t, pvc2.GetSubjectNames(), []string(nil)) assert.Equal(t, pvc2.GetCACertificate(), []byte(nil)) - assert.Equal(t, pvc3.GetSubjectNames(), nil) + assert.Equal(t, pvc3.GetSubjectNames(), []string(nil)) assert.Equal(t, pvc3.GetCACertificate(), []byte(nil)) } From 6b2bf2284679ef3cce29a6ab5e444566ec2cae8d Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 5 Jan 2024 13:08:14 -0500 Subject: [PATCH 18/21] dag: test lookupupstreamvalidation Signed-off-by: Clay Kauzlaric --- internal/dag/cache.go | 3 ++ internal/dag/cache_test.go | 94 +++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/internal/dag/cache.go b/internal/dag/cache.go index 1256dbd7dfa..21f2bdaa7a4 100644 --- a/internal/dag/cache.go +++ b/internal/dag/cache.go @@ -689,6 +689,9 @@ func (kc *KubernetesCache) LookupUpstreamValidation(uv *contour_api_v1.UpstreamV pvc.SubjectNames = []string{uv.SubjectName} case l > 0: // UpstreamValidation is using new SubjectNames field, can use it directly. CEL validation should enforce that SubjectName is contained in SubjectNames + if uv.SubjectName != uv.SubjectNames[0] { + return nil, fmt.Errorf("first entry of SubjectNames (%s) does not match SubjectName (%s)", uv.SubjectNames[0], uv.SubjectName) + } pvc.SubjectNames = uv.SubjectNames } diff --git a/internal/dag/cache_test.go b/internal/dag/cache_test.go index 24227826558..f01fa4c680b 100644 --- a/internal/dag/cache_test.go +++ b/internal/dag/cache_test.go @@ -36,7 +36,6 @@ import ( gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" ) -// TODO(KauzClay): test that lookup peervalidation works func TestKubernetesCacheInsert(t *testing.T) { tests := map[string]struct { cacheGateway *types.NamespacedName @@ -2648,3 +2647,96 @@ func TestRouteTriggersRebuild(t *testing.T) { }) } } + +func TestLookupUpstreamValidation(t *testing.T) { + cache := func(objs ...any) *KubernetesCache { + cache := KubernetesCache{ + FieldLogger: fixture.NewTestLogger(t), + } + for _, o := range objs { + cache.Insert(o) + } + return &cache + } + + uv := func(subjectName string, subjectNames []string) *contour_api_v1.UpstreamValidation { + return &contour_api_v1.UpstreamValidation{ + CACertificate: "ca", + SubjectName: subjectName, + SubjectNames: subjectNames, + } + } + + secret := func() *v1.Secret { + return &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ca", + Namespace: "default", + }, + Type: v1.SecretTypeOpaque, + Data: map[string][]byte{ + CACertificateKey: []byte(fixture.CERTIFICATE), + }, + } + } + + pvc := func(subjectNames []string) *PeerValidationContext { + return &PeerValidationContext{ + CACertificate: &Secret{ + Object: secret(), + ValidCASecret: &SecretValidationStatus{}, + }, + SubjectNames: subjectNames, + } + } + + tests := map[string]struct { + cache *KubernetesCache + meta types.NamespacedName + uv *contour_api_v1.UpstreamValidation + wantPvc *PeerValidationContext + wantErr error + }{ + "contains both SubjectName and SubjectNames correctly": { + cache: cache(secret()), + uv: uv("example.com", []string{"example.com", "extra.com"}), + meta: types.NamespacedName{Namespace: "default", Name: "ca"}, + wantPvc: pvc([]string{"example.com", "extra.com"}), + }, + "SubjectName does not match SubjectNames[0]": { + cache: cache(secret()), + uv: uv("example.com", []string{"wrong.com", "extra.com"}), + meta: types.NamespacedName{Namespace: "default", Name: "ca"}, + wantPvc: pvc([]string{"example.com", "extra.com"}), + wantErr: errors.New("first entry of SubjectNames (wrong.com) does not match SubjectName (example.com)"), + }, + "SubjectName missing": { + cache: cache(secret()), + uv: uv("", []string{"wrong.com", "extra.com"}), + meta: types.NamespacedName{Namespace: "default", Name: "ca"}, + wantPvc: pvc([]string{"example.com", "extra.com"}), + wantErr: errors.New("missing subject alternative name"), + }, + "SubjectNames missing": { + cache: cache(secret()), + uv: uv("example.com", []string{}), + meta: types.NamespacedName{Namespace: "default", Name: "ca"}, + wantPvc: pvc([]string{"example.com"}), + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + gotPvc, gotErr := tc.cache.LookupUpstreamValidation(tc.uv, tc.meta, "default") + + switch { + case tc.wantErr != nil: + require.Error(t, gotErr) + assert.EqualError(t, tc.wantErr, gotErr.Error()) + default: + assert.Nil(t, gotErr) + assert.Equal(t, tc.wantPvc, gotPvc) + } + }) + } +} From 7fe2cf5d0e04c05171ba9a0ecf49dba089a55fed Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 5 Jan 2024 13:08:29 -0500 Subject: [PATCH 19/21] docs: remove todo Signed-off-by: Clay Kauzlaric --- site/content/docs/main/config/upstream-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/docs/main/config/upstream-tls.md b/site/content/docs/main/config/upstream-tls.md index 29b02a2f419..aeade7fdd76 100644 --- a/site/content/docs/main/config/upstream-tls.md +++ b/site/content/docs/main/config/upstream-tls.md @@ -8,7 +8,7 @@ By default, the upstream TLS server certificate will not be validated, but valid This field has mandatory `caSecret`, `subjectName`, and `subjectNames` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name(s). _**Note:** -The `subjectName` field is deprecated in favor of `subjectNames`. When using `subjectNames`, the first entry must match the value for `subjectName`. The `subjectName` field also has a limit of TODO(KauzClay) characters._ +The `subjectName` field is deprecated in favor of `subjectNames`. When using `subjectNames`, the first entry must match the value for `subjectName`. The `subjectName` field also has a limit of 250 characters._ The `caSecret` can be a namespaced name of the form `/`. If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][4] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. From 4714e6fc95a05ec6654e7a184707446b1f91554c Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 5 Jan 2024 13:08:44 -0500 Subject: [PATCH 20/21] docs: correct changelog Signed-off-by: Clay Kauzlaric --- changelogs/unreleased/5849-KauzClay-minor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/5849-KauzClay-minor.md b/changelogs/unreleased/5849-KauzClay-minor.md index 7cb42336e7b..afa791c072b 100644 --- a/changelogs/unreleased/5849-KauzClay-minor.md +++ b/changelogs/unreleased/5849-KauzClay-minor.md @@ -1,5 +1,5 @@ ## Allow Multiple SANs in Upstream Validation section of HTTPProxy -This change introduces a max length of 100 characters to the field `subjectName` in the UpstreamValidation block. +This change introduces a max length of 250 characters to the field `subjectName` in the UpstreamValidation block. Allow multiple SANs in Upstream Validation by adding a new field `subjectNames` to the UpstreamValidtion block. This will exist side by side with the previous `subjectName` field. Using CEL validation, we can enforce that when both are present, the first entry in `subjectNames` must match the value of `subjectName`. \ No newline at end of file From b2914796971ea27f34ec263249a34208cb2aa88d Mon Sep 17 00:00:00 2001 From: Clay Kauzlaric Date: Fri, 5 Jan 2024 15:42:01 -0500 Subject: [PATCH 21/21] test: add cel validation e2e test Signed-off-by: Clay Kauzlaric --- test/e2e/httpproxy/cel_validation_test.go | 69 +++++++++++++++++++++++ test/e2e/httpproxy/httpproxy_test.go | 2 + 2 files changed, 71 insertions(+) create mode 100644 test/e2e/httpproxy/cel_validation_test.go diff --git a/test/e2e/httpproxy/cel_validation_test.go b/test/e2e/httpproxy/cel_validation_test.go new file mode 100644 index 00000000000..584af6017bf --- /dev/null +++ b/test/e2e/httpproxy/cel_validation_test.go @@ -0,0 +1,69 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e + +package httpproxy + +import ( + "context" + "strings" + + . "github.com/onsi/ginkgo/v2" + contourv1 "github.com/projectcontour/contour/apis/projectcontour/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func testCELValidation(namespace string) { + Specify("UpstreamValidation is validated by CEL rule on creation", func() { + t := f.T() + + subjectNameNoMatch := &contourv1.HTTPProxy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: "subjectname-no-match", + }, + Spec: contourv1.HTTPProxySpec{ + VirtualHost: &contourv1.VirtualHost{ + Fqdn: "example.com", + }, + Routes: []contourv1.Route{ + { + Services: []contourv1.Service{ + { + Name: "any-service-name", + Port: 80000, + UpstreamValidation: &contourv1.UpstreamValidation{ + CACertificate: "namespace/name", + SubjectNames: []string{"wrong.com", "example.com"}, + SubjectName: "example.com", + }, + }, + }, + }, + }, + }, + } + + err := f.Client.Create(context.TODO(), subjectNameNoMatch) + require.Error(t, err) + + isExpectedErr := func(err error) bool { + return strings.Contains(err.Error(), "subjectNames[0] must equal subjectName if set") + } + assert.True(t, isExpectedErr(err)) + + }) +} diff --git a/test/e2e/httpproxy/httpproxy_test.go b/test/e2e/httpproxy/httpproxy_test.go index c59dd17b18a..be030dfb3a0 100644 --- a/test/e2e/httpproxy/httpproxy_test.go +++ b/test/e2e/httpproxy/httpproxy_test.go @@ -60,6 +60,8 @@ var _ = AfterSuite(func() { var _ = Describe("HTTPProxy API validation", func() { f.NamespacedTest("httpproxy-required-field-validation", testRequiredFieldValidation) + f.NamespacedTest("httpproxy-cel-validation", testCELValidation) + f.NamespacedTest("httpproxy-invalid-wildcard-fqdn", testWildcardFQDN) f.NamespacedTest("invalid-cookie-rewrite-fields", testInvalidCookieRewriteFields)