ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
25 changed files with 145336 additions and 0 deletions

View file

@ -0,0 +1,87 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: audit-gateway-api-rbac
annotations:
policies.kyverno.io/title: Audit Gateway API mutating RBAC
policies.kyverno.io/category: Gateway API
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Report ClusterRoles and Roles that grant create/update/patch/delete on
gateway.networking.k8s.io resources outside the approved controller set.
spec:
validationFailureAction: Audit
background: true
rules:
- name: flag-unapproved-gateway-api-mutation
match:
any:
- resources:
kinds:
- ClusterRole
- Role
exclude:
any:
- resources:
names:
- cluster-admin
- admin
- edit
- system:*
- cilium-*
- cert-manager-*
- grafana-operator*
- victoriametrics-operator*
- flux-*
- cluster-reconciler-flux-system
- crd-controller-flux-system
- agentgateway-agentgateway-system
# Kyverno * does not match '.' — use olm.og* not olm.og.*
- olm.og*
- aggregate-olm*
# Count rules that explicitly mutate Gateway API kinds (no foreach — wildcard
# AnyIn on * false-positived every Role).
preconditions:
all:
- key: >-
{{ (request.object.rules || `[]`)[?
apiGroups != null &&
contains(apiGroups, 'gateway.networking.k8s.io') &&
(
contains(verbs, 'create') ||
contains(verbs, 'update') ||
contains(verbs, 'patch') ||
contains(verbs, 'delete') ||
contains(verbs, 'deletecollection') ||
contains(verbs, '*')
) &&
resources != null &&
(
contains(resources, 'gateways') ||
contains(resources, 'gateways/status') ||
contains(resources, 'httproutes') ||
contains(resources, 'httproutes/status') ||
contains(resources, 'httproutes/finalizers') ||
contains(resources, 'grpcroutes') ||
contains(resources, 'referencegrants') ||
contains(resources, 'tlsroutes') ||
contains(resources, 'tcproutes') ||
contains(resources, 'gatewayclasses') ||
contains(resources, 'gatewayclasses/status')
)
] | length(@) }}
operator: GreaterThan
value: 0
validate:
message: >-
Role grants mutating verbs on gateway.networking.k8s.io resources
outside the approved controller set. Review and narrow or add to the
policy allowlist.
deny:
conditions:
any:
- key: "{{ request.object.kind }}"
operator: AnyIn
value:
- Role
- ClusterRole

View file

