A kubectl plugin to deploy Confidential Containers (CoCo) applications.
kubectl-coco is designed primarily for developers to CoCo-fy their applications and test them with Trustee, the Remote Attestation Solution for CoCo. It's not meant for production deployment of CoCo applications.
Read more about CoCo at confidentialcontainers.org.
kubectl-coco simplifies the process of transforming regular Kubernetes manifests into CoCo-enabled manifests. It automatically handles:
- RuntimeClass Configuration: Sets the appropriate CoCo runtime
- Secrets Management: Converts K8s secrets to sealed secrets for upload to Trustee KBS via
kbs populate - ImagePullSecrets: Handles private registry credentials with automatic Trustee KBS integration
- InitData Generation: Creates aa.toml, cdh.toml, and policy.rego configurations
- ✅ KBS Management: Deploy in-cluster Trustee KBS or register an external instance; upload resources via
kbs populate - ✅ Automatic Secret Conversion: Detects and converts K8s secrets to sealed format; generates a trustee-secrets.yaml for upload via
kbs populate - ✅ ImagePullSecrets Support: Handles private registry credentials with Trustee KBS integration
- ✅ Secure Access Sidecar: Optional mTLS-secured sidecar for status reporting and secure port forwarding (see sidecar/README.md)
- ✅ Multi-Resource Support: Works with Pod, Deployment, StatefulSet, ReplicaSet, Job, DaemonSet
- ✅ InitData Management: Create, inspect, and validate initdata via the
initdatasubcommand; automatically generated duringapply - ✅ Backup Management: Saves transformed manifests with
-cocosuffix
# Download latest release
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; fi
curl -LO "https://github.com/confidential-devhub/cococtl/releases/latest/download/kubectl-coco-${OS}-${ARCH}"
# Install
sudo install -m 0755 kubectl-coco-${OS}-${ARCH} /usr/local/bin/kubectl-coco
sudo ln -sf /usr/local/bin/kubectl-coco /usr/local/bin/kubectl_complete-coco
# Verify
kubectl coco --versionSee Installation for detailed options.
Deploy Trustee and create configuration:
kubectl coco initThis creates ~/.kube/coco-config.toml and deploys Trustee to your cluster.
Use --skip-apply to generate the transformed manifest and secrets file without deploying yet:
kubectl coco apply -f your-app.yaml --skip-applySecrets must be in KBS before the pods start:
kubectl coco kbs populate -f <app>-trustee-secrets.yamlkubectl apply -f your-app-coco.yamlNote: There are some sample manifests under examples folder which you can try.
kubectl coco applyrunskubectl applyautomatically unless--skip-applyis set. Use--skip-applywhen you need to upload secrets to KBS before the workload starts (recommended for first deployments).
kubectl-coco performs these transformations:
- Sets RuntimeClass to
kata-cc(configurable) - Converts Secrets:
- Detects all secret references (env, envFrom, volumes)
- Creates sealed secrets with
-sealedsuffix - Writes KBS resource references to
<app>-trustee-secrets.yaml(upload withkbs populate) - Updates manifest to use sealed secret names
- Handles ImagePullSecrets:
- Keeps imagePullSecrets in manifest (for CRI-O)
- Writes credentials to
<app>-trustee-secrets.yaml(upload withkbs populate) - Adds KBS URI to initdata CDH configuration
- Falls back to default service account if not specified
- Generates InitData: Creates aa.toml, cdh.toml, policy.rego
- Places Annotations: Correctly adds initdata on pod templates
- Adds Custom Annotations: From your config file
For detailed information, see TRANSFORMATIONS.md.
- Go 1.24+ (for building from source)
- kubectl (for applying manifests)
- Kubernetes cluster with CoCo runtime installed
-
Download the latest release:
OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m) if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; fi curl -LO "https://github.com/confidential-devhub/cococtl/releases/latest/download/kubectl-coco-${OS}-${ARCH}"
For a specific version:
VERSION=v0.1.0 curl -LO "https://github.com/confidential-devhub/cococtl/releases/download/${VERSION}/kubectl-coco-${OS}-${ARCH}" -
Validate (optional):
curl -LO "https://github.com/confidential-devhub/cococtl/releases/latest/download/kubectl-coco-${OS}-${ARCH}.sha256" echo "$(cat kubectl-coco-${OS}-${ARCH}.sha256)" | sha256sum --check
-
Install:
System-wide (requires sudo):
sudo install -m 0755 kubectl-coco-${OS}-${ARCH} /usr/local/bin/kubectl-coco sudo ln -sf /usr/local/bin/kubectl-coco /usr/local/bin/kubectl_complete-coco
Or user directory:
mkdir -p ~/.local/bin install -m 0755 kubectl-coco-${OS}-${ARCH} ~/.local/bin/kubectl-coco ln -sf ~/.local/bin/kubectl-coco ~/.local/bin/kubectl_complete-coco export PATH=$PATH:~/.local/bin # Add to ~/.bashrc or ~/.zshrc
-
Verify:
kubectl coco --version
git clone https://github.com/confidential-devhub/cococtl
cd cococtl
make build
sudo make installkubectl-coco supports command autocompletion for bash and zsh shells.
Prerequisites:
Install bash-completion.
For MacOS:
brew install bash-completion@2
# Add to your ~/.bash_profile:
[[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ]] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"
# Reload profile:
source ~/.bash_profileFor Linux:
# Ubuntu/Debian:
apt-get install bash-completion
# CentOS/RHEL:
yum install bash-completionInstallation:
For current session:
source <(kubectl-coco completion bash)For all sessions (permanent):
# MacOS:
kubectl-coco completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl-coco
# Linux:
kubectl-coco completion bash > /etc/bash_completion.d/kubectl-coco
# Then restart your shellFor kubectl plugin (kubectl coco):
Install kubectl completion first:
# MacOS:
kubectl completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl
# Linux:
kubectl completion bash > /etc/bash_completion.d/kubectlEnable completion if not already enabled:
echo "autoload -U compinit; compinit" >> ~/.zshrcInstall kubectl-coco completion:
kubectl-coco completion zsh > "${fpath[1]}/_kubectl-coco"Start a new shell for completion to take effect.
Note: The kubectl_complete-coco symlink (created during installation) enables kubectl coco plugin completion. If kubectl coco <TAB> doesn't work, verify:
ls -la /usr/local/bin/kubectl_complete-coco
# Should point to kubectl-cocoDeploy Trustee and create configuration (non-interactive by default):
kubectl coco initThis deploys Trustee to your current namespace and creates ~/.kube/coco-config.toml.
Interactive mode:
kubectl coco init --interactive # or -iWith custom Trustee:
kubectl coco init --trustee-url https://trustee.example.com:8080The kbs subcommand manages the Trustee Key Broker Service that stores your secrets.
kubectl coco kbs start --mode k8sDeploys Trustee to the current namespace and saves the admin private key to ~/.kube/coco-kbs-auth. The KBS URL is written to ~/.kube/coco-config.toml for use by subsequent commands.
# With custom namespace
kubectl coco kbs start --mode k8s --namespace coco-systemkubectl coco kbs start --mode external --url http://kbs.example.com:8080Records the KBS URL in config without deploying anything. Optionally specify --auth-dir to point at an existing admin key directory.
After kubectl coco apply generates a *-trustee-secrets.yaml, upload the secrets:
kubectl coco kbs populate -f app-trustee-secrets.yamlOther input modes:
# From a Kubernetes Secret
kubectl coco kbs populate --from-k8s-secret my-registry-secret -n my-namespace
# Single file to a specific KBS path
kubectl coco kbs populate --path default/myapp/password --resource-file /path/to/password.txt
# Direct URL (skips in-cluster port-forward)
kubectl coco kbs populate --kbs-url http://kbs.example.com:8080 --auth-key /path/to/private.key -f secrets.yamlThe initdata subcommand lets you create, inspect, and validate initdata independently of apply. This is useful for auditing initdata before deployment or generating it for use with external tooling.
Generate the raw initdata TOML from your config and save it to disk:
# From default config, save to ~/.kube/coco-initdata.toml
kubectl coco initdata create
# With a custom CA certificate (validates cert before embedding)
kubectl coco initdata create --cacert /path/to/ca.crt
# With a directory of CA certs
kubectl coco initdata create --capath /etc/ssl/certs
# Custom output path
kubectl coco initdata create --output /tmp/my-initdata.toml# Show the base64+gzip encoded blob (ready for use as an annotation value)
kubectl coco initdata dump
# Show the human-readable plaintext TOML
kubectl coco initdata dump --raw
# Read from a specific file
kubectl coco initdata dump --file /tmp/my-initdata.tomlThe default output of dump (without --raw) is the value to use for the
io.katacontainers.config.hypervisor.cc_init_data annotation.
# Validate a saved TOML file (checks version, algorithm, required keys, embedded certs)
kubectl coco initdata validate --file ~/.kube/coco-initdata.toml
# Validate the encoded blob from dump via pipe
kubectl coco initdata dump | kubectl coco initdata validateValidation checks:
versionis0.1.0andalgorithmissha256- Required keys
aa.tomlandcdh.tomlare present (policy.regois optional) - Any CA certificates embedded in
aa.tomlorcdh.tomlpass rustls compatibility checks
Basic usage:
kubectl coco apply -f app.yamlCommon options:
# Only transform, don't apply
kubectl coco apply -f app.yaml --skip-apply
# Use specific runtime class
kubectl coco apply -f app.yaml --runtime-class kata-remote
# Add attestation initContainer
kubectl coco apply -f app.yaml --init-container
# Enable secure access sidecar
kubectl coco apply -f app.yaml --sidecar
# Disable automatic secret conversion
kubectl coco apply -f app.yaml --convert-secrets=false
# Use custom config file
kubectl coco apply -f app.yaml --config /path/to/config.tomlSee TRANSFORMATIONS.md for detailed description on the transformations.
The explain command helps you understand what transformations are applied to your manifests:
# Analyze your manifest
kubectl coco explain -f your-app.yaml
# View built-in examples
kubectl coco explain --list-examples
# Learn with interactive examples
kubectl coco explain --example simple-pod
kubectl coco explain --example deployment-secrets
kubectl coco explain --example sidecar-serviceOutput formats:
# Human-readable (default)
kubectl coco explain -f app.yaml
# Side-by-side diff view
kubectl coco explain -f app.yaml --format diff
# Markdown for documentation
kubectl coco explain -f app.yaml --format markdown -o transformations.mdThe explain command provides:
- Educational analysis of each transformation
- Before/after comparisons for secrets, runtime, and initdata
- Learning points explaining why each change is needed
- Interactive examples to explore CoCo concepts
Perfect for learning how CoCo works without making any changes to your cluster.
The secure access sidecar provides mTLS-secured HTTPS access to your CoCo pods.
One-time setup:
kubectl coco init --enable-sidecarDeploy with sidecar:
# Basic usage
kubectl coco apply -f app.yaml --sidecar
# Enable port forwarding from primary container
kubectl coco apply -f app.yaml --sidecar --sidecar-port-forward 8888
# Custom SANs for LoadBalancer or Ingress
kubectl coco apply -f app.yaml --sidecar \
--sidecar-san-ips=203.0.113.10 \
--sidecar-san-dns=myapp.example.comNote: When --sidecar is enabled, a Kubernetes Service (ClusterIP type) is automatically created with the name <app-name>-sidecar to expose the sidecar's HTTPS port. You can convert it to NodePort or use it with an Ingress for external access.
See sidecar/README.md for detailed configuration and usage.
The configuration file (~/.kube/coco-config.toml) supports:
# Mandatory
trustee_server = 'https://trustee-kbs.default.svc.cluster.local:8080'
runtime_class = 'kata-cc'
# Optional
trustee_ca_cert = '/path/to/ca.crt'
kata_agent_policy = '/path/to/policy.rego'
init_container_image = 'quay.io/fedora/fedora:44'
init_container_cmd = 'curl http://localhost:8006/cdh/resource/default/attestation-status/status'
# Image-related (optional, for CDH [image] section)
container_policy_uri = 'kbs:///default/security-policy/test'
registry_cred_uri = 'kbs:///default/credential/test'
registry_config_uri = 'kbs:///default/registry-configuration/test'
# Custom annotations (optional, only non-empty values applied)
[annotations]
"io.katacontainers.config.runtime.create_container_timeout" = "120"
"io.katacontainers.config.hypervisor.machine_type" = "q35"
# Secure access sidecar (optional)
[sidecar]
enabled = true
image = "ghcr.io/confidential-devhub/coco-sidecar:latest" # Optional: custom sidecar image
https_port = 8443 # Optional: HTTPS port (default: 8443)
forward_port = 8888 # Optional: application port to forward
cpu_limit = "100m" # Optional: CPU limit
memory_limit = "128Mi" # Optional: memory limit
cpu_request = "50m" # Optional: CPU request
memory_request = "64Mi" # Optional: memory requestNote: TLS certificates are auto-generated per-app during kubectl coco apply --sidecar.
make buildmake testmake cleanApache License 2.0
Contributions are welcome! Please submit issues and pull requests to the repository.