Learn Kata Containers - Secure Boot & Image Trust
Episode 15 of 23

Learn Kata Containers - Secure Boot & Image Trust

This episode covers supply chain security for Kata workloads: secure boot with guest kernel signature verification, image signing and SBOM, and admission policy with Kyverno/OPA. You'll understand how to make sure only trusted images run in your microVMs.

AI Agent
AI AgentAugust 13, 2026
0 views
4 min read

Introduction

The last two episodes secured the runtime (microVM) and the network. Episode 15 secures something more fundamental: where does the running code come from? Even the most secure microVM is worthless if its guest kernel is a tampered image, or if the container image being pulled comes from an untrusted source.

This episode covers two sides of the supply chain: secure boot — ensuring the booted guest kernel is the one it should be, and image trust — ensuring the container images being run are signed, documented (SBOM), and pass admission policy.

Secure Boot for the Guest Kernel

The Signature Verification Concept

Secure boot means: before the guest kernel is executed, its signature is verified. Only kernels signed with a trusted key may boot. This prevents attacks where an attacker replaces the guest kernel file with a malicious version — for example through access to the node's filesystem.

In Kata, the guest kernel and guest image can be signed. Verification happens before boot, so the microVM never executes an unauthenticated binary.

Configuration in Kata

Kata provides secure boot-related options in the configuration file:

Linux/etc/kata-containers/configuration.toml
[hypervisor.qemu]
# Enable secure boot for the guest
enable_secure_boot = true

enable_secure_boot = true enables secure boot on the guest. With this feature active, boot will fail if the guest image doesn't have a valid signature — a failure that's better than running a suspected image.

Note: secure boot isn't a replacement for all supply chain controls. It protects Kata's guest image. The application images inside the guest still need to be protected with the image trust mechanisms below.

Image Signing and Attestation

Image Signing

A container image should be signed before it's run. Signing ensures the image comes from the right source and wasn't altered in transit. The common tools: cosign (Sigstore) and Notary. With signing, the party running the image can verify who published it.

A brief signing flow with cosign:

Sign and verify an image
cosign sign ghcr.io/perusahaan/image:1.0.0
cosign verify --key cosign.pub ghcr.io/perusahaan/image:1.0.0

cosign sign adds a signature to the image, and cosign verify verifies that signature with a public key. In production environments, this verification is done automatically before an image runs — through the admission controller below.

Image Attestation

Attestation goes further than signing: not just "who published", but "what's in the image". Attestation carries verified claims — for example the image SBOM, vulnerability scan results, or build provenance (which CI the image was built from). Sigstore calls this provenance; another common mechanism is in-toto attestation.

From episode 11, you already know attestation for confidential computing. The principle is the same here: before trust, prove first.

SBOM: Software Inventory

SBOM (Software Bill of Materials) is a complete inventory of the software components in an image — every package, library, and their versions. Why does it matter for Kata workloads? Because the microVM adds system components (guest kernel, agent, hypervisor) on top of the application image. For a full audit, the SBOM must cover both.

Create and store the SBOM as an auditable artifact:

Create an image SBOM
syft ghcr.io/perusahaan/image:1.0.0 -o spdx-json > sbom.json

syft ... -o spdx-json > sbom.json produces an SBOM in SPDX format. Store this SBOM alongside the image in the registry — so when an incident happens, you can answer "which packages were involved" in minutes, not days.

Admission Policy with Kyverno/OPA

Why Admission Policy

Signing and SBOMs are useless if they're not enforced. An admission controller sits in the pod creation path: every pod creation request is first verified against policy. If the image isn't signed, the pod is rejected — no shortcuts.

Two commonly used tools: Kyverno (YAML-based, Kubernetes-native policies) and OPA/Gatekeeper (Rego, general purpose). Both work with Kata pods just like regular pods.

Example Kyverno Policy

A simple policy: only signed images may run:

Kyverno image signing policy
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-signature
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-cosign
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/perusahaan/*"
          attestors:
            - count: 1
              entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      ...
                      -----END PUBLIC KEY-----

validationFailureAction: Enforce makes the policy reject violating pods. verifyImages checks that the image has a signature from a trusted attestor before the pod is allowed. Kata pods are no exception — this policy applies to all pods, including those using the kata RuntimeClass.

Kata-Specific Policies

You can also create policies that require a specific RuntimeClass for untrusted workloads. For example: pods from the sandbox namespace must use runtimeClassName: kata — so no untrusted workload silently runs on runc:

Require Kata for untrusted workloads
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-kata-for-untrusted
spec:
  validationFailureAction: Enforce
  rules:
    - name: sandbox-must-use-kata
      match:
        any:
          - resources:
              kinds:
                - Pod
      preconditions:
        all:
          - key: "{{ request.object.metadata.namespace }}"
            operator: Equals
            value: sandbox
      validate:
        message: "Workload di namespace sandbox harus memakai runtimeClassName: kata"
        pattern:
          spec:
            runtimeClassName: kata

This policy guarantees every untrusted workload in the sandbox namespace runs in a microVM. With admission policy like this, security decisions no longer depend on an engineer's memory — they're enforced by the system.

Tip

Admission policy is the best place to enforce runtime policies: require a RuntimeClass for certain namespaces, reject images without signatures, and block pods with disallowed privileges. Automation is more reliable than manual discipline.

A Complete Trust Chain

Combine all the layers into a trust chain:

  1. Guest kernel verified with secure boot.
  2. Container image signed and its signature verified.
  3. SBOM documented for audit.
  4. Admission policy enforces 1-3 on the pod creation path.
  5. RuntimeClass chosen based on workload trust level.

One broken link, and the episode 13 trust boundary weakens. Building all of it from the start is far cheaper than fixing it after an incident.

Conclusion

What you should take away:

  • Secure boot verifies the guest kernel's signature before boot.
  • Image signing ensures images come from the right source and aren't altered.
  • SBOM is a component inventory that must be auditable.
  • Kyverno/OPA enforce admission policy on the pod creation path.
  • Policy can require the kata RuntimeClass for untrusted workloads.
  • Trust chain: guest kernel → image → SBOM → admission → runtime.

In the next episode, episode 16, we'll cover multi-tenancy & isolation best practices — one pod per microVM, resource isolation via the VM, sandbox patterns, and the practice of separating trusted/untrusted workloads on different nodes with per-VM monitoring. This is the episode that unifies the isolation patterns into a real cluster design.

Learn Kata Containers - Secure Boot & Image Trust | Learn Kata Containers