@ -0,0 +1,109 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: canonical-cilium-cidrs
annotations:
policies.kyverno.io/title: Canonical Cilium CIDRs
policies.kyverno.io/category: Network Security
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Require canonical, non-redundant Cilium CIDRs and reject generic RFC1918
ranges in favor of explicit routed subnets.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-canonical-cidrs
match:
any:
- resources:
kinds:
- CiliumNetworkPolicy
- CiliumClusterwideNetworkPolicy
operations:
- CREATE
- UPDATE
validate:
cel:
variables:
- name: policySpecs
expression: "has(object.spec) ? [object.spec] : object.specs"
- name: genericPrivateRanges
expression: "['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']"
expressions:
- expression: >-
variables.policySpecs.all(policy,
(!has(policy.ingress) || policy.ingress.all(rule,
(!has(rule.fromCIDR) || rule.fromCIDR.all(value,
isCIDR(value) && value == string(cidr(value).masked())
)) &&
(!has(rule.fromCIDRSet) || rule.fromCIDRSet.all(entry,
(!has(entry.cidr) || (isCIDR(entry.cidr) &&
entry.cidr == string(cidr(entry.cidr).masked()) &&
(!has(entry.except) || entry.except.all(value,
isCIDR(value) && value == string(cidr(value).masked())
))))
))
)) &&
(!has(policy.egress) || policy.egress.all(rule,
(!has(rule.toCIDR) || rule.toCIDR.all(value,
isCIDR(value) && value == string(cidr(value).masked())
)) &&
(!has(rule.toCIDRSet) || rule.toCIDRSet.all(entry,
(!has(entry.cidr) || (isCIDR(entry.cidr) &&
entry.cidr == string(cidr(entry.cidr).masked()) &&
(!has(entry.except) || entry.except.all(value,
isCIDR(value) && value == string(cidr(value).masked())
))))
))
))
)
message: Cilium policy CIDRs must use canonical network prefixes.
- expression: >-
variables.policySpecs.all(policy,
(!has(policy.ingress) || policy.ingress.all(rule,
!has(rule.fromCIDR) ||
rule.fromCIDR.all(value,
rule.fromCIDR.filter(other, other == value).size() == 1 &&
!rule.fromCIDR.exists(other,
other != value && cidr(other).containsCIDR(cidr(value))
)
)
)) &&
(!has(policy.egress) || policy.egress.all(rule,
!has(rule.toCIDR) ||
rule.toCIDR.all(value,
rule.toCIDR.filter(other, other == value).size() == 1 &&
!rule.toCIDR.exists(other,
other != value && cidr(other).containsCIDR(cidr(value))
)
)
))
)
message: >-
Cilium fromCIDR and toCIDR lists must not contain duplicate or
redundant ranges.
- expression: >-
variables.policySpecs.all(policy,
(!has(policy.ingress) || policy.ingress.all(rule,
(!has(rule.fromCIDR) || rule.fromCIDR.all(value,
!variables.genericPrivateRanges.exists(block, block == value)
)) &&
(!has(rule.fromCIDRSet) || rule.fromCIDRSet.all(entry,
!has(entry.cidr) ||
!variables.genericPrivateRanges.exists(block, block == entry.cidr)
))
)) &&
(!has(policy.egress) || policy.egress.all(rule,
(!has(rule.toCIDR) || rule.toCIDR.all(value,
!variables.genericPrivateRanges.exists(block, block == value)
)) &&
(!has(rule.toCIDRSet) || rule.toCIDRSet.all(entry,
!has(entry.cidr) ||
!variables.genericPrivateRanges.exists(block, block == entry.cidr)
))
))
)
message: >-
Cilium policies must use explicit routed subnets instead of
generic RFC1918 ranges.

View file

@ -0,0 +1,56 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cilium-networkpolicy-coverage
annotations:
policies.kyverno.io/title: CiliumNetworkPolicy namespace coverage
policies.kyverno.io/category: Network Security
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Audit namespaces that lack any CiliumNetworkPolicy. Stays Audit forever;
never promote to Enforce (onboarding must not block on CNP admission).
spec:
validationFailureAction: Audit
background: true
rules:
- name: require-namespaced-cilium-networkpolicy
match:
any:
- resources:
kinds:
- Namespace
exclude:
any:
- resources:
names:
- default
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
context:
- name: cnpcount
apiCall:
urlPath: "/apis/cilium.io/v2/namespaces/{{ request.object.metadata.name }}/ciliumnetworkpolicies"
jmesPath: "items | length(@)"
validate:
message: >-
Namespace {{ request.object.metadata.name }} has no CiliumNetworkPolicy
resources. Add at least one namespaced CNP (clusterwide policies are not
counted by this rule yet).
deny:
conditions:
any:
- key: "{{ cnpcount }}"
operator: Equals
value: 0

View file

@ -0,0 +1,49 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deny-latest-tag
annotations:
policies.kyverno.io/title: Deny latest image tags
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Deny containers that pull the :latest tag.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: deny-latest-images
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Containers must not use the :latest tag. Pin a version or digest.
pattern:
spec:
=(initContainers):
- image: "!*:latest"
=(ephemeralContainers):
- image: "!*:latest"
containers:
- image: "!*:latest"

View file

@ -0,0 +1,51 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deny-privileged
annotations:
policies.kyverno.io/title: Deny privileged containers
policies.kyverno.io/category: Pod Security
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Flag containers with privileged: true. Host storage exporters should use
narrow capabilities instead of full privileged where possible.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: deny-privileged-containers
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Containers must not set privileged: true. Prefer drop ALL plus the
minimal capabilities and hostPaths required for the workload.
foreach:
- list: "request.object.spec.[initContainers, ephemeralContainers, containers][]"
deny:
conditions:
any:
- key: "{{ element.securityContext.privileged || false }}"
operator: Equals
value: true

