Run a confidential workload

Mark a Kubernetes workload for confidential treatment with the confidential.ai/cw annotation — what the webhook injects, what the annotation value means for Service and certificate naming, and what must be allowlisted first.

Once installed, mark a workload for confidential treatment with the confidential.ai/cw annotation. The webhook injects a get-cert sidecar that fetches a TEE-bound certificate from the CDS. Under pod-as-CVM (--cvm-mode=pod) it also injects the confidential RuntimeClass for the cluster's CPU TEE — kata-qemu-snp on SEV-SNP, kata-qemu-tdx on TDX (the -nvidia variants when the pod requests a GPU):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-inference
spec:
  template:
    metadata:
      annotations:
        confidential.ai/cw: my-inference   # the workload identity (NOT a boolean)
    spec:
      containers:
        - name: server
          image: ghcr.io/example/inference@sha256:...   # must be on the allowlist

The annotation value is the workload's identity, not a true/false flag. The operator derives a managed headless Service named c8s-<value> from it and the workload's certificate SAN is c8s-<value>.<namespace>.svc (overridable with confidential.ai/c8s-san). So confidential.ai/cw: my-inference yields the Service c8s-my-inference — which is what the front door (tls-lb's upstream, derived via --workload-ref my-inference=<ns>/<kind>/<name>:<port> plus --upstream my-inference) dials to reach the workload over the RA-TLS mesh. Use a stable, DNS-label-safe name; a value like "true" would only produce a Service named c8s-true.

Make sure the image digest is on the allowlist, or image admission refuses to start the container — nri-image-policy on the host, or the in-guest policy-monitor under --cvm-mode=pod.

What the webhook adds

Every annotation the webhook reads, and every container and volume name it reserves, is in Workload annotations.

A workload can also ask for application secrets and encrypted volumes with further annotations on the same pod.

Confirm it worked

# under Pod-as-CVM the pod runs under the confidential RuntimeClass:
kubectl describe pod <POD> | grep "Runtime Class"
#   Runtime Class Name:  kata-qemu-snp     (kata-qemu-tdx on TDX)

# the webhook-injected containers are present, in this order:
kubectl get pod <POD> -o jsonpath='{range .spec.initContainers[*]}{.name}{"\n"}{end}'
#   c8s-cert        the get-cert sidecar
#   c8s-cert-wait   blocks the workload until the first cert is written

A pod stuck before those appear is usually an allowlist miss — see Troubleshoot an install.