01 · A release upgrade is not a security control
Kubernetes 1.37 “Garhwal” shipped on August 26, 2026. Kyverno 1.19.0 shipped six days earlier, followed by security-relevant patch release 1.19.1 on September 10. These releases are recent enough to matter and mature enough to evaluate—but installing them does not prove that a cluster is hardened.
Threat model first: an attacker may submit a workload, influence a policy exception, compromise a CI identity, poison an image reference, or exploit a policy engine as a confused deputy. The defender must prove that the admission decision was enforced, that the admitted image is the one executed, that workload identity is scoped, and that policy failure cannot silently become permission.
| Release | Date | Security decision |
|---|---|---|
| Kubernetes 1.37.0 | 2026-08-26 | Adopt after API, node and workload compatibility tests. Do not infer mTLS or storage re-encryption from the version alone. |
| Kyverno 1.19.0 | 2026-08-20 | Migration release, not the target patch for production. |
| Kyverno 1.19.1 | 2026-09-10 | Minimum 1.19 target for this blueprint; includes exception-scope and API-call hardening fixes. |
02 · What Kubernetes 1.37 changes at the security boundary
Pod Certificates and ClusterTrustBundles are now stable
Kubernetes can now deliver short-lived X.509 key material to Pods through PodCertificateRequests and distribute trust anchors with ClusterTrustBundles. This removes some pressure to mount long-lived private keys as ordinary Secrets. It does not automatically authenticate every workload: you still need a trusted signer, requester authorization, rotation, audience semantics in the application protocol and mTLS verification on both ends.
StorageVersionMigration is GA
The storagemigration.k8s.io/v1 API can rewrite persisted objects into the current storage version. That matters after API-storage upgrades and encryption-at-rest key changes: data already in etcd does not become re-encrypted merely because a new provider is configured. Migration is a powerful bulk write, so restrict who can create StorageVersionMigration objects, monitor the controller and take tested backups first.
SELinux and cgroup-v2 posture improve, but compatibility remains local
SELinuxMount and SELinuxChangePolicy are stable and enabled by default, while the CSI driver still has to advertise support. The default pressure against cgroup v1 continues; use cgroup v2 rather than carrying a temporary compatibility escape hatch. These are node and container isolation controls, not substitutes for admission authorization.
Expert tip: inventory where private keys originate and where trust roots are consumed before migration. A certificate API reduces secret distribution only when applications stop accepting the legacy credential path.
03 · Why the safe Kyverno target is 1.19.1—not 1.19.0
Kyverno 1.19 completes feature parity for CEL-based ValidatingPolicy, MutatingPolicy, GeneratingPolicy, ImageValidatingPolicy and DeletingPolicy. The legacy Policy and ClusterPolicy families are deprecated for removal in 1.20. New policy development should use the policies.kyverno.io APIs, while migration needs side-by-side behavioral tests.
Patch 1.19.1 fixes a high-severity ImageValidatingPolicy exception-scope flaw: an exception intended for selected images could bypass signature verification more broadly because allowed image values were not honored. It also tightens HTTP destination blocklisting and IPv4-in-IPv6 handling for policy API calls, validates exception CEL match conditions and rejects globalContext from namespaced policies.
| Boundary | Failure mode | Required control |
|---|---|---|
| Policy author | Tenant creates or edits cluster-wide enforcement logic. | Separate reviewer-owned repository and tightly scoped RBAC. |
| Policy exception | Broad subject or image selector becomes a bypass. | Named owner, exact scope, expiry and alerting; upgrade to 1.19.1. |
| Controller egress | APICall reaches metadata, internal admin or Kubernetes endpoints. | NetworkPolicy plus external firewall/service-mesh allowlist. |
| Webhook availability | Timeout or outage allows an unsafe object. | Failure policy, replicas, disruption budget, capacity and tested recovery. |
| Image identity | Mutable tag changes after admission evidence was evaluated. | Verify signatures/attestations and resolve immutable digests. |
04 · Attack paths the combined stack must break
Layer model: image verification starts at the image boundary; CEL validation operates at the cluster admission boundary; SELinux and cgroup controls operate at the container/node boundary; Pod certificates cross workload and external-service identity boundaries; APICall misuse can cross from cluster policy into cloud or infrastructure services.
05 · Interactive hardening map
Open each branch and ask for a positive result, a negative result and the independent evidence that distinguishes them.
1 · Supply chain and admission
Verify image signatures and attestations, resolve digests, reject privileged/host-access settings and protect policy definitions from application pull requests. Negative control: unsigned image and disallowed securityContext are both denied.
2 · Workload identity and trust
Authorize the signer, use short lifetimes, distribute explicit trust bundles and require peer verification. Negative control: wrong trust domain, expired certificate and legacy credential fail.
3 · Stored data and API lifecycle
Back up etcd, migrate stored API versions, verify encryption-provider rotation and restrict migration objects. Negative control: unauthorized identity cannot create a migration.
4 · Policy-engine containment
Patch to 1.19.1, restrict policy authors and exceptions, deny controller egress by default and monitor webhook latency/errors. Negative control: namespace author cannot reach internal endpoints through policy.
5 · Runtime and node isolation
Use SELinux-aware CSI drivers, seccomp RuntimeDefault, non-root execution, dropped capabilities and cgroup v2. Negative control: a workload requesting host or unconfined access is rejected.
6 · Evidence and recovery
Correlate admission decision, policy version, image digest, workload identity, node runtime and Kubernetes audit event. Recovery proves the replacement actually runs and expired exceptions no longer work.
06 · Reference controls: enforce, contain and test
A CEL-native validation baseline for Kyverno 1.19
This policy uses the Kyverno 1.19 v1beta1 API and rejects Pods that explicitly disable the runtime seccomp baseline. It covers ordinary, init and ephemeral containers. Start in Audit, inspect reports, then move protected namespaces to Deny. If you copy a current-documentation example, confirm its API version matches the installed Kyverno release; the future v1 API is not interchangeable with 1.19 storage.
apiVersion: policies.kyverno.io/v1beta1
kind: ValidatingPolicy
metadata:
name: restrict-seccomp
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: >-
(!has(object.spec.securityContext) ||
!has(object.spec.securityContext.seccompProfile) ||
object.spec.securityContext.seccompProfile.type in ["RuntimeDefault", "Localhost"]) &&
object.spec.containers.all(c,
!has(c.securityContext) ||
!has(c.securityContext.seccompProfile) ||
c.securityContext.seccompProfile.type in ["RuntimeDefault", "Localhost"]) &&
(!has(object.spec.initContainers) || object.spec.initContainers.all(c,
!has(c.securityContext) ||
!has(c.securityContext.seccompProfile) ||
c.securityContext.seccompProfile.type in ["RuntimeDefault", "Localhost"])) &&
(!has(object.spec.ephemeralContainers) || object.spec.ephemeralContainers.all(c,
!has(c.securityContext) ||
!has(c.securityContext.seccompProfile) ||
c.securityContext.seccompProfile.type in ["RuntimeDefault", "Localhost"]))
message: Seccomp must be RuntimeDefault or an approved Localhost profile.
validationActions:
- DenyContain the policy engine’s egress
A NetworkPolicy is necessary but not universally sufficient: it depends on the CNI, does not govern traffic before the policy takes effect, and DNS allowance can still resolve hostile destinations. Pair it with reviewed destination controls outside the Pod network. The example intentionally allows only DNS and the Kubernetes API service CIDR placeholder; replace it with your cluster’s verified addresses.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kyverno-default-deny-egress
namespace: kyverno
spec:
podSelector:
matchLabels:
app.kubernetes.io/part-of: kyverno
policyTypes: ["Egress"]
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- ipBlock:
cidr: 10.96.0.1/32
ports:
- {protocol: TCP, port: 443}Run harmless negative controls
set -euo pipefail
kubectl version
kubectl get validatingpolicies.policies.kyverno.io
kubectl auth can-i create validatingpolicies.policies.kyverno.io
kubectl auth can-i create policyexceptions.policies.kyverno.io --all-namespaces
# Server-side dry-run must be rejected after the policy is enforced.
if kubectl run seccomp-negative-control \
--image=registry.k8s.io/pause:3.10 \
--overrides='{"spec":{"securityContext":{"seccompProfile":{"type":"Unconfined"}}}}' \
--dry-run=server -o yaml; then
echo "FAIL: unsafe Pod was accepted" >&2
exit 1
fi
echo "PASS: unsafe Pod was rejected"Run the same negative control during upgrades and webhook-failure exercises. A successful controller rollout is deployment evidence, not enforcement evidence.
07 · Rollout plan, detection and operator cheat sheet
Phase 1 · Observe and inventory
Pin Kubernetes and Kyverno versions, inventory legacy policies/exceptions, capture webhook latency and rejection baselines, map Kyverno RBAC and egress, and identify workloads still using long-lived credentials. Record which CSI drivers support SELinux mount behavior.
Phase 2 · Migrate with negative controls
Translate legacy policies to CEL-native APIs one control at a time. Compare allow and deny decisions against recorded fixtures. Do not delete the old rule until the new rule produces equivalent decisions and policy reports in the target namespaces.
Phase 3 · Enforce by risk tier
Move internet-facing and privileged namespaces first only after exception owners are known. Protect policy definitions and Helm values from application teams. Run Pod-certificate adoption as a separate identity project, because admission success cannot prove peer authentication.
Phase 4 · Prove failure behavior
Exercise unavailable webhook replicas, API-server pressure, DNS failure, expired certificate, wrong trust bundle, expired exception and unsigned image. Alerts should identify the policy and affected request without leaking credentials or certificate private material.
| Signal | Security question | Evidence to retain |
|---|---|---|
| Admission rejection/timeout | Was unsafe state denied, or did availability fail open? | Audit event, webhook status, policy UID/version and request identity. |
| PolicyException change | Who expanded or extended a bypass? | Old/new selectors, image scope, actor, approver and expiry. |
| Kyverno egress denial | Did a policy attempt an unapproved destination? | Network flow, policy reference and author identity. |
| Pod certificate request | Which workload requested which signer/lifetime? | Pod UID, ServiceAccount, signer, issuance/denial and peer result. |
| Storage migration | Who initiated bulk object rewrites? | Migration object, target resource, backup reference and completion state. |
| Running imageID | Does runtime state match admission evidence? | Immutable digest, signature/attestation decision and workload owner. |
0 controls verified
This checklist is stored only in the current browser page and resets on reload. It does not inspect or transmit cluster data.
08 · Final word: hardening is a proven chain of decisions
Kubernetes 1.37 gives defenders better building blocks, and Kyverno 1.19.1 gives them a stronger policy language. Neither release can decide which identities deserve authority, which exceptions are tolerable, or whether the runtime state matches the admission record.
The hardened cluster is the one where an unsafe request is denied, a failure remains visible, and the evidence reconstructs why.
Riad DAHMANI — K8SEC Security Research
Primary sources and verification trail
Release facts are grounded in the Kubernetes 1.37 announcement, Pod Certificates and ClusterTrustBundles analysis, StorageVersionMigration GA analysis, the Kyverno 1.19 release announcement, 1.19.1 release notes and ImageValidatingPolicy exception advisory. K8SEC hardening priorities are defensive analysis, not vendor guarantees.
Continue from policy to attack-path evidence
See how admission, workload identity, tools and infrastructure authority combine in a modern agentic system.
Read the agentic attack anatomy Explore KAOS