View file

@ -0,0 +1,29 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- canonical-cilium-cidrs.yaml
- require-app-labels.yaml
- quay-job-labels.yaml
- deny-latest-tag.yaml
- cilium-networkpolicy-coverage.yaml
- deny-privileged.yaml
- require-drop-all-capabilities.yaml
- require-allow-privilege-escalation-false.yaml
- require-resource-requests.yaml
- min-replicas.yaml
- require-public-runtime-gvisor.yaml
# Track C Gateway (Audit)
- require-gateway-route-selectors.yaml
- restrict-route-parentrefs.yaml
- restrict-route-backends.yaml
- restrict-referencegrants.yaml
- protect-shared-gateways.yaml
- audit-gateway-api-rbac.yaml
- restrict-gateway-client-label.yaml
# 2b expanded Audit
- restrict-image-registries.yaml
- restrict-zot-image-pulls.yaml
- restrict-pod-host-access.yaml
- require-vso-secret-labels.yaml
- tls-activation.yaml
- tls-rollout.yaml

View file

@ -0,0 +1,32 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: min-replicas
annotations:
policies.kyverno.io/title: Ban single-replica Deployments
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Audit Deployments whose effective replica count is exactly one. Stopped
Deployments may use zero, and available Deployments must use at least two
unless a resource-specific exception is approved.
spec:
validationFailureAction: Audit
background: true
rules:
- name: min-replicas
match:
any:
- resources:
kinds:
- Deployment
validate:
message: >-
Deployment replica count must be zero or at least two. A single
replica requires a resource-specific PolicyException.
deny:
conditions:
all:
- key: "{{ request.object.spec.replicas || `1` }}"
operator: Equals
value: 1

View file

@ -0,0 +1,54 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: protect-shared-gateways
annotations:
policies.kyverno.io/title: Protect shared Gateway specs
policies.kyverno.io/category: Gateway API
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Shared Gateways (internal, relay, and short) may only have their spec mutated
by Flux GitOps service accounts. Cilium status updates that do not change
spec are not evaluated. Admission-only (userInfo is not available in
background scans).
spec:
validationFailureAction: Audit
background: false
rules:
- name: shared-gateway-spec-gitops-only
match:
any:
- resources:
kinds:
- Gateway
names:
- gateway-internal
- gateway-relay
- gateway-short
namespaces:
- kube-system
operations:
- CREATE
- UPDATE
preconditions:
any:
- key: "{{ request.operation }}"
operator: Equals
value: CREATE
- key: "{{ request.object.spec }}"
operator: NotEquals
value: "{{ request.oldObject.spec }}"
validate:
message: >-
Shared Gateway specs may only be created or changed by Flux
(flux-system kustomize-controller / helm-controller). Other callers
fail this audit until reviewed.
deny:
conditions:
all:
- key: "{{ request.userInfo.username }}"
operator: AnyNotIn
value:
- system:serviceaccount:flux-system:kustomize-controller
- system:serviceaccount:flux-system:helm-controller
- system:serviceaccount:flux-system:flux-operator

View file

@ -0,0 +1,28 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: quay-job-labels
spec:
rules:
- name: migration
match:
any:
- resources:
kinds:
- Job
namespaces:
- quay
names:
- quay-registry-quay-app-upgrade
selector:
matchLabels:
quay-component: quay-app-upgrade
quay-operator/quayregistry: quay-registry
mutate:
patchStrategicMerge:
spec:
template:
metadata:
labels:
app.kubernetes.io/name: quay
app.kubernetes.io/instance: quay-registry

View file

@ -0,0 +1,54 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-allow-privilege-escalation-false
annotations:
policies.kyverno.io/title: Require allowPrivilegeEscalation false
policies.kyverno.io/category: Pod Security
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Require every container to set allowPrivilegeEscalation: false (unset is a
fail).
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-allow-privilege-escalation-false
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Containers must set securityContext.allowPrivilegeEscalation: false
(leaving the field unset is not sufficient).
pattern:
spec:
=(initContainers):
- securityContext:
allowPrivilegeEscalation: false
=(ephemeralContainers):
- securityContext:
allowPrivilegeEscalation: false
containers:
- securityContext:
allowPrivilegeEscalation: false

