From a96c5be367c37607b12a26cb3194b119a1bd15ec Mon Sep 17 00:00:00 2001
From: Sanskar Jaiswal
Date: Thu, 5 Oct 2023 17:25:03 +0530
Subject: [PATCH] cosign: allow identity matching for keyless verification
Add `.spec.verify.matchOIDCIdentity` to OCIRepository and HelmChart.
It allows specifying regular expressions to match against the subject and
issuer of the certificate related to the artifact signature. Its used
only if the artifact was signed using Cosign keyless signing.
Signed-off-by: Sanskar Jaiswal
---
api/v1beta2/ocirepository_types.go | 22 +++
api/v1beta2/zz_generated.deepcopy.go | 20 +++
.../source.toolkit.fluxcd.io_helmcharts.yaml | 26 +++
...rce.toolkit.fluxcd.io_ocirepositories.yaml | 26 +++
docs/api/v1beta2/source.md | 65 ++++++++
internal/controller/helmchart_controller.go | 10 ++
.../controller/helmchart_controller_test.go | 155 ++++++++++++++++++
.../controller/ocirepository_controller.go | 11 ++
.../ocirepository_controller_test.go | 149 +++++++++++++++++
internal/oci/verifier.go | 35 ++--
internal/oci/verifier_test.go | 17 ++
11 files changed, 523 insertions(+), 13 deletions(-)
diff --git a/api/v1beta2/ocirepository_types.go b/api/v1beta2/ocirepository_types.go
index 299f20a52..861003a53 100644
--- a/api/v1beta2/ocirepository_types.go
+++ b/api/v1beta2/ocirepository_types.go
@@ -190,6 +190,28 @@ type OCIRepositoryVerification struct {
// trusted public keys.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
+
+ // MatchOIDCIdentity specifies the identity matching criteria to use
+ // while verifying an OCI artifact which was signed using Cosign keyless
+ // signing. The artifact's identity is deemed to be verified if any of the
+ // specified matchers match against the identity.
+ // +optional
+ MatchOIDCIdentity []OIDCIdentityMatch `json:"matchOIDCIdentity,omitempty"`
+}
+
+// OIDCIdentityMatch specifies options for verifying the certificate identity,
+// i.e. the issuer and the subject of the certificate.
+type OIDCIdentityMatch struct {
+ // Issuer specifies the regex pattern to match against to verify
+ // the OIDC issuer in the Fulcio certificate. The pattern must be a
+ // valid Go regular expression.
+ // +required
+ Issuer string `json:"issuer"`
+ // Subject specifies the regex pattern to match against to verify
+ // the identity subject in the Fulcio certificate. The pattern must
+ // be a valid Go regular expression.
+ // +required
+ Subject string `json:"subject"`
}
// OCIRepositoryStatus defines the observed state of OCIRepository
diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go
index 5c2169a33..e522081f2 100644
--- a/api/v1beta2/zz_generated.deepcopy.go
+++ b/api/v1beta2/zz_generated.deepcopy.go
@@ -834,6 +834,11 @@ func (in *OCIRepositoryVerification) DeepCopyInto(out *OCIRepositoryVerification
*out = new(meta.LocalObjectReference)
**out = **in
}
+ if in.MatchOIDCIdentity != nil {
+ in, out := &in.MatchOIDCIdentity, &out.MatchOIDCIdentity
+ *out = make([]OIDCIdentityMatch, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryVerification.
@@ -845,3 +850,18 @@ func (in *OCIRepositoryVerification) DeepCopy() *OCIRepositoryVerification {
in.DeepCopyInto(out)
return out
}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OIDCIdentityMatch) DeepCopyInto(out *OIDCIdentityMatch) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCIdentityMatch.
+func (in *OIDCIdentityMatch) DeepCopy() *OIDCIdentityMatch {
+ if in == nil {
+ return nil
+ }
+ out := new(OIDCIdentityMatch)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml b/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml
index 9448f29f3..49bdcdd93 100644
--- a/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml
+++ b/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml
@@ -411,6 +411,32 @@ spec:
Chart dependencies, which are not bundled in the umbrella chart
artifact, are not verified.
properties:
+ matchOIDCIdentity:
+ description: MatchOIDCIdentity specifies the identity matching
+ criteria to use while verifying an OCI artifact which was signed
+ using Cosign keyless signing. The artifact's identity is deemed
+ to be verified if any of the specified matchers match against
+ the identity.
+ items:
+ description: OIDCIdentityMatch specifies options for verifying
+ the certificate identity, i.e. the issuer and the subject
+ of the certificate.
+ properties:
+ issuer:
+ description: Issuer specifies the regex pattern to match
+ against to verify the OIDC issuer in the Fulcio certificate.
+ The pattern must be a valid Go regular expression.
+ type: string
+ subject:
+ description: Subject specifies the regex pattern to match
+ against to verify the identity subject in the Fulcio certificate.
+ The pattern must be a valid Go regular expression.
+ type: string
+ required:
+ - issuer
+ - subject
+ type: object
+ type: array
provider:
default: cosign
description: Provider specifies the technology used to sign the
diff --git a/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml b/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml
index df40334a4..b795c8fda 100644
--- a/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml
+++ b/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml
@@ -164,6 +164,32 @@ spec:
public keys used to verify the signature and specifies which provider
to use to check whether OCI image is authentic.
properties:
+ matchOIDCIdentity:
+ description: MatchOIDCIdentity specifies the identity matching
+ criteria to use while verifying an OCI artifact which was signed
+ using Cosign keyless signing. The artifact's identity is deemed
+ to be verified if any of the specified matchers match against
+ the identity.
+ items:
+ description: OIDCIdentityMatch specifies options for verifying
+ the certificate identity, i.e. the issuer and the subject
+ of the certificate.
+ properties:
+ issuer:
+ description: Issuer specifies the regex pattern to match
+ against to verify the OIDC issuer in the Fulcio certificate.
+ The pattern must be a valid Go regular expression.
+ type: string
+ subject:
+ description: Subject specifies the regex pattern to match
+ against to verify the identity subject in the Fulcio certificate.
+ The pattern must be a valid Go regular expression.
+ type: string
+ required:
+ - issuer
+ - subject
+ type: object
+ type: array
provider:
default: cosign
description: Provider specifies the technology used to sign the
diff --git a/docs/api/v1beta2/source.md b/docs/api/v1beta2/source.md
index 3d58db692..31fa0f06b 100644
--- a/docs/api/v1beta2/source.md
+++ b/docs/api/v1beta2/source.md
@@ -3295,6 +3295,71 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
trusted public keys.
+
+
+matchOIDCIdentity
+
+
+[]OIDCIdentityMatch
+
+
+ |
+
+(Optional)
+ MatchOIDCIdentity specifies the identity matching criteria to use
+while verifying an OCI artifact which was signed using Cosign keyless
+signing. The artifact’s identity is deemed to be verified if any of the
+specified matchers match against the identity.
+ |
+
+
+
+
+
+
+
+(Appears on:
+OCIRepositoryVerification)
+
+OIDCIdentityMatch specifies options for verifying the certificate identity,
+i.e. the issuer and the subject of the certificate.
+