diff --git a/api/kyverno/v2/policy_exception_types.go b/api/kyverno/v2/policy_exception_types.go index fbf0c1ca5e..4f11c9337a 100644 --- a/api/kyverno/v2/policy_exception_types.go +++ b/api/kyverno/v2/policy_exception_types.go @@ -16,6 +16,7 @@ limitations under the License. package v2 import ( + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1" "github.com/kyverno/kyverno/ext/wildcard" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -51,6 +52,11 @@ func (p *PolicyException) GetKind() string { return "PolicyException" } +// HasPodSecurity checks if podSecurity controls is specified +func (p *PolicyException) HasPodSecurity() bool { + return len(p.Spec.PodSecurity) > 0 +} + // PolicyExceptionSpec stores policy exception spec type PolicyExceptionSpec struct { // Background controls if exceptions are applied to existing policies during a background scan. @@ -68,6 +74,11 @@ type PolicyExceptionSpec struct { // Exceptions is a list policy/rules to be excluded Exceptions []Exception `json:"exceptions" yaml:"exceptions"` + + // PodSecurity specifies the Pod Security Standard controls to be excluded. + // Applicable only to policies that have validate.podSecurity subrule. + // +optional + PodSecurity []kyvernov1.PodSecurityStandard `json:"podSecurity,omitempty" yaml:"podSecurity,omitempty"` } func (p *PolicyExceptionSpec) BackgroundProcessingEnabled() bool { diff --git a/api/kyverno/v2/zz_generated.deepcopy.go b/api/kyverno/v2/zz_generated.deepcopy.go index 3be826dc3d..a433a13ef2 100644 --- a/api/kyverno/v2/zz_generated.deepcopy.go +++ b/api/kyverno/v2/zz_generated.deepcopy.go @@ -709,6 +709,13 @@ func (in *PolicyExceptionSpec) DeepCopyInto(out *PolicyExceptionSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.PodSecurity != nil { + in, out := &in.PodSecurity, &out.PodSecurity + *out = make([]kyvernov1.PodSecurityStandard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/api/kyverno/v2beta1/policy_exception_types.go b/api/kyverno/v2beta1/policy_exception_types.go index 7e22fe3ce8..b48c6dbb4b 100644 --- a/api/kyverno/v2beta1/policy_exception_types.go +++ b/api/kyverno/v2beta1/policy_exception_types.go @@ -16,6 +16,7 @@ limitations under the License. package v2beta1 import ( + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/ext/wildcard" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" @@ -51,6 +52,11 @@ func (p *PolicyException) GetKind() string { return "PolicyException" } +// HasPodSecurity checks if podSecurity controls is specified +func (p *PolicyException) HasPodSecurity() bool { + return len(p.Spec.PodSecurity) > 0 +} + // PolicyExceptionSpec stores policy exception spec type PolicyExceptionSpec struct { // Background controls if exceptions are applied to existing policies during a background scan. @@ -68,6 +74,11 @@ type PolicyExceptionSpec struct { // Exceptions is a list policy/rules to be excluded Exceptions []Exception `json:"exceptions" yaml:"exceptions"` + + // PodSecurity specifies the Pod Security Standard controls to be excluded. + // Applicable only to policies that have validate.podSecurity subrule. + // +optional + PodSecurity []kyvernov1.PodSecurityStandard `json:"podSecurity,omitempty" yaml:"podSecurity,omitempty"` } func (p *PolicyExceptionSpec) BackgroundProcessingEnabled() bool { diff --git a/api/kyverno/v2beta1/zz_generated.deepcopy.go b/api/kyverno/v2beta1/zz_generated.deepcopy.go index b3326b74eb..1c0ca94bc8 100755 --- a/api/kyverno/v2beta1/zz_generated.deepcopy.go +++ b/api/kyverno/v2beta1/zz_generated.deepcopy.go @@ -552,6 +552,13 @@ func (in *PolicyExceptionSpec) DeepCopyInto(out *PolicyExceptionSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.PodSecurity != nil { + in, out := &in.PodSecurity, &out.PodSecurity + *out = make([]v1.PodSecurityStandard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/charts/kyverno/charts/crds/templates/crds.yaml b/charts/kyverno/charts/crds/templates/crds.yaml index 155454b441..66946c7aa8 100644 --- a/charts/kyverno/charts/crds/templates/crds.yaml +++ b/charts/kyverno/charts/crds/templates/crds.yaml @@ -46256,6 +46256,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -46847,6 +46899,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -47438,6 +47542,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match diff --git a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policyexceptions.yaml b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policyexceptions.yaml index 0316731972..a5b2d0c523 100644 --- a/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policyexceptions.yaml +++ b/cmd/cli/kubectl-kyverno/data/crds/kyverno.io_policyexceptions.yaml @@ -600,6 +600,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -1191,6 +1243,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -1782,6 +1886,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match diff --git a/config/crds/kyverno.io_policyexceptions.yaml b/config/crds/kyverno.io_policyexceptions.yaml index 0316731972..a5b2d0c523 100644 --- a/config/crds/kyverno.io_policyexceptions.yaml +++ b/config/crds/kyverno.io_policyexceptions.yaml @@ -600,6 +600,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -1191,6 +1243,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -1782,6 +1886,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml index 580a96e71a..e4e799170b 100644 --- a/config/install-latest-testing.yaml +++ b/config/install-latest-testing.yaml @@ -46479,6 +46479,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -47070,6 +47122,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match @@ -47661,6 +47765,58 @@ spec: type: object type: array type: object + podSecurity: + description: PodSecurity specifies the Pod Security Standard controls + to be excluded. Applicable only to policies that have validate.podSecurity + subrule. + items: + description: PodSecurityStandard specifies the Pod Security Standard + controls to be excluded. + properties: + controlName: + description: 'ControlName specifies the name of the Pod Security + Standard control. See: https://kubernetes.io/docs/concepts/security/pod-security-standards/' + enum: + - HostProcess + - Host Namespaces + - Privileged Containers + - Capabilities + - HostPath Volumes + - Host Ports + - AppArmor + - SELinux + - /proc Mount Type + - Seccomp + - Sysctls + - Volume Types + - Privilege Escalation + - Running as Non-root + - Running as Non-root user + type: string + images: + description: 'Images selects matching containers and applies + the container level PSS. Each image is the image name consisting + of the registry address, repository, image, and tag. Empty + list matches no containers, PSS checks are applied at the + pod level only. Wildcards (''*'' and ''?'') are allowed. See: + https://kubernetes.io/docs/concepts/containers/images.' + items: + type: string + type: array + restrictedField: + description: RestrictedField selects the field for the given + Pod Security Standard control. When not set, all restricted + fields for the control are selected. + type: string + values: + description: Values defines the allowed values that can be excluded. + items: + type: string + type: array + required: + - controlName + type: object + type: array required: - exceptions - match diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html index baa6c0a3e4..136378e9df 100644 --- a/docs/user/crd/index.html +++ b/docs/user/crd/index.html @@ -2825,7 +2825,9 @@ Allowed values are v1.19, v1.20, v1.21, v1.22, v1.23, v1.24, v1.25, v1.26, lates

(Appears on: -PodSecurity) +PodSecurity, +PolicyExceptionSpec, +PolicyExceptionSpec)