View file

@ -0,0 +1,70 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-app-labels
annotations:
policies.kyverno.io/title: Require application identity labels
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Require application name and instance labels, accepting Dragonfly's native
app identity in its namespace.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-app-name-and-instance
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
- dragonfly
validate:
message: >-
Pod must have non-empty labels app.kubernetes.io/name and
app.kubernetes.io/instance for Cilium and operational selectors.
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
app.kubernetes.io/instance: "?*"
- name: dragonfly-identity
match:
any:
- resources:
kinds:
- Pod
namespaces:
- dragonfly
validate:
message: >-
Pods require name and instance labels; Dragonfly cache Pods may use
their native app label as the instance identity.
anyPattern:
- metadata:
labels:
app.kubernetes.io/name: "?*"
app.kubernetes.io/instance: "?*"
- metadata:
labels:
app.kubernetes.io/name: dragonfly
app: "?*"

View file

@ -0,0 +1,59 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-drop-all-capabilities
annotations:
policies.kyverno.io/title: Require capabilities.drop ALL
policies.kyverno.io/category: Pod Security
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Require every container to drop ALL capabilities (add back only what is
needed).
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-capabilities-drop-all
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Containers must set securityContext.capabilities.drop to include ALL.
pattern:
spec:
=(initContainers):
- securityContext:
capabilities:
drop:
- ALL
=(ephemeralContainers):
- securityContext:
capabilities:
drop:
- ALL
containers:
- securityContext:
capabilities:
drop:
- ALL

View file

@ -0,0 +1,39 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-gateway-route-selectors
annotations:
policies.kyverno.io/title: Require Gateway allowedRoutes Selector
policies.kyverno.io/category: Gateway API
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Shared Gateways must not use allowedRoutes.namespaces.from: All. Prefer
label Selectors (gateway.quorate.internal/allow-internal|public|short).
spec:
validationFailureAction: Audit
background: true
rules:
- name: deny-from-all-on-shared-gateways
match:
any:
- resources:
kinds:
- Gateway
names:
- gateway-internal
- gateway-relay
- gateway-short
namespaces:
- kube-system
validate:
message: >-
Shared Gateway listeners must set allowedRoutes.namespaces.from to
Selector (not All) with the platform attach labels.
foreach:
- list: "request.object.spec.listeners[]"
deny:
conditions:
any:
- key: "{{ element.allowedRoutes.namespaces.from || 'All' }}"
operator: Equals
value: All

View file

@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-public-runtime-gvisor
annotations:
policies.kyverno.io/title: Require gVisor in public-runtime namespaces
policies.kyverno.io/category: Runtime Isolation
policies.kyverno.io/severity: high
policies.kyverno.io/description: >-
Tier O and Tier R application namespaces are labeled as public-runtime
namespaces. Every admitted pod in those namespaces must use gVisor.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: public-pods-use-gvisor
match:
any:
- resources:
kinds:
- Pod
namespaceSelector:
matchLabels:
security.quorate.internal/public-runtime: gvisor
validate:
message: Public-runtime pods must set spec.runtimeClassName to gvisor.
pattern:
spec:
runtimeClassName: gvisor

View file

@ -0,0 +1,53 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-requests
annotations:
policies.kyverno.io/title: Require CPU and memory requests
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Require regular and init containers to set cpu and memory requests.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-cpu-memory-requests
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Containers must set resources.requests.cpu and resources.requests.memory.
pattern:
spec:
=(initContainers):
- resources:
requests:
memory: "?*"
cpu: "?*"
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"

View file

