Skip to content

eBook

Zero Trust for Kubernetes with Kyverno

Kubernetes trusts by default. Any Pod can reach any other Pod, every Pod gets an API token, and any image can run. This guide removes that implicit trust with policy as code, mapped to NIST SP 800-207 and the CISA Zero Trust Maturity Model.

By the Kyverno maintainers at Nirmata

Why Kubernetes needs Zero Trust

Six defaults that let one compromised Pod reach the rest

Each one has existed since Kubernetes 1.0. Each one maps to a chapter that closes it.

Kubernetes defaults and their risk
Default behaviorRiskFixed in
Any Pod can reach any other PodAn attacker moves laterally from one compromised Pod.Chapter 4
Every Pod mounts a service account tokenA stolen token lets an attacker call the Kubernetes API.Chapter 5
RBAC allows wildcards and cluster-admin bindingsOne over-privileged account controls the cluster.Chapter 5
The cluster runs any image from any registryTampered or vulnerable images run in production.Chapter 6
Pods can run as root or privilegedA container escape gives access to the node.Chapter 6
Exceptions to policy never expireTemporary bypasses become permanent holes.Chapter 7

What's inside

Five control areas, one policy layer

Each chapter gives you a tested Kyverno policy, shows how to check that it works, and names the other components that complete the control.

Default deny, generated in every namespace

Segmentation that depends on a human setting a label correctly isn't segmentation. Derive it from a boundary the platform team controls.

  • Reject namespaces that don't declare a workspace and tier.
  • Copy those labels onto every Pod, so developers can't get them wrong.
  • Generate default-deny, DNS, workspace-isolation and tier rules from the labels.

Policies in the repo

  • generate-default-deny
  • generate-workspace-network-policy
  • generate-backend-tier-policy
  • require-workspace-labels
  • add-workload-labels
  • protect-segmentation-labels
  • generate-strict-mtls

Also needed: a CNI plugin that enforces NetworkPolicy (Cilium or Calico), and a service mesh for mTLS.

Maturity check

Where does your cluster sit on the CISA Zero Trust Maturity Model?

Pick the stage that matches each pillar today. You'll get your next step and the chapter that covers it.

NetworksChapter 4

Flat Pod network.

IdentityChapter 5

Shared admin accounts and standing cluster-admin.

Applications & WorkloadsChapter 6

Any image, any settings.

GovernanceChapter 7

Exceptions by email, and they never expire.

Visibility & AnalyticsChapter 8

No policy data.

Your overall stage

Traditional

Implicit trust everywhere. The audit profile shows you exactly where, without blocking anything.

Your next steps

  1. Networks → Initial: Default deny in audit for new namespaces. Ch 4
  2. Identity → Initial: RBAC guardrails in audit. Ch 5
  3. Applications & Workloads → Initial: Registry allowlist and Pod Security Baseline. Ch 6

Why now

None of these attacks used a novel technique

Each one worked because trust was implicit somewhere. The eBook maps eight documented incidents to the control that would have stopped or contained them.

  • March 2025

    IngressNightmare

    An admission webhook accepted unauthenticated requests and ran with a service account that could read every Secret. More than 6,500 clusters were found exposed.

    Restrict webhook access, scope the service account · Ch 4, 5

  • Through Nov 2025

    ShadowRay 2.0

    The Ray dashboard API has no authentication by default and was exposed to the internet, then used to mine crypto, steal models and spread to other nodes.

    Default-deny ingress and egress, tier segmentation · Ch 4

  • November 2025

    runc container escapes

    Containers with custom mount configurations could redirect writes to host paths and gain root on the node.

    Restricted Pod Security Standard · Ch 6

  • March 2026

    LiteLLM supply chain

    A compromised CI credential published a backdoored LLM gateway that harvested cloud and Kubernetes credentials and deployed privileged Pods.

    Verify signatures, block privileged Pods, restrict egress · Ch 4–6

Companion repository

See where you stand without blocking a single request

The audit profile installs every core policy in Audit mode, so it reports violations without blocking anything.

bash
# 1. Get the policies
git clone https://github.com/nirmata/kyverno-zero-trust
cd kyverno-zero-trust

# 2. Install every core policy in Audit mode
kubectl apply -k deploy/audit

# 3. Review what would have been blocked
kubectl get policyreports -A

Each policy has a README, Kyverno CLI tests and an end-to-end test for a local kind cluster. Browse the repo → (opens in a new tab)

  1. Days 1–30

    See where you stand

    • Apply the audit profile in test, then production.
    • Generate default deny and DNS rules for new namespaces.
    • Set up the exception namespace and approvers.
    • Record baseline metrics.
  2. Days 31–60

    Enforce the basics

    • Fix audit failures, or cover them with governed exceptions.
    • Move Pod security, registry and RBAC policies to Deny.
    • Roll default deny into existing namespaces, one team at a time.
    • Add kyverno test to CI and start signing images.
  3. Days 61–90

    Remove standing trust

    • Enforce image signature verification.
    • Replace standing admin access with JIT RoleBindings.
    • Require compensating controls for every exception.
    • Turn on mTLS and name-based egress for sensitive namespaces.

From one cluster to a fleet

The policies are open source. Operating them everywhere is the hard part.

Nirmata Control Hub authors, delivers and reports on Kyverno policies and exceptions across every cluster and team, so you can track maturity by pillar fleet-wide. Nirmata Enterprise for Kyverno is a hardened, supported build of the same engine, with CVE fixes backported to every supported release.

Keep going

Talk to the team that created Kyverno

Mapping Kubernetes controls to NIST and CISA for an audit, moving from Audit to Enforce, or rolling Zero Trust out across a fleet? Talk to the maintainers.