PodSecurityStandard specifies the Pod Security Standard controls to be excluded.

@@ -6193,6 +6195,21 @@ set of conditions. The declaration can contain nested any or

Exceptions is a list policy/rules to be excluded

+ + +podSecurity
+ + +[]PodSecurityStandard + + + + +(Optional) +

PodSecurity specifies the Pod Security Standard controls to be excluded. +Applicable only to policies that have validate.podSecurity subrule.

+ + @@ -6958,6 +6975,21 @@ set of conditions. The declaration can contain nested any or

Exceptions is a list policy/rules to be excluded

+ + +podSecurity
+ + +[]PodSecurityStandard + + + + +(Optional) +

PodSecurity specifies the Pod Security Standard controls to be excluded. +Applicable only to policies that have validate.podSecurity subrule.

+ +
@@ -7677,6 +7709,21 @@ set of conditions. The declaration can contain nested any or

Exceptions is a list policy/rules to be excluded

+ + +podSecurity
+ + +[]PodSecurityStandard + + + + +(Optional) +

PodSecurity specifies the Pod Security Standard controls to be excluded. +Applicable only to policies that have validate.podSecurity subrule.

+ + @@ -8635,6 +8682,21 @@ set of conditions. The declaration can contain nested any or

Exceptions is a list policy/rules to be excluded