@ -0,0 +1,34 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-vso-secret-labels
annotations:
policies.kyverno.io/title: Require VSO ownership labels on VSO Secrets
policies.kyverno.io/category: Secrets
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Secrets that carry secrets.hashicorp.com/vso-ownerRefUID must also set
app.kubernetes.io/managed-by=hashicorp-vso so ownership stays consistent.
spec:
validationFailureAction: Audit
background: true
rules:
- name: vso-owner-implies-managed-by
match:
any:
- resources:
kinds:
- Secret
preconditions:
all:
- key: "{{ request.object.metadata.labels.\"secrets.hashicorp.com/vso-ownerRefUID\" || '' }}"
operator: NotEquals
value: ""
validate:
message: >-
Secrets with secrets.hashicorp.com/vso-ownerRefUID must set
app.kubernetes.io/managed-by to hashicorp-vso.
pattern:
metadata:
labels:
app.kubernetes.io/managed-by: hashicorp-vso

View file

@ -0,0 +1,42 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-gateway-client-label
annotations:
policies.kyverno.io/title: Restrict Gateway client privilege label
policies.kyverno.io/category: Gateway API
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Only approved namespaces may set gateway.quorate.internal/allow-gateway-client.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: gateway-client-label-namespace-allowlist
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: >-
{{ request.object.metadata.labels."gateway.quorate.internal/allow-gateway-client" || '' }}
operator: Equals
value: "true"
validate:
message: >-
gateway.quorate.internal/allow-gateway-client is only allowed on pods
in approved OIDC client namespaces (forgejo, forgejo-public, grafana,
longhorn, quay).
deny:
conditions:
all:
- key: "{{ request.namespace }}"
operator: AnyNotIn
value:
- forgejo
- forgejo-public
- grafana
- longhorn
- quay

View file

@ -0,0 +1,53 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
annotations:
policies.kyverno.io/title: Restrict image registries (audit)
policies.kyverno.io/category: Supply Chain
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Audit containers that pull outside the internal registry endpoints ahead
of Phase 4 image trust. Zot repository access is enforced separately.
spec:
validationFailureAction: Audit
background: true
rules:
- name: allow-internal-registries-only
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Prefer an internal registry endpoint. External registries are inventory
for the mirror/promote pipeline, and Zot repositories are separately
restricted.
foreach:
- list: "request.object.spec.[initContainers, ephemeralContainers, containers][]"
deny:
conditions:
all:
- key: >-
{{ regex_match('^(quay\.quorate\.internal/|zot\.quorate\.internal/|registry\.quorate\.internal/)', element.image) }}
operator: Equals
value: false

View file

@ -0,0 +1,79 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-pod-host-access
annotations:
policies.kyverno.io/title: Restrict host namespaces and hostPath (audit)
policies.kyverno.io/category: Pod Security
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
Audit Pod Security restricted host access (hostNetwork, hostPID, hostIPC,
hostPath). Complements deny-privileged; named exceptions for host agents.
spec:
validationFailureAction: Audit
background: true
rules:
- name: deny-host-namespaces
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Pods must not set hostNetwork, hostPID, or hostIPC (PSS restricted).
pattern:
spec:
=(hostNetwork): "false"
=(hostPID): "false"
=(hostIPC): "false"
- name: deny-hostpath-volumes
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kube-public
- kube-node-lease
- flux-system
- flux-canary
- kyverno
- cert-manager
- cilium-secrets
- olm
- operators
- longhorn
- openebs
- intel-system
- nfd
validate:
message: >-
Pods must not use hostPath volumes (PSS restricted). Prefer emptyDir,
PVC, or projected volumes.
pattern:
spec:
=(volumes):
- X(hostPath): "null"

View file

@ -0,0 +1,31 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-referencegrants
annotations:
policies.kyverno.io/title: Deny ReferenceGrant by default
policies.kyverno.io/category: Gateway API
policies.kyverno.io/severity: medium
policies.kyverno.io/description: >-
ReferenceGrant is default-deny. Add a named PolicyException for reviewed
cross-namespace backend cases.
spec:
validationFailureAction: Audit
background: true
rules:
- name: deny-referencegrant
match:
any:
- resources:
kinds:
- ReferenceGrant
validate:
message: >-
ReferenceGrant is not allowed by default. Request a named
PolicyException after review.
deny:
conditions:
any:
- key: "{{ request.object.kind }}"
operator: Equals
value: ReferenceGrant

Some files were not shown because too many files have changed in this diff Show more