Container Security

Kubernetes Admission Controllers for Supply Chain Policy

Admission controllers are the only Kubernetes enforcement point that sees every workload before it runs. That makes them the right place to enforce image provenance, signing, and SBOM policies.

Shadab Khan
Security Engineer
6 min read

By late 2022 most Kubernetes platform teams had converged on the same uncomfortable conclusion: pod security standards, network policies, and RBAC together still do not answer the question "is this container image allowed to run here?" The answer lives further upstream, in the build and signing pipeline, and the single enforcement point where that answer can be checked before anything bad happens is the admission controller. Admission controllers intercept every API request to create or modify a workload, and they can reject any request that fails a policy — before a pod is scheduled, before an image is pulled, before code runs. For supply chain policy this is the right layer, and after two years of production use across our customer base, the patterns that work are clearer than they were at the start. This post lays them out.

What is an admission controller doing that other Kubernetes controls do not?

An admission controller runs in the API server request path and can mutate or reject any object before it is persisted. That position gives it two properties nothing else in Kubernetes has: it sees every workload creation event before it takes effect, and it can veto. Network policies enforce in the data path after workloads are running. Pod security standards enforce against pod spec fields but not against image content or provenance. Admission controllers sit upstream of both and can enforce properties the pod spec alone does not encode: "this image must be signed by our build platform," "this image must have an associated SBOM," "this image must not contain vulnerabilities above severity X."

There are two variants: validating admission controllers reject bad requests, mutating admission controllers modify requests before persistence. Supply chain policy is almost entirely a validating concern — you are making an allow/deny decision based on image properties.

What supply chain policies are best enforced at admission time?

Four that consistently pay off:

Image signature verification. Reject images that are not signed by a trusted key. Cosign/Sigstore integration with admission controllers is mature enough in 2022 to be production-viable. The policy is stated in keyless-verification terms: image must be signed, the signature must be tied to a Fulcio cert whose OIDC identity matches an allowed pattern (e.g., your organization's GitHub Actions workflow identity).

Provenance attestation check. Reject images without a valid in-toto/SLSA provenance attestation signed by your build platform. Stronger than signature verification alone because provenance encodes how the image was built, not just that it was built by someone trusted.

SBOM presence. Reject images without an associated SBOM (SPDX or CycloneDX). This is a simple gate that disproportionately improves posture because it forces every workload to be inventoriable.

Registry pinning. Reject images pulled from registries outside your allowed list. Prevents exfil-style "pull from attacker's registry" attacks and prevents accidental pulls from public Docker Hub in environments that should only run internal images.

What are the viable admission controller implementations in 2022?

Three that are production-proven:

OPA Gatekeeper. Uses Open Policy Agent's Rego language. Mature, flexible, has a growing library of prebuilt constraints. The downside is Rego's learning curve; policies are powerful but not intuitive.

Kyverno. Kubernetes-native policy language using YAML. Easier to read and write than Rego for most teams; has first-class support for image signature verification and SBOM policy. This is the default recommendation for new adopters as of late 2022.

Custom webhook. Writing a validating webhook in Go or Python directly. Best when your policy logic is idiosyncratic and does not fit either OPA or Kyverno cleanly. Operational cost is real; you own the HA, the TLS, and the monitoring.

Don't use the built-in PodSecurityPolicy admission controller — it's deprecated in favor of Pod Security Admission, and neither handles supply chain properties.

How do signature verification policies actually fail in production?

Three failure modes, all worth planning for:

Signature verification latency on cold pulls. The first pod using a new image triggers a signature lookup against Rekor (the Sigstore transparency log) or your internal OCI registry's signature store. Tail latencies on these lookups can push pod startup over liveness-probe thresholds if your control plane is slow. Mitigation: aggressive local caching and pre-warming of recently-pushed images.

Expired or rotated signing keys. Images signed with a key that has since been rotated need a policy that respects the "was valid at the time of signing" property, not "is valid now." This is exactly what transparency logs give you, but only if your admission policy is written to consult them — a common mistake is to check the current keyring, which rejects perfectly valid older images.

Emergency override pressure. When a production incident is happening and a hotfix image needs to ship, the admission policy will block it if the signing infrastructure is having a simultaneous bad day. Every team we have seen in this situation has wished they had a documented, audit-logged break-glass override before they needed it. Build it first.

What does a reasonable rollout order look like?

Four stages, each taking one to three weeks depending on cluster count:

  1. Audit mode. Deploy policies in warn-only mode. Log every violation but do not block. Run for two weeks. Inventory every workload that would be rejected; triage each.
  2. Enforce in staging. Turn on blocking in non-production clusters only. Leave production in warn mode.
  3. Enforce in production for new workloads. Block creates but allow updates to existing workloads that predate the policy. This prevents the nightmare scenario of a policy change bricking running services.
  4. Retroactive enforcement. Block updates to existing workloads until they satisfy the policy. Requires a migration plan; many teams stop at stage 3 for months while they clean up legacy images.

The failure mode of skipping stage 1 is that a policy change breaks a production deploy at 2am. It is hard to overstate how much political capital gets burned when this happens; the audit-mode discipline is worth the extra week.

Where does admission control hit its limits?

Admission control enforces at the moment of pod creation. It cannot retroactively detect that a running workload violates a policy that was changed after the workload started. It cannot enforce properties that depend on runtime behavior (tool-calling agents, dynamic loading, etc.). It cannot substitute for upstream build pipeline controls — a signed image can still be a signed malicious image. Admission control is the gate; the build pipeline and runtime monitoring are the rest of the house.

How Safeguard Helps

Safeguard integrates with OPA Gatekeeper and Kyverno to make supply chain admission policies declarative from a single source of truth. The platform generates signed SBOMs at build time, publishes provenance attestations, and produces Kyverno/Gatekeeper policies that enforce those artifacts at admission. Griffin AI summarizes which clusters are in warn mode versus enforce mode and flags configuration drift across the cluster fleet. Break-glass override events are logged and auditable through the same policy engine the rest of the platform uses. For teams running many clusters across multiple cloud accounts, Safeguard provides the multi-cluster policy control plane that makes admission-time supply chain enforcement operationally sustainable rather than a one-cluster experiment.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.