+ + +podSecurity
+ + +[]PodSecurityStandard + + + + +(Optional) +

PodSecurity specifies the Pod Security Standard controls to be excluded. +Applicable only to policies that have validate.podSecurity subrule.

+ + @@ -9288,6 +9350,21 @@ set of conditions. The declaration can contain nested any or

Exceptions is a list policy/rules to be excluded

+ + +podSecurity
+ + +[]PodSecurityStandard + + + + +(Optional) +

PodSecurity specifies the Pod Security Standard controls to be excluded. +Applicable only to policies that have validate.podSecurity subrule.

+ +
diff --git a/pkg/client/applyconfigurations/kyverno/v2/policyexceptionspec.go b/pkg/client/applyconfigurations/kyverno/v2/policyexceptionspec.go index 65c8b6e7af..c26cb9f34c 100644 --- a/pkg/client/applyconfigurations/kyverno/v2/policyexceptionspec.go +++ b/pkg/client/applyconfigurations/kyverno/v2/policyexceptionspec.go @@ -19,16 +19,18 @@ limitations under the License. package v2 import ( + v1 "github.com/kyverno/kyverno/pkg/client/applyconfigurations/kyverno/v1" v2beta1 "github.com/kyverno/kyverno/pkg/client/applyconfigurations/kyverno/v2beta1" ) // PolicyExceptionSpecApplyConfiguration represents an declarative configuration of the PolicyExceptionSpec type for use // with apply. type PolicyExceptionSpecApplyConfiguration struct { - Background *bool `json:"background,omitempty"` - Match *v2beta1.MatchResourcesApplyConfiguration `json:"match,omitempty"` - Conditions *v2beta1.AnyAllConditionsApplyConfiguration `json:"conditions,omitempty"` - Exceptions []ExceptionApplyConfiguration `json:"exceptions,omitempty"` + Background *bool `json:"background,omitempty"` + Match *v2beta1.MatchResourcesApplyConfiguration `json:"match,omitempty"` + Conditions *v2beta1.AnyAllConditionsApplyConfiguration `json:"conditions,omitempty"` + Exceptions []ExceptionApplyConfiguration `json:"exceptions,omitempty"` + PodSecurity []v1.PodSecurityStandardApplyConfiguration `json:"podSecurity,omitempty"` } // PolicyExceptionSpecApplyConfiguration constructs an declarative configuration of the PolicyExceptionSpec type for use with @@ -73,3 +75,16 @@ func (b *PolicyExceptionSpecApplyConfiguration) WithExceptions(values ...*Except } return b } + +// WithPodSecurity adds the given value to the PodSecurity field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the PodSecurity field. +func (b *PolicyExceptionSpecApplyConfiguration) WithPodSecurity(values ...*v1.PodSecurityStandardApplyConfiguration) *PolicyExceptionSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPodSecurity") + } + b.PodSecurity = append(b.PodSecurity, *values[i]) + } + return b +} diff --git a/pkg/client/applyconfigurations/kyverno/v2beta1/policyexceptionspec.go b/pkg/client/applyconfigurations/kyverno/v2beta1/policyexceptionspec.go index d93cf5b338..69c5d0fa1a 100644 --- a/pkg/client/applyconfigurations/kyverno/v2beta1/policyexceptionspec.go +++ b/pkg/client/applyconfigurations/kyverno/v2beta1/policyexceptionspec.go @@ -18,13 +18,18 @@ limitations under the License. package v2beta1 +import ( + v1 "github.com/kyverno/kyverno/pkg/client/applyconfigurations/kyverno/v1" +) + // PolicyExceptionSpecApplyConfiguration represents an declarative configuration of the PolicyExceptionSpec type for use // with apply. type PolicyExceptionSpecApplyConfiguration struct { - Background *bool `json:"background,omitempty"` - Match *MatchResourcesApplyConfiguration `json:"match,omitempty"` - Conditions *AnyAllConditionsApplyConfiguration `json:"conditions,omitempty"` - Exceptions []ExceptionApplyConfiguration `json:"exceptions,omitempty"` + Background *bool `json:"background,omitempty"` + Match *MatchResourcesApplyConfiguration `json:"match,omitempty"` + Conditions *AnyAllConditionsApplyConfiguration `json:"conditions,omitempty"` + Exceptions []ExceptionApplyConfiguration `json:"exceptions,omitempty"` + PodSecurity []v1.PodSecurityStandardApplyConfiguration `json:"podSecurity,omitempty"` } // PolicyExceptionSpecApplyConfiguration constructs an declarative configuration of the PolicyExceptionSpec type for use with @@ -69,3 +74,16 @@ func (b *PolicyExceptionSpecApplyConfiguration) WithExceptions(values ...*Except } return b } + +// WithPodSecurity adds the given value to the PodSecurity field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the PodSecurity field. +func (b *PolicyExceptionSpecApplyConfiguration) WithPodSecurity(values ...*v1.PodSecurityStandardApplyConfiguration) *PolicyExceptionSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPodSecurity") + } + b.PodSecurity = append(b.PodSecurity, *values[i]) + } + return b +} diff --git a/pkg/engine/handlers/validation/validate_pss.go b/pkg/engine/handlers/validation/validate_pss.go index f9e9a01c69..78d5bf7a01 100644 --- a/pkg/engine/handlers/validation/validate_pss.go +++ b/pkg/engine/handlers/validation/validate_pss.go @@ -44,7 +44,7 @@ func (h validatePssHandler) Process( // check if there is a policy exception matches the incoming resource exception := engineutils.MatchesException(exceptions, policyContext, logger) - if exception != nil { + if exception != nil && !exception.HasPodSecurity() { key, err := cache.MetaNamespaceKeyFunc(exception) if err != nil { logger.Error(err, "failed to compute policy exception key", "namespace", exception.GetNamespace(), "name", exception.GetName()) @@ -70,10 +70,11 @@ func (h validatePssHandler) Process( Spec: *podSpec, ObjectMeta: *metadata, } - allowed, pssChecks, err := pss.EvaluatePod(podSecurity, pod) + levelVersion, err := pss.ParseVersion(podSecurity.Level, podSecurity.Version) if err != nil { return resource, handlers.WithError(rule, engineapi.Validation, "failed to parse pod security api version", err) } + allowed, pssChecks := pss.EvaluatePod(levelVersion, podSecurity.Exclude, pod) pssChecks = convertChecks(pssChecks, resource.GetKind()) podSecurityChecks := engineapi.PodSecurityChecks{ Level: podSecurity.Level, @@ -86,6 +87,23 @@ func (h validatePssHandler) Process( engineapi.RulePass(rule.Name, engineapi.Validation, msg).WithPodSecurityChecks(podSecurityChecks), ) } else { + // apply pod security exceptions if exist + if exception != nil && exception.HasPodSecurity() { + pssChecks, err = pss.ApplyPodSecurityExclusion(levelVersion, exception.Spec.PodSecurity, pssChecks, pod) + if len(pssChecks) == 0 && err == nil { + key, err := cache.MetaNamespaceKeyFunc(exception) + if err != nil { + logger.Error(err, "failed to compute policy exception key", "namespace", exception.GetNamespace(), "name", exception.GetName()) + return resource, handlers.WithError(rule, engineapi.Validation, "failed to compute exception key", err) + } else { + podSecurityChecks.Checks = pssChecks + logger.V(3).Info("policy rule skipped due to policy exception", "exception", key) + return resource, handlers.WithResponses( + engineapi.RuleSkip(rule.Name, engineapi.Validation, "rule skipped due to policy exception "+key).WithException(exception).WithPodSecurityChecks(podSecurityChecks), + ) + } + } + } msg := fmt.Sprintf(`Validation rule '%s' failed. It violates PodSecurity "%s:%s": %s`, rule.Name, podSecurity.Level, podSecurity.Version, pss.FormatChecksPrint(pssChecks)) return resource, handlers.WithResponses( engineapi.RuleFail(rule.Name, engineapi.Validation, msg).WithPodSecurityChecks(podSecurityChecks), @@ -161,7 +179,7 @@ func getSpec(resource unstructured.Unstructured) (podSpec *corev1.PodSpec, metad metadata = &pod.ObjectMeta return podSpec, metadata, nil } else { - return nil, nil, fmt.Errorf("Could not find correct resource type") + return nil, nil, fmt.Errorf("could not find correct resource type") } if err != nil { return nil, nil, err diff --git a/pkg/pss/evaluate.go b/pkg/pss/evaluate.go index c4c362288d..e35ec800b1 100644 --- a/pkg/pss/evaluate.go +++ b/pkg/pss/evaluate.go @@ -218,54 +218,64 @@ func getContainerInfo(pod *corev1.Pod, index int, containerType string) corev1.C return container } -func parseVersion(rule *kyvernov1.PodSecurity) (*api.LevelVersion, error) { +func ParseVersion(level api.Level, version string) (*api.LevelVersion, error) { // Get pod security admission version var apiVersion api.Version // Version set to "latest" by default - if rule.Version == "" || rule.Version == "latest" { + if version == "" || version == "latest" { apiVersion = api.LatestVersion() } else { - parsedApiVersion, err := api.ParseVersion(rule.Version) + parsedApiVersion, err := api.ParseVersion(version) if err != nil { return nil, err } apiVersion = api.MajorMinorVersion(parsedApiVersion.Major(), parsedApiVersion.Minor()) } return &api.LevelVersion{ - Level: rule.Level, + Level: level, Version: apiVersion, }, nil } // EvaluatePod applies PSS checks to the pod and exempts controls specified in the rule -func EvaluatePod(rule *kyvernov1.PodSecurity, pod *corev1.Pod) (bool, []pssutils.PSSCheckResult, error) { - levelVersion, err := parseVersion(rule) - if err != nil { - return false, nil, err +func EvaluatePod(levelVersion *api.LevelVersion, excludes []kyvernov1.PodSecurityStandard, pod *corev1.Pod) (bool, []pssutils.PSSCheckResult) { + var err error + // apply the pod security checks on pods + defaultCheckResults := evaluatePSS(levelVersion, *pod) + // exclude pod security controls if specified + if len(excludes) > 0 { + defaultCheckResults, err = ApplyPodSecurityExclusion(levelVersion, excludes, defaultCheckResults, pod) } - defaultCheckResults := evaluatePSS(levelVersion, *pod) + return (len(defaultCheckResults) == 0 && err == nil), defaultCheckResults +} - for _, exclude := range rule.Exclude { +// ApplyPodSecurityExclusion excludes pod security controls +func ApplyPodSecurityExclusion( + levelVersion *api.LevelVersion, + excludes []kyvernov1.PodSecurityStandard, + defaultCheckResults []pssutils.PSSCheckResult, + pod *corev1.Pod, +) ([]pssutils.PSSCheckResult, error) { + var err error + for _, exclude := range excludes { spec, matching := GetPodWithMatchingContainers(exclude, pod) switch { // exclude pod level checks case spec != nil: - isContainerLevelExclusion := false excludeCheckResults := evaluatePSS(levelVersion, *spec) - defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, isContainerLevelExclusion) + defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, false) // exclude container level checks default: - isContainerLevelExclusion := true excludeCheckResults := evaluatePSS(levelVersion, *matching) - defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, isContainerLevelExclusion) + defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, true) } } - return (len(defaultCheckResults) == 0 && err == nil), defaultCheckResults, err + return defaultCheckResults, err } // GetPodWithMatchingContainers extracts matching container/pod info by the given exclude rule diff --git a/pkg/pss/evaluate_test.go b/pkg/pss/evaluate_test.go index 486fc3acb8..066f7034aa 100644 --- a/pkg/pss/evaluate_test.go +++ b/pkg/pss/evaluate_test.go @@ -46,9 +46,10 @@ func Test_EvaluatePod(t *testing.T) { err = json.Unmarshal(test.rawRule, &rule) assert.NilError(t, err) - allowed, checkResults, err := EvaluatePod(&rule, &pod) + levelVersion, err := ParseVersion(rule.Level, rule.Version) assert.Assert(t, err == nil) + allowed, checkResults := EvaluatePod(levelVersion, rule.Exclude, &pod) if allowed != test.allowed { for _, result := range checkResults { fmt.Printf("failed check result: %v\n", result) diff --git a/pkg/pss/fuzz_test.go b/pkg/pss/fuzz_test.go index f1b6d5e97b..39630b5532 100644 --- a/pkg/pss/fuzz_test.go +++ b/pkg/pss/fuzz_test.go @@ -423,7 +423,8 @@ func FuzzBaselinePS(f *testing.F) { rule = baselineLatestRule } - allowed, _, _ := EvaluatePod(&rule, pod) + levelVersion, _ := ParseVersion(rule.Level, rule.Version) + allowed, _ := EvaluatePod(levelVersion, rule.Exclude, pod) if allowPod != allowed { pJson, err := json.MarshalIndent(pod, "", "") if err != nil { diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/README.md b/test/conformance/chainsaw/exceptions/exclude-capabilities/README.md new file mode 100644 index 0000000000..386acdaa22 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/README.md @@ -0,0 +1,13 @@ +## Description + +This test creates a policy that enforces the restricted profile and a policy exception that exempts containers running either the nginx or redis image from the Capabilities control. +The policy exception is configured to apply only to the pods that in `staging-ns` namespace. + +## Steps + +1. - Create a cluster policy + - Assert the policy becomes ready +1. - Create a policy exception for the cluster policy created above. +1. - Try to create a pod named `goodpod01` whose image is `nginx` in the `staging-ns` namespace that violates the policy, expecting the creation to succeed + - Try to create a pod named `badpod01` whose image is `nginx` in the `default` namespace that violates the policy, expecting the creation to fail + - Try to create a pod named `badpod02` whose image is `busybox` in the `staging-ns` namespace that violates the policy,, expecting the creation to fail diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/chainsaw-test.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/chainsaw-test.yaml new file mode 100755 index 0000000000..80e7c2ca9f --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/chainsaw-test.yaml @@ -0,0 +1,37 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: exclude-capabilities +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - assert: + file: ns.yaml + - name: step-03 + try: + - apply: + file: exception.yaml + - name: step-04 + try: + - apply: + file: pod-allowed.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-rejected-1.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-rejected-2.yaml diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/exception.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/exception.yaml new file mode 100644 index 0000000000..64cc01904a --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/exception.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v2beta1 +kind: PolicyException +metadata: + name: pod-security-exception + namespace: policy-exception-ns +spec: + exceptions: + - policyName: psa-1 + ruleNames: + - restricted + match: + any: + - resources: + namespaces: + - staging-ns + podSecurity: + - controlName: Capabilities + images: + - nginx* + - redis* diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/ns.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/ns.yaml new file mode 100644 index 0000000000..2e951f10d4 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/ns.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: policy-exception-ns +--- +apiVersion: v1 +kind: Namespace +metadata: + name: staging-ns diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-allowed.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-allowed.yaml new file mode 100644 index 0000000000..5f71bc34f5 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-allowed.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod01 + namespace: staging-ns +spec: + containers: + - name: container01 + image: nginx:1.1.9 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - SYS_ADMIN + drop: + - ALL diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-1.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-1.yaml new file mode 100644 index 0000000000..0a1d765faf --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-1.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: default +spec: + containers: + - name: container01 + image: nginx:1.1.9 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - SYS_ADMIN + drop: + - ALL diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-2.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-2.yaml new file mode 100644 index 0000000000..be836a239b --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/pod-rejected-2.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod02 + namespace: staging-ns +spec: + containers: + - name: container01 + image: busybox:1.28 + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - SYS_ADMIN + drop: + - ALL diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/policy-assert.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/policy-assert.yaml new file mode 100644 index 0000000000..d52b6efde4 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-1 +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/exceptions/exclude-capabilities/policy.yaml b/test/conformance/chainsaw/exceptions/exclude-capabilities/policy.yaml new file mode 100644 index 0000000000..70dfebfda1 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-capabilities/policy.yaml @@ -0,0 +1,18 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-1 +spec: + background: true + validationFailureAction: Enforce + rules: + - name: restricted + match: + any: + - resources: + kinds: + - Pod + validate: + podSecurity: + level: restricted + version: latest diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/README.md b/test/conformance/chainsaw/exceptions/exclude-host-ports/README.md new file mode 100644 index 0000000000..70e1be5432 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/README.md @@ -0,0 +1,13 @@ +## Description + +This test creates a policy that enforces the baseline profile and a policy exception that exempts any pod whose image is `nginx` and hostPort set to either 10 or 20. +The policy exception is configured to apply only to the pods that in `staging-ns-3` namespace. + +## Steps + +1. - Create a cluster policy + - Assert the policy becomes ready +1. - Create a policy exception for the cluster policy created above. +1. - Try to create a pod named `good-pod-1` in the `default` namespace whose hostPort is set to zero, expecting the creation to succeed. + - Try to create a pod named `good-pod-2` in the `staging-ns-3` namespace that uses the HostPort control whose values are 10 and 20, expecting the creation to succeed. + - Try to create a pod named `bad-pod` in the `default` namespace that uses both the HostProcess controls with value 20, expecting the creation to fail. diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/chainsaw-test.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/chainsaw-test.yaml new file mode 100755 index 0000000000..b96ee034ec --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/chainsaw-test.yaml @@ -0,0 +1,34 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: exclude-host-ports +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - assert: + file: ns.yaml + - name: step-03 + try: + - apply: + file: exception.yaml + - name: step-04 + try: + - apply: + file: pod-allowed-1.yaml + - apply: + file: pod-allowed-2.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-rejected.yaml diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/exception.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/exception.yaml new file mode 100644 index 0000000000..3a3aa8b001 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/exception.yaml @@ -0,0 +1,28 @@ +apiVersion: kyverno.io/v2beta1 +kind: PolicyException +metadata: + name: pod-security-exception + namespace: policy-exception-ns-3 +spec: + exceptions: + - policyName: psa-3 + ruleNames: + - baseline + match: + any: + - resources: + namespaces: + - staging-ns-3 + podSecurity: + - controlName: "Host Ports" + images: + - nginx + restrictedField: "spec.containers[*].ports[*].hostPort" + values: + - "10" + - controlName: "Host Ports" + images: + - nginx + restrictedField: "spec.initContainers[*].ports[*].hostPort" + values: + - "20" diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/ns.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/ns.yaml new file mode 100644 index 0000000000..4f510c6f7c --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/ns.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: policy-exception-ns-3 +--- +apiVersion: v1 +kind: Namespace +metadata: + name: staging-ns-3 diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-1.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-1.yaml new file mode 100644 index 0000000000..f4a1662af6 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-1.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: good-pod-1 + namespace: default +spec: + containers: + - name: nginx1 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 0 + containerPort: 80 + initContainers: + - name: nginx2 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 0 + containerPort: 8080 \ No newline at end of file diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-2.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-2.yaml new file mode 100644 index 0000000000..827acece94 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-allowed-2.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: good-pod-2 + namespace: staging-ns-3 +spec: + containers: + - name: nginx1 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 10 + containerPort: 80 + initContainers: + - name: nginx2 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 20 + containerPort: 80 \ No newline at end of file diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-rejected.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-rejected.yaml new file mode 100644 index 0000000000..43914ea4ef --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/pod-rejected.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Pod +metadata: + name: bad-pod + namespace: default +spec: + containers: + - name: nginx1 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 20 + containerPort: 80 + initContainers: + - name: nginx2 + image: nginx + args: + - sleep + - 1d + ports: + - hostPort: 20 + containerPort: 80 diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/policy-assert.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/policy-assert.yaml new file mode 100644 index 0000000000..43944a468a --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-3 +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/exceptions/exclude-host-ports/policy.yaml b/test/conformance/chainsaw/exceptions/exclude-host-ports/policy.yaml new file mode 100644 index 0000000000..8bf4dedbe8 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-ports/policy.yaml @@ -0,0 +1,18 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-3 +spec: + background: true + validationFailureAction: Enforce + rules: + - name: baseline + match: + any: + - resources: + kinds: + - Pod + validate: + podSecurity: + level: baseline + version: latest diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/README.md b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/README.md new file mode 100644 index 0000000000..ca4c0dd608 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/README.md @@ -0,0 +1,14 @@ +## Description + +This test creates a policy that enforces the baseline profile and exempts any pod that violates the Host Namespaces control and a policy exception that exempts any pod that violates the HostProcess control. +The policy exception is configured to apply only to the pods that in `staging-ns-1` namespace. + +## Steps + +1. - Create a cluster policy + - Assert the policy becomes ready +1. - Create a policy exception for the cluster policy created above. +1. - Try to create a pod named `goodpod-01` in the `staging-ns-1` namespace that uses both the Host Namespace and the HostProcess controls, expecting the creation to succeed. + - Try to create a pod named `goodpod-02` in the `staging-ns-1` namespace that uses the HostProcess control, expecting the creation to succeed. + - Try to create a pod named `goodpod-03` in the `default` namespace that uses the Host Namespace control, expecting the creation to succeed. + - Try to create a pod named `badpod-01` in the `default` namespace that uses both the Host Namespace and the HostProcess controls, expecting the creation to fail. diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/chainsaw-test.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/chainsaw-test.yaml new file mode 100755 index 0000000000..ff18b07197 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/chainsaw-test.yaml @@ -0,0 +1,36 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: exclude-host-process-and-host-namespaces +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: ns.yaml + - assert: + file: ns.yaml + - name: step-03 + try: + - apply: + file: exception.yaml + - name: step-04 + try: + - apply: + file: pod-allowed-1.yaml + - apply: + file: pod-allowed-2.yaml + - apply: + file: pod-allowed-3.yaml + - apply: + expect: + - check: + ($error != null): true + file: pod-rejected.yaml diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/exception.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/exception.yaml new file mode 100644 index 0000000000..989c1cc748 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/exception.yaml @@ -0,0 +1,17 @@ +apiVersion: kyverno.io/v2beta1 +kind: PolicyException +metadata: + name: pod-security-exception + namespace: policy-exception-ns-1 +spec: + exceptions: + - policyName: psa-2 + ruleNames: + - baseline + match: + any: + - resources: + namespaces: + - staging-ns-1 + podSecurity: + - controlName: HostProcess diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/ns.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/ns.yaml new file mode 100644 index 0000000000..84ec947882 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/ns.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: policy-exception-ns-1 +--- +apiVersion: v1 +kind: Namespace +metadata: + name: staging-ns-1 diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-1.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-1.yaml new file mode 100644 index 0000000000..64f95fbe92 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-1.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod-01 + namespace: staging-ns-1 +spec: + hostIPC: true + hostNetwork: true + securityContext: + windowsOptions: + hostProcess: true + containers: + - name: container01 + image: dummyimagename diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-2.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-2.yaml new file mode 100644 index 0000000000..c85da123d6 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-2.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod-02 + namespace: staging-ns-1 +spec: + hostNetwork: true + securityContext: + windowsOptions: + hostProcess: true + containers: + - name: container01 + image: dummyimagename diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-3.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-3.yaml new file mode 100644 index 0000000000..381bb99755 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-allowed-3.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goodpod-03 + namespace: default +spec: + hostIPC: true + containers: + - name: container01 + image: dummyimagename diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-rejected.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-rejected.yaml new file mode 100644 index 0000000000..522e1bdd03 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/pod-rejected.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod-01 + namespace: default +spec: + hostIPC: true + hostNetwork: true + securityContext: + windowsOptions: + hostProcess: true + containers: + - name: container01 + image: dummyimagename diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy-assert.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy-assert.yaml new file mode 100644 index 0000000000..2fa6a45c50 --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-2 +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy.yaml b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy.yaml new file mode 100644 index 0000000000..f8614b068e --- /dev/null +++ b/test/conformance/chainsaw/exceptions/exclude-host-process-and-host-namespaces/policy.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: psa-2 +spec: + background: true + validationFailureAction: Enforce + rules: + - name: baseline + match: + any: + - resources: + kinds: + - Pod + validate: + podSecurity: + level: baseline + version: latest + exclude: + - controlName: Host Namespaces