1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-26 09:33:48 +00:00
kyverno/api/policies.kyverno.io/v1alpha1/imageverification_policy.go
shuting c0ab93b95b
fix: autogen status for ivpol (#12431)
* feat: enable mutating webhook for ivpol

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix: unit tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix: add objects to payload

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* chore: add chainsaw test

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* chore: add update codegen

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix: propagate policy response to admission reponse

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* chore: update chainsaw tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix: ivpol autogen meta

Signed-off-by: ShutingZhao <shuting@nirmata.com>

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
2025-03-18 10:40:21 +00:00

498 lines
18 KiB
Go

package v1alpha1
import (
"strings"
"github.com/kyverno/kyverno/api/kyverno"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +genclient:nonNamespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=imageverificationpolicies,scope="Cluster",shortName=ivpol,categories=kyverno
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditionStatus.ready`
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ImageVerificationPolicy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ImageVerificationPolicySpec `json:"spec"`
// Status contains policy runtime data.
// +optional
Status IvpolStatus `json:"status,omitempty"`
}
type IvpolStatus struct {
// +optional
ConditionStatus ConditionStatus `json:"conditionStatus,omitempty"`
// +optional
Autogen IvpolAutogenStatus `json:"autogen,omitempty"`
}
type IvpolAutogenStatus struct {
// +optional
Rules []*IvpolAutogen `json:"rules,omitempty"`
}
type IvpolAutogen struct {
Name string `json:"name,omitempty"`
Spec ImageVerificationPolicySpec `json:"spec"`
}
func (s *ImageVerificationPolicy) GetName() string {
name := s.Name
if s.Annotations == nil {
if _, found := s.Annotations[kyverno.AnnotationAutogenControllers]; found {
if strings.HasPrefix(name, "autogen-cronjobs-") {
return strings.TrimPrefix(name, "autogen-cronjobs-")
} else if strings.HasPrefix(name, "autogen-") {
return strings.TrimPrefix(name, "autogen-")
}
}
}
return name
}
func (s *ImageVerificationPolicy) GetMatchConstraints() admissionregistrationv1.MatchResources {
if s.Spec.MatchConstraints == nil {
return admissionregistrationv1.MatchResources{}
}
return *s.Spec.MatchConstraints
}
func (s *ImageVerificationPolicy) GetMatchConditions() []admissionregistrationv1.MatchCondition {
return s.Spec.MatchConditions
}
func (s *ImageVerificationPolicy) GetWebhookConfiguration() *WebhookConfiguration {
return s.Spec.WebhookConfiguration
}
func (s *ImageVerificationPolicy) GetFailurePolicy() admissionregistrationv1.FailurePolicyType {
if s.Spec.FailurePolicy == nil {
return admissionregistrationv1.Fail
}
return *s.Spec.FailurePolicy
}
func (s *ImageVerificationPolicy) GetVariables() []admissionregistrationv1.Variable {
return s.Spec.Variables
}
func (s *ImageVerificationPolicy) GetSpec() *ImageVerificationPolicySpec {
return &s.Spec
}
func (s *ImageVerificationPolicy) GetStatus() *IvpolStatus {
return &s.Status
}
func (s *ImageVerificationPolicy) GetKind() string {
return "ImageVerificationPolicy"
}
// AdmissionEnabled checks if admission is set to true
func (s ImageVerificationPolicySpec) AdmissionEnabled() bool {
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Admission == nil || s.EvaluationConfiguration.Admission.Enabled == nil {
return true
}
return *s.EvaluationConfiguration.Admission.Enabled
}
// BackgroundEnabled checks if background is set to true
func (s ImageVerificationPolicySpec) BackgroundEnabled() bool {
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Background == nil || s.EvaluationConfiguration.Background.Enabled == nil {
return true
}
return *s.EvaluationConfiguration.Background.Enabled
}
func (status *IvpolStatus) SetReadyByCondition(c PolicyConditionType, s metav1.ConditionStatus, message string) {
reason := "Succeeded"
if s != metav1.ConditionTrue {
reason = "Failed"
}
newCondition := metav1.Condition{
Type: string(c),
Reason: reason,
Status: s,
Message: message,
}
meta.SetStatusCondition(&status.ConditionStatus.Conditions, newCondition)
}
func (status *IvpolStatus) GetConditionStatus() *ConditionStatus {
return &status.ConditionStatus
}
// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ImageVerificationPolicyList is a list of ImageVerificationPolicy instances
type ImageVerificationPolicyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []ImageVerificationPolicy `json:"items"`
}
// CredentialsProvidersType provides the list of credential providers required.
// +kubebuilder:validation:Enum=default;amazon;azure;google;github
type CredentialsProvidersType string
const (
DEFAULT CredentialsProvidersType = "default"
AWS CredentialsProvidersType = "amazon"
ACR CredentialsProvidersType = "azure"
GCP CredentialsProvidersType = "google"
GHCR CredentialsProvidersType = "github"
)
// ImageVerificationPolicySpec is the specification of the desired behavior of the ImageVerificationPolicy.
type ImageVerificationPolicySpec struct {
// MatchConstraints specifies what resources this policy is designed to validate.
// +optional
MatchConstraints *admissionregistrationv1.MatchResources `json:"matchConstraints"`
// FailurePolicy defines how to handle failures for the admission policy. Failures can
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
// or mis-configured policy definitions or bindings.
// +optional
FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy"`
// ValidationAction specifies the action to be taken when the matched resource violates the policy.
// Required.
// +listType=set
ValidationAction []admissionregistrationv1.ValidationAction `json:"validationActions,omitempty"`
// MatchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
// +optional
MatchConditions []admissionregistrationv1.MatchCondition `json:"matchConditions,omitempty"`
// Variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// +optional
Variables []admissionregistrationv1.Variable `json:"variables,omitempty"`
// ImagesRules is a list of Glob and CELExpressions to match images.
// Any image that matches one of the rules is considered for validation
// Any image that does not match a rule is skipped, even when they are passed as arguments to
// image verification functions
// +optional
ImageRules []ImageRule `json:"imageRules"`
// MutateDigest enables replacement of image tags with digests.
// Defaults to true.
// +kubebuilder:default=true
// +optional
MutateDigest *bool `json:"mutateDigest"`
// VerifyDigest validates that images have a digest.
// +kubebuilder:default=true
// +optional
VerifyDigest *bool `json:"verifyDigest"`
// Required validates that images are verified i.e. have matched passed a signature or attestation check.
// +kubebuilder:default=true
// +optional
Required *bool `json:"required"`
// Credentials provides credentials that will be used for authentication with registry.
// +kubebuilder:validation:Optional
Credentials *Credentials `json:"credentials,omitempty"`
// Images is a list of CEL expression to extract images from the resource
// +optional
Images []Image `json:"images,omitempty"`
// Attestors provides a list of trusted authorities.
Attestors []Attestor `json:"attestors"`
// Attestations provides a list of image metadata to verify
// +optional
Attestations []Attestation `json:"attestations"`
// Verifications contain CEL expressions which is used to apply the image verification checks.
// +listType=atomic
Verifications []admissionregistrationv1.Validation `json:"verifications"`
// WebhookConfiguration defines the configuration for the webhook.
// +optional
WebhookConfiguration *WebhookConfiguration `json:"webhookConfiguration,omitempty"`
// EvaluationConfiguration defines the configuration for the policy evaluation.
// +optional
EvaluationConfiguration *EvaluationConfiguration `json:"evaluation,omitempty"`
}
// ImageRule defines a Glob or a CEL expression for matching images
type ImageRule struct {
// Glob defines a globbing pattern for matching images
// +optional
Glob string `json:"glob"`
// Cel defines CEL Expressions for matching images
// +optional
CELExpression string `json:"cel"`
}
type Image struct {
// Name is the name for this imageList. It is used to refer to the images in verification block as images.<name>
Name string `json:"name"`
// Expression defines CEL expression to extact images from the resource.
Expression string `json:"expression"`
}
type Credentials struct {
// AllowInsecureRegistry allows insecure access to a registry.
// +optional
AllowInsecureRegistry bool `json:"allowInsecureRegistry,omitempty"`
// Providers specifies a list of OCI Registry names, whose authentication providers are provided.
// It can be of one of these values: default,google,azure,amazon,github.
// +optional
Providers []CredentialsProvidersType `json:"providers,omitempty"`
// Secrets specifies a list of secrets that are provided for credentials.
// Secrets must live in the Kyverno namespace.
// +optional
Secrets []string `json:"secrets,omitempty"`
}
// Attestor is an identity that confirms or verifies the authenticity of an image or an attestation
type Attestor struct {
// Name is the name for this attestor. It is used to refer to the attestor in verification
Name string `json:"name"`
// Cosign defines attestor configuration for Cosign based signatures
// +optional
Cosign *Cosign `json:"cosign,omitempty"`
// Notary defines attestor configuration for Notary based signatures
// +optional
Notary *Notary `json:"notary,omitempty"`
}
func (a Attestor) GetKey() string {
return a.Name
}
func (a Attestor) IsCosign() bool {
return a.Cosign != nil
}
func (a Attestor) IsNotary() bool {
return a.Notary != nil
}
// Cosign defines attestor configuration for Cosign based signatures
type Cosign struct {
// Key defines the type of key to validate the image.
// +optional
Key *Key `json:"key,omitempty"`
// Keyless sets the configuration to verify the authority against a Fulcio instance.
// +optional
Keyless *Keyless `json:"keyless,omitempty"`
// Certificate defines the configuration for local signature verification
// +optional
Certificate *Certificate `json:"certificate,omitempty"`
// Sources sets the configuration to specify the sources from where to consume the signature and attestations.
// +optional
Source *Source `json:"source,omitempty"`
// CTLog sets the configuration to verify the authority against a Rekor instance.
// +optional
CTLog *CTLog `json:"ctlog,omitempty"`
// TUF defines the configuration to fetch sigstore root
// +optional
TUF *TUF `json:"tuf,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.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}
// Notary defines attestor configuration for Notary based signatures
type Notary struct {
// Certs define the cert chain for Notary signature verification
Certs string `json:"certs"`
// TSACerts define the cert chain for verifying timestamps of notary signature
// +optional
TSACerts string `json:"tsaCerts"`
}
// TUF defines the configuration to fetch sigstore root
type TUF struct {
// Root defines the path or data of the trusted root
// +optional
Root TUFRoot `json:"root,omitempty"`
// Mirror is the base URL of Sigstore TUF repository
// +optional
Mirror string `json:"mirror,omitempty"`
}
// TUFRoot defines the path or data of the trusted root
type TUFRoot struct {
// Path is the URL or File location of the TUF root
// +optional
Path string `json:"path,omitempty"`
// Data is the base64 encoded TUF root
// +optional
Data string `json:"data,omitempty"`
}
// Source specifies the location of the signature / attestations.
type Source struct {
// Repository defines the location from where to pull the signature / attestations.
// +optional
Repository string `json:"repository,omitempty"`
// SignaturePullSecrets is an optional list of references to secrets in the
// same namespace as the deploying resource for pulling any of the signatures
// used by this Source.
// +optional
SignaturePullSecrets []corev1.LocalObjectReference `json:"PullSecrets,omitempty"`
// TagPrefix is an optional prefix that signature and attestations have.
// This is the 'tag based discovery' and in the future once references are
// fully supported that should likely be the preferred way to handle these.
// +optional
TagPrefix string `json:"tagPrefix,omitempty"`
}
// CTLog sets the configuration to verify the authority against a Rekor instance.
type CTLog struct {
// URL sets the url to the rekor instance (by default the public rekor.sigstore.dev)
// +optional
URL string `json:"url,omitempty"`
// RekorPubKey is an optional PEM-encoded public key to use for a custom Rekor.
// If set, this will be used to validate transparency log signatures from a custom Rekor.
// +optional
RekorPubKey string `json:"rekorPubKey,omitempty"`
// CTLogPubKey, if set, is used to validate SCTs against a custom source.
// +optional
CTLogPubKey string `json:"ctLogPubKey,omitempty"`
// TSACertChain, if set, is the PEM-encoded certificate chain file for the RFC3161 timestamp authority. Must
// contain the root CA certificate. Optionally may contain intermediate CA certificates, and
// may contain the leaf TSA certificate if not present in the timestamurce.
// +optional
TSACertChain string `json:"tsaCertChain,omitempty"`
// InsecureIgnoreTlog skips transparency log verification.
// +optional
InsecureIgnoreTlog bool `json:"insecureIgnoreTlog,omitempty"`
// IgnoreSCT defines whether to use the Signed Certificate Timestamp (SCT) log to check for a certificate
// timestamp. Default is false. Set to true if this was opted out during signing.
// +optional
InsecureIgnoreSCT bool `json:"insecureIgnoreSCT,omitempty"`
}
// This references a public verification key stored in
// a secret in the kyverno namespace.
// A Key must specify only one of SecretRef, Data or KMS
type Key struct {
// SecretRef sets a reference to a secret with the key.
// +optional
SecretRef *corev1.SecretReference `json:"secretRef,omitempty"`
// Data contains the inline public key
// +optional
Data string `json:"data,omitempty"`
// KMS contains the KMS url of the public key
// Supported formats differ based on the KMS system used.
// +optional
KMS string `json:"kms,omitempty"`
// HashAlgorithm specifues signature algorithm for public keys. Supported values are
// sha224, sha256, sha384 and sha512. Defaults to sha256.
// +optional
HashAlgorithm string `json:"hashAlgorithm,omitempty"`
}
// Keyless contains location of the validating certificate and the identities
// against which to verify.
type Keyless struct {
// Identities sets a list of identities.
Identities []Identity `json:"identities"`
// 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"`
}
// Certificate defines the configuration for local signature verification
type Certificate struct {
// Certificate is the to the public certificate for local signature verification.
// +optional
Certificate string `json:"cert,omitempty"`
// CertificateChain is the list of CA certificates in PEM format which will be needed
// when building the certificate chain for the signing certificate. Must start with the
// parent intermediate CA certificate of the signing certificate and end with the root certificate
// +optional
CertificateChain string `json:"certChain,omitempty"`
}
// Identity may contain the issuer and/or the subject found in the transparency
// log.
// Issuer/Subject uses a strict match, while IssuerRegExp and SubjectRegExp
// apply a regexp for matching.
type Identity struct {
// Issuer defines the issuer for this identity.
// +optional
Issuer string `json:"issuer,omitempty"`
// Subject defines the subject for this identity.
// +optional
Subject string `json:"subject,omitempty"`
// IssuerRegExp specifies a regular expression to match the issuer for this identity.
// +optional
IssuerRegExp string `json:"issuerRegExp,omitempty"`
// SubjectRegExp specifies a regular expression to match the subject for this identity.
// +optional
SubjectRegExp string `json:"subjectRegExp,omitempty"`
}
// Attestation defines the identification details of the metadata that has to be verified
type Attestation struct {
// Name is the name for this attestation. It is used to refer to the attestation in verification
Name string `json:"name"`
// InToto defines the details of attestation attached using intoto format
// +optional
InToto *InToto `json:"intoto,omitempty"`
// Referrer defines the details of attestation attached using OCI 1.1 format
// +optional
Referrer *Referrer `json:"referrer,omitempty"`
}
func (a Attestation) GetKey() string {
return a.Name
}
func (a Attestation) IsInToto() bool {
return a.InToto != nil
}
func (a Attestation) IsReferrer() bool {
return a.Referrer != nil
}
type InToto struct {
// Type defines the type of attestation contained within the statement.
Type string `json:"type"`
}
type Referrer struct {
// Type defines the type of attestation attached to the image.
Type string `json:"type"`
}
// EvaluationMode returns the evaluation mode of the policy.
func (s ImageVerificationPolicySpec) EvaluationMode() EvaluationMode {
if s.EvaluationConfiguration == nil || s.EvaluationConfiguration.Mode == "" {
return EvaluationModeKubernetes
}
return s.EvaluationConfiguration.Mode
}