1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

Image verify attestors (#3614)

* fix logs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix logs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* support multiple attestors

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* rm CLI tests (not currently supported)

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* apply attestor repo

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix linter issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix entryError assignment

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* format

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add intermediary certs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
Jim Bugwadia 2022-04-19 08:35:12 -07:00 committed by GitHub
parent 1cfc80d32a
commit 3b1a1acd9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1260 additions and 318 deletions

View file

@ -58,10 +58,12 @@ type ImageVerification struct {
// Annotations are used for image verification.
// Every specified key-value pair must exist and match in the verified payload.
// The payload may contain other key-value pairs.
// Deprecated. Use annotations per Attestor instead.
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
// Repository is an optional alternate OCI repository to use for image signatures that match this rule.
// Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule.
// If specified Repository will override the default OCI image repository configured for the installation.
// The repository can also be overridden per Attestor or Attestation.
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
}
@ -93,8 +95,16 @@ type Attestor struct {
// Attestor is a nested AttestorSet used to specify a more complex set of match authorities
// +kubebuilder:validation:Optional
// TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.
Attestors []*apiextv1.JSON `json:"attestors,omitempty" yaml:"attestors,omitempty"`
Attestor *apiextv1.JSON `json:"attestor,omitempty" yaml:"attestor,omitempty"`
// Annotations are used for image verification.
// Every specified key-value pair must exist and match in the verified payload.
// The payload may contain other key-value pairs.
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
// Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule.
// If specified Repository will override other OCI image repository locations for this Attestor.
Repository string `json:"repository,omitempty" yaml:"repository,omitempty"`
}
type StaticKeyAttestor struct {
@ -103,6 +113,17 @@ type StaticKeyAttestor struct {
// specified or can be a variable reference to a key specified in a ConfigMap (see
// https://kyverno.io/docs/writing-policies/variables/).
Key string `json:"key,omitempty" yaml:"key,omitempty"`
// Intermediates is an optional PEM encoded set of certificates that are not trust
// anchors, but can be used to form a chain from the leaf certificate to a
// root certificate.
// +kubebuilder:validation:Optional
Intermediates string `json:"intermediates,omitempty" yaml:"intermediates,omitempty"`
// Roots is an optional set of PEM encoded trusted root certificates.
// If not provided, the system roots are used.
// +kubebuilder:validation:Optional
Roots string `json:"roots,omitempty" yaml:"roots,omitempty"`
}
type KeylessAttestor struct {
@ -115,7 +136,14 @@ type KeylessAttestor struct {
// +kubebuilder:validation:Required
Subject string `json:"subject,omitempty" yaml:"subject,omitempty"`
// Roots is a PEM encoded CA certificate chain
// Intermediates is an optional PEM encoded set of certificates that are not trust
// anchors, but can be used to form a chain from the leaf certificate to a
// root certificate.
// +kubebuilder:validation:Optional
Intermediates string `json:"intermediates,omitempty" yaml:"intermediates,omitempty"`
// Roots is an optional set of PEM encoded trusted root certificates.
// If not provided, the system roots are used.
// +kubebuilder:validation:Optional
Roots string `json:"roots,omitempty" yaml:"roots,omitempty"`
@ -202,10 +230,10 @@ func validateAttestorSet(as *AttestorSet, path *field.Path) (errs field.ErrorLis
}
func (a *Attestor) Validate(path *field.Path) (errs field.ErrorList) {
if (a.StaticKey != nil && (a.Keyless != nil || len(a.Attestors) != 0)) ||
(a.Keyless != nil && (a.StaticKey != nil || len(a.Attestors) != 0)) ||
(len(a.Attestors) > 0 && (a.StaticKey != nil || a.Keyless != nil)) ||
(a.StaticKey == nil && a.Keyless == nil && len(a.Attestors) == 0) {
if (a.StaticKey != nil && (a.Keyless != nil || a.Attestor != nil)) ||
(a.Keyless != nil && (a.StaticKey != nil || a.Attestor != nil)) ||
(a.Attestor != nil && (a.StaticKey != nil || a.Keyless != nil)) ||
(a.StaticKey == nil && a.Keyless == nil && a.Attestor == nil) {
errs = append(errs, field.Invalid(path, a, "One of static key, keyless, or nested attestor is required"))
}
@ -221,17 +249,16 @@ func (a *Attestor) Validate(path *field.Path) (errs field.ErrorList) {
errs = append(errs, keylessErrors...)
}
attestorsPath := path.Child("attestors")
for i, rawJson := range a.Attestors {
attestorSet, err := AttestorSetUnmarshal(rawJson)
if a.Attestor != nil {
attestorPath := path.Child("attestor")
attestorSet, err := AttestorSetUnmarshal(a.Attestor)
if err != nil {
fieldErr := field.Invalid(attestorsPath.Index(i), rawJson, err.Error())
fieldErr := field.Invalid(attestorPath, a.Attestor, err.Error())
errs = append(errs, fieldErr)
continue
} else {
attestorErrors := validateAttestorSet(attestorSet, attestorPath)
errs = append(errs, attestorErrors...)
}
attestorErrors := validateAttestorSet(attestorSet, attestorsPath.Index(i))
errs = append(errs, attestorErrors...)
}
return errs
@ -278,7 +305,10 @@ func (iv *ImageVerification) Convert() *ImageVerification {
copy.ImageReferences = []string{iv.Image}
}
var attestor Attestor
attestor := &Attestor{
Annotations: iv.Annotations,
}
if iv.Key != "" {
attestor.StaticKey = &StaticKeyAttestor{
Key: iv.Key,
@ -292,7 +322,7 @@ func (iv *ImageVerification) Convert() *ImageVerification {
}
attestorSet := &AttestorSet{}
attestorSet.Entries = append(attestorSet.Entries, &attestor)
attestorSet.Entries = append(attestorSet.Entries, attestor)
copy.Attestors = append(copy.Attestors, attestorSet)
return copy

View file

@ -125,15 +125,16 @@ func (in *Attestor) DeepCopyInto(out *Attestor) {
*out = new(KeylessAttestor)
(*in).DeepCopyInto(*out)
}
if in.Attestors != nil {
in, out := &in.Attestors, &out.Attestors
*out = make([]*apiextensionsv1.JSON, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(apiextensionsv1.JSON)
(*in).DeepCopyInto(*out)
}
if in.Attestor != nil {
in, out := &in.Attestor, &out.Attestor
*out = new(apiextensionsv1.JSON)
(*in).DeepCopyInto(*out)
}
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}

View file

@ -1245,7 +1245,7 @@ spec:
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs. Deprecated. Use annotations per Attestor instead.
type: object
attestations:
description: Attestations are optional checks for signed in-toto Statements used to verify the image. See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the OCI registry and decodes them into a list of Statement declarations.
@ -1342,11 +1342,14 @@ spec:
description: Entries contains the available attestors. An attestor can be a static key, attributes for keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet used to specify a more complex set of match authorities TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet used to specify a more complex set of match authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute used to verify a Sigstore keyless attestor. See https://github.com/sigstore/cosign/blob/main/KEYLESS.md.
properties:
@ -1355,22 +1358,34 @@ spec:
type: string
description: AdditionalExtensions are certificate-extensions used for keyless signing.
type: object
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
issuer:
description: Issuer is the certificate issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA certificate chain
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
subject:
description: Subject is the verified identity used for keyless signing, for example the email address
type: string
type: object
repository:
description: Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule. If specified Repository will override other OCI image repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
key:
description: Key is an X.509 public key used to verify image signatures. The key can be directly specified or can be a variable reference to a key specified in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
type: object
type: object
type: array
@ -1391,7 +1406,7 @@ spec:
description: Key is the PEM encoded public key that the image or attestation is signed with. Deprecated. Use StaticKeyAttestor instead.
type: string
repository:
description: Repository is an optional alternate OCI repository to use for image signatures that match this rule. If specified Repository will override the default OCI image repository configured for the installation.
description: Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule. If specified Repository will override the default OCI image repository configured for the installation. The repository can also be overridden per Attestor or Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate chain used for keyless signing Deprecated. Use KeylessAttestor instead.
@ -2683,7 +2698,7 @@ spec:
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs. Deprecated. Use annotations per Attestor instead.
type: object
attestations:
description: Attestations are optional checks for signed in-toto Statements used to verify the image. See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the OCI registry and decodes them into a list of Statement declarations.
@ -2780,11 +2795,14 @@ spec:
description: Entries contains the available attestors. An attestor can be a static key, attributes for keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet used to specify a more complex set of match authorities TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet used to specify a more complex set of match authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute used to verify a Sigstore keyless attestor. See https://github.com/sigstore/cosign/blob/main/KEYLESS.md.
properties:
@ -2793,22 +2811,34 @@ spec:
type: string
description: AdditionalExtensions are certificate-extensions used for keyless signing.
type: object
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
issuer:
description: Issuer is the certificate issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA certificate chain
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
subject:
description: Subject is the verified identity used for keyless signing, for example the email address
type: string
type: object
repository:
description: Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule. If specified Repository will override other OCI image repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
key:
description: Key is an X.509 public key used to verify image signatures. The key can be directly specified or can be a variable reference to a key specified in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
type: object
type: object
type: array
@ -2829,7 +2859,7 @@ spec:
description: Key is the PEM encoded public key that the image or attestation is signed with. Deprecated. Use StaticKeyAttestor instead.
type: string
repository:
description: Repository is an optional alternate OCI repository to use for image signatures that match this rule. If specified Repository will override the default OCI image repository configured for the installation.
description: Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule. If specified Repository will override the default OCI image repository configured for the installation. The repository can also be overridden per Attestor or Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate chain used for keyless signing Deprecated. Use KeylessAttestor instead.
@ -4830,7 +4860,7 @@ spec:
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs. Deprecated. Use annotations per Attestor instead.
type: object
attestations:
description: Attestations are optional checks for signed in-toto Statements used to verify the image. See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the OCI registry and decodes them into a list of Statement declarations.
@ -4927,11 +4957,14 @@ spec:
description: Entries contains the available attestors. An attestor can be a static key, attributes for keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet used to specify a more complex set of match authorities TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet used to specify a more complex set of match authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute used to verify a Sigstore keyless attestor. See https://github.com/sigstore/cosign/blob/main/KEYLESS.md.
properties:
@ -4940,22 +4973,34 @@ spec:
type: string
description: AdditionalExtensions are certificate-extensions used for keyless signing.
type: object
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
issuer:
description: Issuer is the certificate issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA certificate chain
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
subject:
description: Subject is the verified identity used for keyless signing, for example the email address
type: string
type: object
repository:
description: Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule. If specified Repository will override other OCI image repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
key:
description: Key is an X.509 public key used to verify image signatures. The key can be directly specified or can be a variable reference to a key specified in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
type: object
type: object
type: array
@ -4976,7 +5021,7 @@ spec:
description: Key is the PEM encoded public key that the image or attestation is signed with. Deprecated. Use StaticKeyAttestor instead.
type: string
repository:
description: Repository is an optional alternate OCI repository to use for image signatures that match this rule. If specified Repository will override the default OCI image repository configured for the installation.
description: Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule. If specified Repository will override the default OCI image repository configured for the installation. The repository can also be overridden per Attestor or Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate chain used for keyless signing Deprecated. Use KeylessAttestor instead.
@ -6268,7 +6313,7 @@ spec:
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs. Deprecated. Use annotations per Attestor instead.
type: object
attestations:
description: Attestations are optional checks for signed in-toto Statements used to verify the image. See https://github.com/in-toto/attestation. Kyverno fetches signed attestations from the OCI registry and decodes them into a list of Statement declarations.
@ -6365,11 +6410,14 @@ spec:
description: Entries contains the available attestors. An attestor can be a static key, attributes for keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet used to specify a more complex set of match authorities TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
annotations:
additionalProperties:
type: string
description: Annotations are used for image verification. Every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet used to specify a more complex set of match authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute used to verify a Sigstore keyless attestor. See https://github.com/sigstore/cosign/blob/main/KEYLESS.md.
properties:
@ -6378,22 +6426,34 @@ spec:
type: string
description: AdditionalExtensions are certificate-extensions used for keyless signing.
type: object
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
issuer:
description: Issuer is the certificate issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA certificate chain
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
subject:
description: Subject is the verified identity used for keyless signing, for example the email address
type: string
type: object
repository:
description: Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule. If specified Repository will override other OCI image repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional PEM encoded set of certificates that are not trust anchors, but can be used to form a chain from the leaf certificate to a root certificate.
type: string
key:
description: Key is an X.509 public key used to verify image signatures. The key can be directly specified or can be a variable reference to a key specified in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set of PEM encoded trusted root certificates. If not provided, the system roots are used.
type: string
type: object
type: object
type: array
@ -6414,7 +6474,7 @@ spec:
description: Key is the PEM encoded public key that the image or attestation is signed with. Deprecated. Use StaticKeyAttestor instead.
type: string
repository:
description: Repository is an optional alternate OCI repository to use for image signatures that match this rule. If specified Repository will override the default OCI image repository configured for the installation.
description: Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule. If specified Repository will override the default OCI image repository configured for the installation. The repository can also be overridden per Attestor or Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate chain used for keyless signing Deprecated. Use KeylessAttestor instead.

View file

@ -954,7 +954,7 @@ func printTestResult(resps map[string]report.PolicyReportResult, testResults []T
rc.Pass++
}
} else {
log.Log.V(2).Info("result mismatch", "expected", testRes.Result, "received", v.Result, "key", resultKey)
log.Log.V(2).Info("result mismatch", "expected", v.Result, "received", testRes.Result, "key", resultKey)
res.Result = boldRed.Sprintf("Fail")
rc.Fail++
}

View file

@ -504,7 +504,7 @@ OuterLoop:
log.Log.Error(err, "failed to marshal resource")
}
updated_resource, err := ut.ConvertToUnstructured(resourceRaw)
updatedResource, err := ut.ConvertToUnstructured(resourceRaw)
if err != nil {
log.Log.Error(err, "unable to convert raw resource to unstructured")
}
@ -536,7 +536,8 @@ OuterLoop:
if err := context.MutateResourceWithImageInfo(resourceRaw, ctx); err != nil {
log.Log.Error(err, "failed to add image variables to context")
}
mutateResponse := engine.Mutate(&engine.PolicyContext{Policy: policy, NewResource: *updated_resource, JSONContext: ctx, NamespaceLabels: namespaceLabels})
mutateResponse := engine.Mutate(&engine.PolicyContext{Policy: policy, NewResource: *updatedResource, JSONContext: ctx, NamespaceLabels: namespaceLabels})
if mutateResponse != nil {
engineResponses = append(engineResponses, mutateResponse)
}

View file

@ -1989,7 +1989,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -2147,15 +2148,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -2168,13 +2174,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -2182,10 +2197,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -2193,6 +2222,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -2226,9 +2261,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -4303,7 +4340,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -4461,15 +4499,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -4482,13 +4525,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -4496,10 +4548,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -4507,6 +4573,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -4540,9 +4612,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate

View file

@ -1990,7 +1990,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -2148,15 +2149,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -2169,13 +2175,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -2183,10 +2198,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -2194,6 +2223,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -2227,9 +2262,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -4305,7 +4342,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -4463,15 +4501,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -4484,13 +4527,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -4498,10 +4550,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -4509,6 +4575,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -4542,9 +4614,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate

View file

@ -2006,7 +2006,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -2164,15 +2165,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -2185,13 +2191,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -2199,10 +2214,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -2210,6 +2239,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -2243,9 +2278,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -4320,7 +4357,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -4478,15 +4516,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -4499,13 +4542,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -4513,10 +4565,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -4524,6 +4590,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -4557,9 +4629,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -7522,7 +7596,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -7680,15 +7755,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -7701,13 +7781,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -7715,10 +7804,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -7726,6 +7829,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -7759,9 +7868,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -9837,7 +9948,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -9995,15 +10107,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -10016,13 +10133,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -10030,10 +10156,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -10041,6 +10181,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -10074,9 +10220,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -11468,7 +11616,7 @@ spec:
- name: TUF_ROOT
value: /.sigstore
image: ghcr.io/kyverno/kyverno:latest
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
livenessProbe:
failureThreshold: 2
httpGet:
@ -11523,7 +11671,7 @@ spec:
fieldRef:
fieldPath: metadata.namespace
image: ghcr.io/kyverno/kyvernopre:latest
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
name: kyverno-pre
resources:
limits:

View file

@ -1995,7 +1995,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -2153,15 +2154,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -2174,13 +2180,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -2188,10 +2203,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -2199,6 +2228,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -2232,9 +2267,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -4309,7 +4346,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -4467,15 +4505,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -4488,13 +4531,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -4502,10 +4554,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -4513,6 +4579,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -4546,9 +4618,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -7487,7 +7561,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -7645,15 +7720,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -7666,13 +7746,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -7680,10 +7769,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -7691,6 +7794,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -7724,9 +7833,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate
@ -9802,7 +9913,8 @@ spec:
description: Annotations are used for image verification.
Every specified key-value pair must exist and match
in the verified payload. The payload may contain other
key-value pairs.
key-value pairs. Deprecated. Use annotations per Attestor
instead.
type: object
attestations:
description: Attestations are optional checks for signed
@ -9960,15 +10072,20 @@ spec:
keyless verification, or a nested attestor declaration.
items:
properties:
attestors:
description: 'Attestor is a nested AttestorSet
annotations:
additionalProperties:
type: string
description: Annotations are used for image
verification. Every specified key-value
pair must exist and match in the verified
payload. The payload may contain other key-value
pairs.
type: object
attestor:
description: Attestor is a nested AttestorSet
used to specify a more complex set of match
authorities TODO: Nested typed declarations
are cause issues with OpenAPIv3 Schemas.
Need to revisit.'
items:
x-kubernetes-preserve-unknown-fields: true
type: array
authorities
x-kubernetes-preserve-unknown-fields: true
keyless:
description: Keyless is a set of attribute
used to verify a Sigstore keyless attestor.
@ -9981,13 +10098,22 @@ spec:
certificate-extensions used for keyless
signing.
type: object
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
issuer:
description: Issuer is the certificate
issuer used for keyless signing.
type: string
roots:
description: Roots is a PEM encoded CA
certificate chain
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
subject:
description: Subject is the verified identity
@ -9995,10 +10121,24 @@ spec:
the email address
type: string
type: object
repository:
description: Repository is an optional alternate
OCI repository to use for signatures and
attestations that match this rule. If specified
Repository will override other OCI image
repository locations for this Attestor.
type: string
staticKey:
description: StaticKey is a set of attributes
used to verify an X.509 public key
properties:
intermediates:
description: Intermediates is an optional
PEM encoded set of certificates that
are not trust anchors, but can be used
to form a chain from the leaf certificate
to a root certificate.
type: string
key:
description: Key is an X.509 public key
used to verify image signatures. The
@ -10006,6 +10146,12 @@ spec:
be a variable reference to a key specified
in a ConfigMap (see https://kyverno.io/docs/writing-policies/variables/).
type: string
roots:
description: Roots is an optional set
of PEM encoded trusted root certificates.
If not provided, the system roots are
used.
type: string
type: object
type: object
type: array
@ -10039,9 +10185,11 @@ spec:
type: string
repository:
description: Repository is an optional alternate OCI repository
to use for image signatures that match this rule. If
specified Repository will override the default OCI image
repository configured for the installation.
to use for image signatures and attestations that match
this rule. If specified Repository will override the
default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or
Attestation.
type: string
roots:
description: Roots is the PEM encoded Root certificate

View file

@ -264,14 +264,38 @@ See <a href="https://github.com/sigstore/cosign/blob/main/KEYLESS.md">https://gi
</tr>
<tr>
<td>
<code>attestors</code></br>
<code>attestor</code></br>
<em>
[]*k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON
</em>
</td>
<td>
<p>Attestor is a nested AttestorSet used to specify a more complex set of match authorities
TODO: Nested typed declarations are cause issues with OpenAPIv3 Schemas. Need to revisit.</p>
<p>Attestor is a nested AttestorSet used to specify a more complex set of match authorities</p>
</td>
</tr>
<tr>
<td>
<code>annotations</code></br>
<em>
map[string]string
</em>
</td>
<td>
<p>Annotations are used for image verification.
Every specified key-value pair must exist and match in the verified payload.
The payload may contain other key-value pairs.</p>
</td>
</tr>
<tr>
<td>
<code>repository</code></br>
<em>
string
</em>
</td>
<td>
<p>Repository is an optional alternate OCI repository to use for signatures and attestations that match this rule.
If specified Repository will override other OCI image repository locations for this Attestor.</p>
</td>
</tr>
</tbody>
@ -1540,7 +1564,8 @@ map[string]string
<td>
<p>Annotations are used for image verification.
Every specified key-value pair must exist and match in the verified payload.
The payload may contain other key-value pairs.</p>
The payload may contain other key-value pairs.
Deprecated. Use annotations per Attestor instead.</p>
</td>
</tr>
<tr>
@ -1551,8 +1576,9 @@ string
</em>
</td>
<td>
<p>Repository is an optional alternate OCI repository to use for image signatures that match this rule.
If specified Repository will override the default OCI image repository configured for the installation.</p>
<p>Repository is an optional alternate OCI repository to use for image signatures and attestations that match this rule.
If specified Repository will override the default OCI image repository configured for the installation.
The repository can also be overridden per Attestor or Attestation.</p>
</td>
</tr>
</tbody>
@ -1598,13 +1624,27 @@ string
</tr>
<tr>
<td>
<code>intermediates</code></br>
<em>
string
</em>
</td>
<td>
<p>Intermediates is an optional PEM encoded set of certificates that are not trust
anchors, but can be used to form a chain from the leaf certificate to a
root certificate.</p>
</td>
</tr>
<tr>
<td>
<code>roots</code></br>
<em>
string
</em>
</td>
<td>
<p>Roots is a PEM encoded CA certificate chain</p>
<p>Roots is an optional set of PEM encoded trusted root certificates.
If not provided, the system roots are used.</p>
</td>
</tr>
<tr>
@ -2626,6 +2666,31 @@ specified or can be a variable reference to a key specified in a ConfigMap (see
<a href="https://kyverno.io/docs/writing-policies/variables/)">https://kyverno.io/docs/writing-policies/variables/)</a>.</p>
</td>
</tr>
<tr>
<td>
<code>intermediates</code></br>
<em>
string
</em>
</td>
<td>
<p>Intermediates is an optional PEM encoded set of certificates that are not trust
anchors, but can be used to form a chain from the leaf certificate to a
root certificate.</p>
</td>
</tr>
<tr>
<td>
<code>roots</code></br>
<em>
string
</em>
</td>
<td>
<p>Roots is an optional set of PEM encoded trusted root certificates.
If not provided, the system roots are used.</p>
</td>
</tr>
</tbody>
</table>
<hr />

View file

@ -38,6 +38,7 @@ type Options struct {
ImageRef string
Key string
Roots []byte
Intermediates []byte
Subject string
Issuer string
AdditionalExtensions map[string]string

View file

@ -29,6 +29,10 @@ func SetMock(image string, data [][]byte) error {
return nil
}
func ClearMock() {
client = &driver{}
}
type mock struct {
data map[string][]cosign.SignedPayload
}

View file

@ -12,10 +12,10 @@ import (
"github.com/kyverno/kyverno/pkg/cosign"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/utils"
engineUtils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/registryclient"
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
imageUtils "github.com/kyverno/kyverno/pkg/utils/image"
"github.com/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/log"
)
@ -133,7 +133,7 @@ type imageVerifier struct {
resp *response.EngineResponse
}
func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]map[string]imageutils.ImageInfo) {
func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]map[string]imageUtils.ImageInfo) {
// for backward compatibility
imageVerify = imageVerify.Convert()
@ -141,7 +141,7 @@ func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[st
for _, imageInfo := range infoMap {
path := imageInfo.Pointer
image := imageInfo.String()
jmespath := utils.JsonPointerToJMESPath(path)
jmespath := engineUtils.JsonPointerToJMESPath(path)
changed, err := iv.policyContext.JSONContext.HasChanged(jmespath)
if err == nil && !changed {
iv.logger.V(4).Info("no change in image, skipping check", "image", image)
@ -156,7 +156,7 @@ func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[st
var ruleResp *response.RuleResponse
if len(imageVerify.Attestations) == 0 {
var digest string
ruleResp, digest = iv.verifySignature(imageVerify, imageInfo)
ruleResp, digest = iv.verifySignatures(imageVerify, imageInfo)
if ruleResp.Status == response.RuleStatusPass {
iv.patchDigest(path, imageInfo, digest, ruleResp)
}
@ -180,67 +180,122 @@ func imageMatches(image string, imagePatterns []string) bool {
return false
}
func (iv *imageVerifier) verifySignature(imageVerify *v1.ImageVerification, imageInfo imageutils.ImageInfo) (*response.RuleResponse, string) {
func (iv *imageVerifier) verifySignatures(imageVerify *v1.ImageVerification, imageInfo imageUtils.ImageInfo) (*response.RuleResponse, string) {
image := imageInfo.String()
iv.logger.Info("verifying image", "image", image)
iv.logger.Info("verifying image", "image", image, "attestors", len(imageVerify.Attestors), "attestations", len(imageVerify.Attestations))
ruleResp := &response.RuleResponse{
Name: iv.rule.Name,
Type: response.Validation,
var digest string
for i, attestorSet := range imageVerify.Attestors {
var err error
path := fmt.Sprintf(".attestors[%d]", i)
digest, err = iv.verifyAttestorSet(attestorSet, imageVerify, image, path)
if err != nil {
iv.logger.Error(err, "failed to verify signature", "attestorSet", attestorSet)
msg := fmt.Sprintf("failed to verify signature for %s: %s", image, err.Error())
return ruleResponse(iv.rule, response.ImageVerify, msg, response.RuleStatusFail), ""
}
}
opts := cosign.Options{
ImageRef: image,
Repository: imageVerify.Repository,
Log: iv.logger,
msg := fmt.Sprintf("verified image signatures for %s", image)
return ruleResponse(iv.rule, response.ImageVerify, msg, response.RuleStatusPass), digest
}
func (iv *imageVerifier) verifyAttestorSet(attestorSet *v1.AttestorSet, imageVerify *v1.ImageVerification, image, path string) (string, error) {
var errorList []error
verifiedCount := 0
requiredCount := getRequiredCount(attestorSet)
for i, a := range attestorSet.Entries {
var digest string
var entryError error
attestorPath := fmt.Sprintf("%s.entries[%d]", path, i)
if a.Attestor != nil {
nestedAttestorSet, err := v1.AttestorSetUnmarshal(a.Attestor)
if err != nil {
entryError = errors.Wrapf(err, "failed to unmarshal nested attestor %s", attestorPath)
} else {
attestorPath += ".attestor"
digest, entryError = iv.verifyAttestorSet(nestedAttestorSet, imageVerify, image, attestorPath)
}
} else {
opts, subPath := iv.buildOptionsAndPath(a, imageVerify, image)
digest, entryError = cosign.VerifySignature(*opts)
if entryError != nil {
entryError = fmt.Errorf("%s: %s", attestorPath+subPath, entryError.Error())
}
}
if entryError == nil {
verifiedCount++
if verifiedCount >= requiredCount {
iv.logger.V(2).Info("image verification succeeded", "verifiedCount", verifiedCount, "requiredCount", requiredCount)
return digest, nil
}
} else {
errorList = append(errorList, entryError)
}
}
attestor := iv.getAttestor(imageVerify)
if attestor == nil {
ruleResp.Status = response.RuleStatusError
ruleResp.Message = "failed to find attestor"
return ruleResp, ""
iv.logger.Info("image verification failed", "verifiedCount", verifiedCount, "requiredCount", requiredCount, "errors", errorList)
err := engineUtils.CombineErrors(errorList)
return "", err
}
func getRequiredCount(as *v1.AttestorSet) int {
if as.Count == nil || *as.Count == 0 {
return len(as.Entries)
}
return *as.Count
}
func (iv *imageVerifier) buildOptionsAndPath(attestor *v1.Attestor, imageVerify *v1.ImageVerification, image string) (*cosign.Options, string) {
path := ""
opts := &cosign.Options{
ImageRef: image,
Repository: imageVerify.Repository,
Annotations: imageVerify.Annotations,
Log: iv.logger,
}
if imageVerify.Roots != "" {
opts.Roots = []byte(imageVerify.Roots)
}
if attestor.StaticKey != nil {
path = path + ".staticKey"
opts.Key = attestor.StaticKey.Key
if attestor.StaticKey.Roots != "" {
opts.Roots = []byte(attestor.StaticKey.Roots)
}
if attestor.StaticKey.Intermediates != "" {
opts.Intermediates = []byte(attestor.StaticKey.Intermediates)
}
} else if attestor.Keyless != nil {
opts.Roots = []byte(attestor.Keyless.Roots)
path = path + ".keyless"
if attestor.Keyless.Roots != "" {
opts.Roots = []byte(attestor.Keyless.Roots)
}
if attestor.Keyless.Intermediates != "" {
opts.Intermediates = []byte(attestor.Keyless.Intermediates)
}
opts.Issuer = attestor.Keyless.Issuer
opts.Subject = attestor.Keyless.Subject
opts.AdditionalExtensions = attestor.Keyless.AdditionalExtensions
}
if imageVerify.Annotations != nil {
opts.Annotations = imageVerify.Annotations
if attestor.Repository != "" {
opts.Repository = attestor.Repository
}
start := time.Now()
digest, err := cosign.VerifySignature(opts)
if err != nil {
iv.logger.Info("failed to verify image", "image", image, "error", err, "duration", time.Since(start).Seconds())
ruleResp.Status = response.RuleStatusFail
ruleResp.Message = fmt.Sprintf("image verification failed for %s: %v", image, err)
return ruleResp, ""
if attestor.Annotations != nil {
opts.Annotations = attestor.Annotations
}
ruleResp.Status = response.RuleStatusPass
ruleResp.Message = fmt.Sprintf("image %s verified", image)
iv.logger.V(3).Info("verified image", "image", image, "digest", digest, "duration", time.Since(start).Seconds())
return ruleResp, digest
return opts, path
}
func (iv *imageVerifier) getAttestor(imageVerify *v1.ImageVerification) *v1.Attestor {
for _, attestorSet := range imageVerify.Attestors {
for _, attestor := range attestorSet.Entries {
return attestor
}
}
return nil
}
func (iv *imageVerifier) patchDigest(path string, imageInfo imageutils.ImageInfo, digest string, ruleResp *response.RuleResponse) {
func (iv *imageVerifier) patchDigest(path string, imageInfo imageUtils.ImageInfo, digest string, ruleResp *response.RuleResponse) {
if imageInfo.Digest == "" {
patch, err := makeAddDigestPatch(path, imageInfo, digest)
if err != nil {
@ -252,7 +307,7 @@ func (iv *imageVerifier) patchDigest(path string, imageInfo imageutils.ImageInfo
}
}
func makeAddDigestPatch(path string, imageInfo imageutils.ImageInfo, digest string) ([]byte, error) {
func makeAddDigestPatch(path string, imageInfo imageUtils.ImageInfo, digest string) ([]byte, error) {
var patch = make(map[string]interface{})
patch["op"] = "replace"
patch["path"] = path
@ -260,7 +315,7 @@ func makeAddDigestPatch(path string, imageInfo imageutils.ImageInfo, digest stri
return json.Marshal(patch)
}
func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo imageutils.ImageInfo) *response.RuleResponse {
func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo imageUtils.ImageInfo) *response.RuleResponse {
image := imageInfo.String()
start := time.Now()
@ -312,7 +367,7 @@ func buildStatementMap(statements []map[string]interface{}) map[string][]map[str
return results
}
func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img imageutils.ImageInfo) (bool, error) {
func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img imageUtils.ImageInfo) (bool, error) {
if len(a.Conditions) == 0 {
return true, nil
}

View file

@ -2,6 +2,7 @@ package engine
import (
"encoding/json"
"strings"
"testing"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
@ -12,7 +13,7 @@ import (
"gotest.tools/assert"
)
var test_policy_good = `{
var testPolicyGood = `{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
@ -61,7 +62,7 @@ var test_policy_good = `{
}
}`
var test_policy_bad = `{
var testPolicyBad = `{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
@ -110,7 +111,7 @@ var test_policy_bad = `{
}
}`
var test_resource = `{
var testResource = `{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {"name": "test"},
@ -130,8 +131,8 @@ var payloads = [][]byte{
[]byte(`{"payloadType":"https://example.com/CodeReview/v1","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2V4YW1wbGUuY29tL0NvZGVSZXZpZXcvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2hjci5pby9qaW1idWd3YWRpYS9wYXVzZTIiLCJkaWdlc3QiOnsic2hhMjU2IjoiYjMxYmZiNGQwMjEzZjI1NGQzNjFlMDA3OWRlYWFlYmVmYTRmODJiYTdhYTc2ZWY4MmU5MGI0OTM1YWQ1YjEwNSJ9fV0sInByZWRpY2F0ZSI6eyJhdXRob3IiOiJtYWlsdG86YWxpY2VAZXhhbXBsZS5jb20iLCJyZXBvIjp7ImJyYW5jaCI6Im1haW4iLCJ0eXBlIjoiZ2l0IiwidXJpIjoiaHR0cHM6Ly9naXRodWIuY29tL2V4YW1wbGUvbXktcHJvamVjdCJ9LCJyZXZpZXdlcnMiOlsibWFpbHRvOmJvYkBleGFtcGxlLmNvbSJdfX0=","signatures":[{"keyid":"","sig":"MEUCIEeZbdBEFQzWqiMhB+SJgM6yFppUuQSKrpOIX1mxLDmRAiEA8pXqFq0GVc9LKhPzrnJRZhSruDNiKbiLHG5x7ETFyY8="}]}`),
}
func Test_CosignAttest(t *testing.T) {
policyContext := buildContext(t, test_policy_good, test_resource)
func Test_CosignMockAttest(t *testing.T) {
policyContext := buildContext(t, testPolicyGood, testResource)
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", payloads)
assert.NilError(t, err)
@ -141,8 +142,8 @@ func Test_CosignAttest(t *testing.T) {
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
}
func Test_CosignAttest_fail(t *testing.T) {
policyContext := buildContext(t, test_policy_bad, test_resource)
func Test_CosignMockAttest_fail(t *testing.T) {
policyContext := buildContext(t, testPolicyBad, testResource)
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", payloads)
assert.NilError(t, err)
@ -180,3 +181,282 @@ func buildContext(t *testing.T, policy, resource string) *PolicyContext {
}
return policyContext
}
var testSampleSingleKeyPolicy = `
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "check-image",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none"
}
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"webhookTimeoutSeconds": 30,
"failurePolicy": "Fail",
"rules": [
{
"name": "check-signature",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"verifyImages": [
{
"imageReferences": [
"ghcr.io/kyverno/test-verify-image:*"
],
"attestors": [
{
"entries": [
{
"staticKey": {
"key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM\n5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==\n-----END PUBLIC KEY-----"
}
}
]
}
]
}
]
}
]
}
}
`
var testSampleMultipleKeyPolicy = `
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "check-image",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none"
}
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"webhookTimeoutSeconds": 30,
"failurePolicy": "Fail",
"rules": [
{
"name": "check-signature",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"verifyImages": [
{
"imageReferences": [
"ghcr.io/kyverno/test-verify-image:*"
],
"attestors": [
{
"count": COUNT,
"entries": [
{
"staticKey": {
"key": "KEY1"
}
},
{
"staticKey": {
"key": "KEY2"
}
}
]
}
]
}
]
}
]
}
}
`
var testSampleResource = `{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {"name": "test"},
"spec": {
"containers": [
{
"name": "pause2",
"image": "ghcr.io/kyverno/test-verify-image:signed"
}
]
}
}`
var testVerifyImageKey = `-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==\n-----END PUBLIC KEY-----\n`
var testOtherKey = `-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyBg8yod24/wIcc5QqlVLtCfL+6Te+nwdPdTvMb1AiZn24zBToHJVZvQdYLgRWAbh0Jd+6JhEwsDmnXRrlV7rfw==\n-----END PUBLIC KEY-----\n`
func Test_SignatureGoodSigned(t *testing.T) {
policyContext := buildContext(t, testSampleSingleKeyPolicy, testSampleResource)
cosign.ClearMock()
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
}
func Test_SignatureUnsigned(t *testing.T) {
cosign.ClearMock()
unsigned := strings.Replace(testSampleResource, ":signed", ":unsigned", -1)
policyContext := buildContext(t, testSampleSingleKeyPolicy, unsigned)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
}
func Test_SignatureWrongKey(t *testing.T) {
cosign.ClearMock()
otherKey := strings.Replace(testSampleResource, ":signed", ":signed-by-someone-else", -1)
policyContext := buildContext(t, testSampleSingleKeyPolicy, otherKey)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
}
func Test_SignaturesMultiKey(t *testing.T) {
cosign.ClearMock()
policy := strings.Replace(testSampleMultipleKeyPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1)
policy = strings.Replace(policy, "COUNT", "0", -1)
policyContext := buildContext(t, policy, testSampleResource)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
}
func Test_SignaturesMultiKeyFail(t *testing.T) {
cosign.ClearMock()
policy := strings.Replace(testSampleMultipleKeyPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "COUNT", "0", -1)
policyContext := buildContext(t, policy, testSampleResource)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
}
func Test_SignaturesMultiKeyOneGoodKey(t *testing.T) {
cosign.ClearMock()
policy := strings.Replace(testSampleMultipleKeyPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
policy = strings.Replace(policy, "COUNT", "1", -1)
policyContext := buildContext(t, policy, testSampleResource)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
}
func Test_SignaturesMultiKeyZeroGoodKey(t *testing.T) {
cosign.ClearMock()
policy := strings.Replace(testSampleMultipleKeyPolicy, "KEY1", testOtherKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
policy = strings.Replace(policy, "COUNT", "1", -1)
policyContext := buildContext(t, policy, testSampleResource)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
}
var testNestedAttestorPolicy = `
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "check-image-keyless",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none"
}
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"webhookTimeoutSeconds": 30,
"failurePolicy": "Fail",
"rules": [
{
"name": "check-image-keyless",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"verifyImages": [
{
"imageReferences": [
"ghcr.io/kyverno/test-verify-image:*"
],
"attestors": [
{
"count": COUNT,
"entries": [
{
"staticKey": {
"key": "KEY1"
}
},
{
"attestor": {
"entries": [
{
"staticKey": {
"key": "KEY2"
}
}
]
}
}
]
}
]
}
]
}
]
}
}
`
func Test_NestedAttestors(t *testing.T) {
cosign.ClearMock()
policy := strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1)
policy = strings.Replace(policy, "COUNT", "0", -1)
policyContext := buildContext(t, policy, testSampleResource)
err := VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
policy = strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
policy = strings.Replace(policy, "COUNT", "0", -1)
policyContext = buildContext(t, policy, testSampleResource)
err = VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
policy = strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
policy = strings.Replace(policy, "COUNT", "1", -1)
policyContext = buildContext(t, policy, testSampleResource)
err = VerifyAndPatchImages(policyContext)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
}

View file

@ -27,9 +27,9 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
var skippedRules []string
logger := log.Log.WithName("EngineMutate").WithValues("policy", policy.GetName(), "kind", patchedResource.GetKind(),
"namespace", patchedResource.GetNamespace(), "skippedRules", patchedResource.GetName())
"namespace", patchedResource.GetNamespace(), "name", patchedResource.GetName())
logger.V(4).Info("start policy processing", "startTime", startTime)
logger.V(4).Info("start mutate policy processing", "startTime", startTime)
startMutateResultResponse(resp, policy, patchedResource)
defer endMutateResultResponse(logger, resp, startTime)

View file

@ -98,3 +98,21 @@ func JsonPointerToJMESPath(jsonPointer string) string {
return sb.String()
}
func CombineErrors(errors []error) error {
if len(errors) == 0 {
return nil
}
if len(errors) == 1 {
return errors[0]
}
messages := make([]string, len(errors))
for i := range errors {
messages[i] = errors[i].Error()
}
msg := strings.Join(messages, "; ")
return fmt.Errorf(msg)
}

View file

@ -3,12 +3,13 @@ package validate
import (
"fmt"
"strconv"
"strings"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/anchor"
"github.com/kyverno/kyverno/pkg/engine/common"
"github.com/kyverno/kyverno/pkg/engine/wildcards"
engineUtils "github.com/kyverno/kyverno/pkg/engine/utils"
)
type PatternError struct {
@ -153,24 +154,6 @@ func validateMap(log logr.Logger, resourceMap, patternMap map[string]interface{}
return "", nil
}
func combineErrors(errors []error) error {
if len(errors) == 0 {
return nil
}
if len(errors) == 1 {
return errors[0]
}
messages := make([]string, len(errors))
for i := range errors {
messages[i] = errors[i].Error()
}
msg := strings.Join(messages, "; ")
return fmt.Errorf(msg)
}
func validateArray(log logr.Logger, resourceArray, patternArray []interface{}, originPattern interface{}, path string, ac *anchor.AnchorKey) (string, error) {
if len(patternArray) == 0 {
return path, fmt.Errorf("pattern Array empty")
@ -214,7 +197,7 @@ func validateArray(log logr.Logger, resourceArray, patternArray []interface{}, o
if applyCount == 0 && len(skipErrors) > 0 {
return path, &PatternError{
Err: combineErrors(skipErrors),
Err: engineUtils.CombineErrors(skipErrors),
Path: path,
Skip: true,
}
@ -248,7 +231,7 @@ func validateArrayOfMaps(log logr.Logger, resourceMapArray []interface{}, patter
if applyCount == 0 && len(skipErrors) > 0 {
return path, &PatternError{
Err: combineErrors(skipErrors),
Err: engineUtils.CombineErrors(skipErrors),
Path: path,
Skip: true,
}

View file

@ -30,7 +30,7 @@ func Validate(policyContext *PolicyContext) (resp *response.EngineResponse) {
startTime := time.Now()
logger := buildLogger(policyContext)
logger.V(4).Info("start policy processing", "startTime", startTime)
logger.V(4).Info("start validate policy processing", "startTime", startTime)
defer func() {
buildResponse(policyContext, resp, startTime)
logger.V(4).Info("finished policy processing", "processingTime", resp.PolicyResponse.ProcessingTime.String(), "validationRulesApplied", resp.PolicyResponse.RulesAppliedCount)