This repository contains Kyverno CEL policies for managing Confidential Containers workloads on Kubernetes/OpenShift clusters.
- Kubernetes/OpenShift cluster with Kata Containers runtime configured
- Kyverno v1.18.0+ installed in the cluster (required for CEL compression/decompression support)
kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/refs/heads/main/config/install-latest-testing.yaml| Policy | File | Description |
|---|---|---|
| Inject Kata RuntimeClass | policies/mutate/add-runtimeclass-mpol/inject-kata-cc-runtime.yaml |
Automatically adds runtimeClassName: kata-cc to pods with label coco: enabled |
| Inject InitData | policies/mutate/inject-initdata-mpol/inject-coco-initdata.yaml |
Injects CoCo initdata annotation from a ConfigMap |
| Inject Sidecar | policies/mutate/inject-sidecar-mpol/inject-coco-mtls-sidecar.yaml |
Injects secure mTLS sidecar for attestation API |
| Inject Init Container | policies/mutate/inject-init-container-mpol/inject-coco-attestation-init.yaml |
Injects attestation verification init container |
| Inject Sealed Secret Config | policies/mutate/inject-sealed-secret-mpol/inject-sealed-secret-config.yaml |
Injects sealed secret references (secretKeyRef + volume + volumeMount) from ConfigMap settings |
| Policy | File | Description |
|---|---|---|
| Validate InitData ConfigMap | policies/validate/validate-initdata-configmap-vpol/validate-initdata-configmap.yaml |
Validates structure of initdata ConfigMaps |
Add the label coco: enabled to your pods to automatically assign the kata-cc runtime class:
apiVersion: v1
kind: Pod
metadata:
name: my-coco-pod
labels:
coco: enabled
spec:
containers:
- name: app
image: myapp:latest- Create a ConfigMap with base64-gzip encoded initdata:
# Encode your initdata TOML
echo '<your-initdata-toml>' | gzip | base64- Create the ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-initdata
data:
data: <base64-gzip-encoded-content>- Reference it in your pod:
metadata:
labels:
coco: enabled
annotations:
coco.io/initdata-configmap: my-initdata- Create a sidecar configuration ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-sidecar-config
data:
sidecar_image: "ghcr.io/confidential-containers/secure-sidecar:latest"
tls_cert_uri: "kbs:///default/sidecar-tls/app/cert.pem"
https_port: "8443"
forward_port: "8080"- Reference it in your pod:
metadata:
annotations:
coco.io/sidecar-config: my-sidecar-config- Create an init container configuration ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-init-config
data:
init_image: "ghcr.io/confidential-containers/attestation-init:latest"
kbs_url: "https://kbs.example.com:8080"
timeout: "60"- Reference it in your pod:
metadata:
annotations:
coco.io/init-config: my-init-configThe sealed secret configuration flow:
- Create a sealed secret envelope JSON, for example:
{"version":"0.1.0","type":"vault","name":"kbs:///default/mysecret/secret","provider":"kbs","provider_settings":{},"annotations":{}} - Encode and pack it as
sealed.<header>.<base64url(json)>.<signature> - Store the sealed value in a regular Kubernetes Secret
- Create a ConfigMap defining how to inject
secretKeyRefandvolumeMount - Pod gets injected env var, volume, and volumeMount from that ConfigMap
- Kata agent unwraps the sealed value inside TEE via KBS at runtime
Steps:
- Create the sealed secret payload Secret:
apiVersion: v1
kind: Secret
metadata:
name: sealed-secret
type: Opaque
stringData:
secret: "sealed.<header>.<base64url(json)>.<signature>"- Create the injection ConfigMap that maps env var + volume to that Secret:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-secret-config
data:
env_name: PROTECTED_SECRET
secret_name: sealed-secret
secret_key: secret
volume_name: sealed-secret-volume
mount_path: /sealed/myvalue- Reference the ConfigMap in your pod:
metadata:
labels:
coco: enabled
annotations:
coco.io/sealed-secret-config: my-secret-configConfigMaps with label coco.io/type: initdata are validated to ensure they contain required fields:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-initdata
labels:
coco.io/type: initdata
data:
version: "0.1.0"
algorithm: "sha384" # sha256, sha384, or sha512
policy.rego: |
package agent_policy
default allow = true
aa.toml: |
[token_configs.kbs]
url = "https://kbs.example.com:8080"
cdh.toml: |
[kbc]
name = "cc_kbc"
url = "https://kbs.example.com:8080".
├── configmaps/ # Example ConfigMaps for testing
├── policies/
│ ├── mutate/ # Mutating policies
│ │ ├── *-mpol/ # CEL MutatingPolicy
│ │ └── *.yaml # Legacy ClusterPolicy
│ └── validate/ # Validation policies
│ ├── *-vpol/ # CEL ValidatingPolicy
│ └── *.yaml # Legacy ClusterPolicy
└── tests/ # Test manifests