Skip to content

Instantly share code, notes, and snippets.

@pgvishnuram
Created November 1, 2023 07:38
Show Gist options
  • Save pgvishnuram/e28526ad491672b7c575aaa53b784df4 to your computer and use it in GitHub Desktop.
Save pgvishnuram/e28526ad491672b7c575aaa53b784df4 to your computer and use it in GitHub Desktop.
# most of these policies taken verbatim from the kyverno library
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrictedish-v2
annotations:
kubernetes.io/description: intended to simulate Openshifts restricted-v2
pods to be run with a UID, and SELinux context that are allocated to the namespace. This
is the most restrictive SCC and it is used by default for authenticated users.
On top of the legacy 'restricted' SCC, it also requires to drop ALL capabilities
and does not allow privilege escalation binaries. It will also default the seccomp
profile to runtime/default if unset, otherwise this seccomp profile is required.
# intended to simulate most or all of the openshift4 restricted-v2 policy
# selinux may be more restrictive than in openshift4
spec:
validationFailureAction: Enforce
background: true
rules:
- name: scc-disable-host-namespaces
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
hostDir, hostIPC, hostNetwork, hostPID, hostPorts may not be set to true
pattern:
spec:
securityContext:
hostDir:
allow: false
hostIPC:
allow: false
hostNetwork:
allow: false
hostPID:
allow: false
hostPorts:
allow: false
- name: require-drop-all
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Containers must drop `ALL` capabilities.
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
deny:
conditions:
all:
- key: ALL
operator: AnyNotIn
value: "{{ element.securityContext.capabilities.drop[] || `[]` }}"
- name: adding-capabilities-strict
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Any capabilities added other than NET_BIND_SERVICE are disallowed.
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
deny:
conditions:
all:
- key: "{{ element.securityContext.capabilities.add[] || `[]` }}"
operator: AnyNotIn
value:
- NET_BIND_SERVICE
- ''
- name: must-run-as-higher-uid
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Running as root is not allowed. The fields spec.securityContext.runAsUser,
spec.containers[*].securityContext.runAsUser, spec.initContainers[*].securityContext.runAsUser,
and spec.ephemeralContainers[*].securityContext.runAsUser must be unset or
set to a number greater than 999.
pattern:
spec:
=(securityContext):
=(runAsUser): ">999"
=(ephemeralContainers):
- =(securityContext):
=(runAsUser): ">999"
=(initContainers):
- =(securityContext):
=(runAsUser): ">999"
containers:
- =(securityContext):
=(runAsUser): ">999"
- name: privilege-escalation
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Privilege escalation is disallowed. The fields
spec.containers[*].securityContext.allowPrivilegeEscalation,
spec.initContainers[*].securityContext.allowPrivilegeEscalation,
and spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation
must be set to `false`.
pattern:
spec:
=(ephemeralContainers):
- securityContext:
allowPrivilegeEscalation: "false"
=(initContainers):
- securityContext:
allowPrivilegeEscalation: "false"
containers:
- securityContext:
allowPrivilegeEscalation: "false"
- name: privileged-containers
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged
and spec.initContainers[*].securityContext.privileged must be unset or set to `false`.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(privileged): "false"
=(initContainers):
- =(securityContext):
=(privileged): "false"
containers:
- =(securityContext):
=(privileged): "false"
- name: check-seccomp-strict
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Use of custom Seccomp profiles is disallowed. The fields
spec.securityContext.seccompProfile.type,
spec.containers[*].securityContext.seccompProfile.type,
spec.initContainers[*].securityContext.seccompProfile.type, and
spec.ephemeralContainers[*].securityContext.seccompProfile.type
must be set to `RuntimeDefault` or `Localhost`.
anyPattern:
- spec:
securityContext:
seccompProfile:
type: "RuntimeDefault | Localhost"
=(ephemeralContainers):
- =(securityContext):
=(seccompProfile):
=(type): "RuntimeDefault | Localhost"
=(initContainers):
- =(securityContext):
=(seccompProfile):
=(type): "RuntimeDefault | Localhost"
containers:
- =(securityContext):
=(seccompProfile):
=(type): "RuntimeDefault | Localhost"
- spec:
=(ephemeralContainers):
- securityContext:
seccompProfile:
type: "RuntimeDefault | Localhost"
=(initContainers):
- securityContext:
seccompProfile:
type: "RuntimeDefault | Localhost"
containers:
- securityContext:
seccompProfile:
type: "RuntimeDefault | Localhost"
- name: check-runasgroup
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Running with root group IDs is disallowed. The fields
spec.securityContext.runAsGroup, spec.containers[*].securityContext.runAsGroup,
spec.initContainers[*].securityContext.runAsGroup, and
spec.ephemeralContainers[*].securityContext.runAsGroup must be
set to a value greater than zero.
anyPattern:
- spec:
securityContext:
runAsGroup: ">0"
=(ephemeralContainers):
- =(securityContext):
=(runAsGroup): ">0"
=(initContainers):
- =(securityContext):
=(runAsGroup): ">0"
containers:
- =(securityContext):
=(runAsGroup): ">0"
- spec:
=(ephemeralContainers):
- securityContext:
runAsGroup: ">0"
=(initContainers):
- securityContext:
runAsGroup: ">0"
containers:
- securityContext:
runAsGroup: ">0"
- name: check-supplementalgroups
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Containers cannot run with a root primary or supplementary GID. The field
spec.securityContext.supplementalGroups must be unset or
set to a value greater than zero.
pattern:
spec:
=(securityContext):
=(supplementalGroups): ">0"
- name: check-fsgroup
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Containers cannot run with a root primary or supplementary GID. The field
spec.securityContext.fsGroup must be unset or set to a value greater than zero.
pattern:
spec:
=(securityContext):
=(fsGroup): ">0"
- name: restricted-volumes
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Only the following types of volumes may be used: configMap, csi, downwardAPI,
emptyDir, ephemeral, persistentVolumeClaim, projected, and secret.
deny:
conditions:
all:
- key: "{{ request.object.spec.volumes[].keys(@)[] || '' }}"
operator: AnyNotIn
value:
- configMap
- csi
- downwardAPI
- emptyDir
- ephemeral
- persistentVolumeClaim
- projected
- secret
- ''
- name: selinux-type
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Setting the SELinux type is restricted. The fields
spec.securityContext.seLinuxOptions.type, spec.containers[*].securityContext.seLinuxOptions.type,
, spec.initContainers[*].securityContext.seLinuxOptions, and spec.ephemeralContainers[*].securityContext.seLinuxOptions.type
must either be unset or set to one of the allowed values (container_t, container_init_t, or container_kvm_t).
pattern:
spec:
=(securityContext):
=(seLinuxOptions):
=(type): "container_t | container_init_t | container_kvm_t"
=(ephemeralContainers):
- =(securityContext):
=(seLinuxOptions):
=(type): "container_t | container_init_t | container_kvm_t"
=(initContainers):
- =(securityContext):
=(seLinuxOptions):
=(type): "container_t | container_init_t | container_kvm_t"
containers:
- =(securityContext):
=(seLinuxOptions):
=(type): "container_t | container_init_t | container_kvm_t"
- name: selinux-user-role
preconditions:
all:
- key: "{{ request.operation || 'BACKGROUND' }}"
operator: NotEquals
value: DELETE
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Setting the SELinux user or role is forbidden. The fields
spec.securityContext.seLinuxOptions.user, spec.securityContext.seLinuxOptions.role,
spec.containers[*].securityContext.seLinuxOptions.user, spec.containers[*].securityContext.seLinuxOptions.role,
spec.initContainers[*].securityContext.seLinuxOptions.user, spec.initContainers[*].securityContext.seLinuxOptions.role,
spec.ephemeralContainers[*].securityContext.seLinuxOptions.user, and spec.ephemeralContainers[*].securityContext.seLinuxOptions.role
must be unset.
pattern:
spec:
=(securityContext):
=(seLinuxOptions):
X(user): "null"
X(role): "null"
=(ephemeralContainers):
- =(securityContext):
=(seLinuxOptions):
X(user): "null"
X(role): "null"
=(initContainers):
- =(securityContext):
=(seLinuxOptions):
X(user): "null"
X(role): "null"
containers:
- =(securityContext):
=(seLinuxOptions):
X(user): "null"
X(role): "null"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment