CLI Reference

Type, default, and effect for every flag of every c8s command — install and uninstall, the CDS, allowlist, secrets and volumes, the in-pod fetchers, and the node-side daemons.

One section per command, mirroring the flag definitions in the c8s source. Each table lists every flag of the command above it.

The c8s binary also responds to the symlink aliases get-cert, ratls-mesh, and nri-image-policy (each auto-prepends the matching subcommand).

c8s install

Install the c8s operator, CRDs, attestation-api, and component charts via Helm. Flags are registered with cobra/pflag.

FlagTypeDefaultRequiredDescription
--namespacestringc8s-systemNonamespace to install into
--releasestringc8sNoHelm release name
-f, --valuesstring slicenilNovalues files (repeatable)
--waitbooltrueNowait for the release to become ready (helm --wait)
--install-crdsbooltrueNoinstall chart CRDs (false passes helm --skip-crds)
--webhook-cert-fs-groupint6465532NofsGroup for injected certificate volume
--webhook-get-cert-renew-intervalduration6hNorenewal interval for injected workload certificates
--webhook-get-cert-run-as-userint6465532NorunAsUser for injected get-cert containers
--webhook-get-cert-run-as-groupint6465532NorunAsGroup for injected get-cert containers
--webhook-get-cert-run-as-non-rootbooltrueNoset runAsNonRoot for injected get-cert containers
--single-nodeboolfalseNosingle-node / single-CVM cluster: clear the dedicated-CDS-node selector and taint toleration so every node is CDS-eligible (no role=cds label or dedicated node needed). Sets cds.node.selector={} and cds.node.tolerations=[]
--volumesboolfalseNoDeploy volumed, the node agent for encrypted volumes.
--cvm-modestring""YesDeployment shape: bare-metal (self-managed confidential node), gke (GKE confidential nodes), or aks (Azure vTPM nodes). All modes use one node CVM as the trust domain.
--hardware-platformstring""YesCPU-level TEE hardware (orthogonal to --cvm-mode): sev-snp (/dev/sev-guest) or tdx (Intel TDX, /dev/tdx-guest). Under --cvm-mode=aks both ride the Azure vTPM (/dev/tpm0, no guest device): sev-snp selects the az-snp shape, tdx selects az-tdx
--image-tagstring""Nocomponent image tag to resolve digests at (default: the CLI build version, or main for an unstamped build); override to pin a specific branch/tag/release
--resolve-digestsbooltrueNoresolve each component image tag to its registry digest (via crane), pin it, and add the resolved images to the NRI allowlist. Pass --resolve-digests=false when supplying digests via -f
--attestbooltrueNodeploy the router attestation sidecar that serves /.well-known/c8s/ (browser and CLI verification via c8s-verify); --attest=false sets router.attest.enabled=false and omits it
--node-cidrstring slicenilNoCIDR(s) containing node sandbox inventories; by default CDS derives one host route per node.
--measurementsstring slicenilNoExpected node CVM launch measurement(s), pinned into CDS and ratls-mesh; empty leaves measurement pinning disabled (unsafe). Cannot be combined with --measurements-config.
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs, each matched as a whole image. Templated down to cds and ratlsMesh, and fanned out flat so every component keeps pinning. Cannot be combined with --measurements or --rtmrs
--rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> completing --measurements on --hardware-platform=tdx (repeatable / comma-separated); sets cds.rtmrs and ratlsMesh.rtmrs. RTMR[1] is the guest kernel, RTMR[2] the command line carrying the dm-verity root hash; without them the measurement pin covers TDVF firmware only. Ignored for SEV-SNP evidence. Cannot be combined with --measurements-config
--image-pull-secretstring""Noname of an existing kubernetes.io/dockerconfigjson Secret in the release namespace; the chart appends it to every component's imagePullSecrets, so all pods pull the c8s images from an authenticated registry from first start. The Secret is never created or managed by the install — install fails fast when it is missing or has the wrong type
--workload-refstring slicenilNoexisting workload to adopt as a confidential workload, as <cw-id>=<namespace>/<kind>/<name>[:<port>]; repeatable. Kind is any resource exposing a pod template at spec.template (deployment, statefulset, daemonset, or an operator CRD such as <kind>.<group>); install patches the pod template with confidential.ai/cw=<cw-id> once c8s is ready. The optional :<port> is the router upstream port, required on the ref --upstream selects
--upstreamstring""Noconfidential.ai/cw id of the adopted --workload-ref workload router routes its catch-all to; derives the mesh-wrapped upstream c8s-<id>.<ns>.svc.cluster.local:<port> from that ref's :<port>. Without this or a verified-https router.upstream, router renders no catch-all route until one is attached
--operator-keysstring""Nopath to a PEM bundle of operator EC public keys that authorize c8s allowlist writes; sets cds.operatorKeys. Without it, allowlist writes are disabled (reads still served). See creating the operator credential
--forceboolfalseNoProceed past guarded install prompts, including missing operator keys or a platform image-policy floor that would deny system pods.

c8s uninstall

Uninstall the c8s Helm release and sweep c8s host artifacts, including image-policy and mesh state. Requires Helm and kubectl on PATH.

FlagTypeDefaultRequiredDescription
--namespacestringc8s-systemNonamespace the release was installed into
--releasestringc8sNoHelm release name
--waitbooltrueNoWait for the Helm release deletion to finish.
--host-sweepbooltrueNoSweep c8s host artifacts after deleting the release.
--host-sweep-onlyboolfalseNoskip the helm uninstall and run only the host sweep — for a cluster whose release is already gone (e.g. a previous bare helm uninstall) but whose nodes still carry c8s artifacts. Uses the chart defaults and the distro detected from the cluster when the release values are unavailable
--forceboolfalseNoAllow uninstall while pods hold c8s encrypted volumes; open mappings can block cleanup.
--delete-crdsboolfalseNoalso delete the ConfidentialWorkload CRD — this deletes every ConfidentialWorkload object in the cluster with it
--delete-namespaceboolfalseNoalso delete the release namespace (and everything left in it, e.g. an operator-created image pull Secret)

c8s render-values

Print the resolved Helm values an install would apply, to stdout — without contacting a cluster. Useful for feeding a GitOps consumer (e.g. a Flux HelmRelease's valuesFrom) instead of recomputing digests and device mappings. Unlike install, the host distro is not autodetected — pass --distro to pin it. Still needs the registry reachable for the default digest resolution (--resolve-digests=true).

FlagTypeDefaultRequiredDescription
--distrostring""Nohost Kubernetes distro (k8s | rke2); install autodetects it, render-values does not, so pass it to pin the value (unset leaves the chart default)
--single-nodeboolfalseNosingle-node / single-CVM cluster: clear the dedicated-CDS-node selector and toleration (cds.node.selector={}, cds.node.tolerations=[])
--volumesboolfalseNoDeploy volumed, the node agent for encrypted volumes.
--cvm-modestring""YesDeployment shape: bare-metal (self-managed confidential node), gke (GKE confidential nodes), or aks (Azure vTPM nodes). All modes use one node CVM as the trust domain.
--hardware-platformstring""YesCPU-level TEE hardware (orthogonal to --cvm-mode): sev-snp (/dev/sev-guest) or tdx (Intel TDX, /dev/tdx-guest). Under --cvm-mode=aks both ride the Azure vTPM (/dev/tpm0): sev-snp renders az-snp, tdx renders az-tdx
--measurementsstring slicenilNoExpected node CVM launch measurement(s), pinned into CDS and ratls-mesh; empty leaves measurement pinning disabled (unsafe). Cannot be combined with --measurements-config.
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs, each matched as a whole image; emits cds.measurementsConfig + ratlsMesh.measurementsConfig and the flat pins alongside. Cannot be combined with --measurements or --rtmrs
--rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> completing --measurements on --hardware-platform=tdx (repeatable / comma-separated); emits cds.rtmrs + ratlsMesh.rtmrs. Ignored for SEV-SNP evidence. Cannot be combined with --measurements-config
--resolve-digestsbooltrueNoresolve each component image tag to its registry digest (via crane), pin it, and enable the NRI allowlist derivation
--image-tagstring""Nocomponent image tag to resolve digests at (default: the CLI build version, or main)
--image-pull-secretstring""Noname of an existing dockerconfigjson Secret the chart wires into every component's imagePullSecrets
--operator-keysstring""Nopath to a PEM bundle of operator EC public keys that authorize c8s allowlist writes; the file's content is embedded as cds.operatorKeys in the emitted values (the chart value is PEM content, never a path)
--install-crdsbooltrueNoemit values for chart CRDs (false sets statusMirror.enabled=false, matching install --install-crds=false)
--workload-refstring slicenilNoadopted workload as <cw-id>=<namespace>/<kind>/<name>[:<port>]; repeatable. Used here only to derive --upstream's address (render-values patches nothing)
--upstreamstring""Noconfidential.ai/cw id of the adopted --workload-ref workload router routes its catch-all to; derives router.upstream.address c8s-<id>.<ns>.svc.cluster.local:<port> from that ref's :<port>

c8s operator

Run the c8s controller-manager and admission webhook.

FlagTypeDefaultRequiredDescription
--metrics-bind-addressstring:8080Noaddress for Prometheus metrics
--health-probe-bind-addressstring:8081Noaddress for health/readyz probes
--leader-electbooltrueNoenable leader election for HA
--leader-election-namespacestringc8s-systemNonamespace holding the leader-election Lease
--status-mirror-enabledbooltrueNoenable CRD-backed ConfidentialWorkload status mirror controller
--get-cert-imagestring""Noimage reference the webhook injects for get-cert containers (empty = webhook disabled)
--cds-urlstring""NoCDS Service URL the injected get-cert containers POST to
--attestation-api-urlstring""Noattestation-api endpoint (empty = no verification)
--cds-measurementsstring slicenilNoSHA-384 hex launch measurement(s) the injected secret fetcher requires CDS to present (repeatable; empty pins none)
--cds-rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> the injected sidecars additionally hold CDS to (repeatable; ignored for SEV-SNP evidence, empty pins no registers)
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs; any listed image may serve as CDS, and the injected sidecars carry the digests flat. Cannot be combined with --cds-measurements or --cds-rtmrs
--exclude-namespacesstring slicenilNoextra namespaces the startup reinject sweep skips (mirrors webhook.extraExcluded)
--webhook-config-namestring""NoMutatingWebhookConfiguration to patch caBundle (empty = skip)
--webhook-service-namestring""Nowebhook Service name (defaults to c8s)
--webhook-service-namespacestring""Nowebhook Service namespace (defaults to --leader-election-namespace)
--cert-fs-groupint6465532NofsGroup applied to injected pods when unset (-1 disables mutation)
--get-cert-renew-intervalduration2hNorenewal interval for injected workload certificates
--get-cert-run-as-userint6465532NorunAsUser for injected get-cert containers
--get-cert-run-as-groupint6465532NorunAsGroup for injected get-cert containers
--get-cert-run-as-non-rootbooltrueNoset runAsNonRoot for injected get-cert containers
--workload-claims-host-dirstring""Nohost directory holding the nri-image-policy inventory socket (Node-as-CVM); when set, the webhook mounts it into the c8s-cert container and injects --workload-claims so get-cert redeems a sandbox token

c8s cds

Run the Certificate Distribution Service (CDS). Requires --ratls-platform, --attestation-api-url, and --allowlist-db.

FlagTypeDefaultRequiredDescription
--hoststring0.0.0.0Nolisten host
-p, --portint8443Nolisten port
--log-levelstringinfoNolog level: debug, info, warn, error
--attestation-api-urlstring""YesURL of the attestation-api service
--ca-common-namestringc8s Mesh CANocommon name for the in-memory generated mesh CA
--ca-cert-validityduration8760hNovalidity period of the in-memory mesh CA certificate
--measurementsstring slicenilNoSHA-384 hex launch measurements allowed to call /attest (repeatable / comma-separated); empty = no pinning (UNSAFE)
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs, each matched as a whole image (launch digest plus, on TDX, that image's registers). Every listed image may call /attest, and the same file pins CDS for the components that dial it, so any listed image may serve as CDS. Cannot be combined with --measurements or --rtmrs
--rtmrsstring slicenilNoTDX RTMR pins <index>=<sha384-hex> required of TDX callers on /attest and /attest-key (repeatable); RTMR[1] pins the guest kernel, RTMR[2] the command line carrying the dm-verity root hash. SNP evidence is unaffected; empty leaves the TDX reference values covering TDVF firmware only (UNSAFE)
--jwt-clock-skewint6430NoEAR JWT exp/nbf/iat clock-skew tolerance in seconds; also applied to operator write tokens
--cert-ttlduration24hNoTTL of the leaf and EAR /attest issues, capped at the built-in 24h leaf ceiling
--named-cert-ttlduration6hNoupper bound on the TTL of a leaf carrying a matched-workload stamp (never applied to membership-only leaves); must be positive and may only shorten the built-in 6h ceiling
--challenge-ttlduration1mNolifetime of an attestation challenge nonce; issuance and /secrets keep separate pools
--request-timeoutduration5sNoper-request timeout on /attest and /sign-csr, and on the inventory callback (0 disables)
--max-request-sizeint6465536Nomax request body bytes on write endpoints; must be positive
--read-timeoutduration10sNoHTTP server read timeout
--read-header-timeoutduration5sNoHTTP server read-header timeout
--write-timeoutduration10sNoHTTP server write timeout
--idle-timeoutduration20sNoHTTP server idle timeout
--max-header-bytesint1048576Nomaximum HTTP request header bytes
--san-validationbooltrueNorequire CSR IP SANs to equal the request source IP (false rejects CSRs carrying IP SANs)
--dns-san-patternstring slicenilNoregex a CSR's DNS SANs may match in full; repeatable, and a SAN passes if it matches any one. The chart always supplies the in-cluster Service DNS pattern and appends a public hostname when router fronts a routed domain. A CSR carrying DNS SANs is rejected when none are set
--allowed-cn-patternstring""Noregex the CSR Subject CN must match in full (empty disables)
--readiness-intervalduration10sNointerval of the attestation-api health check behind /readyz; must be positive
--min-ca-validityduration1hNo/readyz fails when the loaded mesh CA has less than this remaining lifetime
--allowlist-dbstring""Yespath to the allowlist SQLite database
--allowlist-persistentboolfalseNowhether --allowlist-db is on durable storage; false makes the CDS warn at startup that operator-added digests and the mesh CA do not survive a restart
--sandbox-inventory-cidrstring slicenilNoCIDR(s) holding the node addresses the CDS may dial for a sandbox's admission inventory (repeatable); it is what stops a workload pointing the callback at its own pod IP. Unset, the CDS derives one host route per node from the live node list and refuses sandbox tokens until that syncs
--allowlist-seedstring""Nopath to a JSON allowlist (version + digests map) seeded into the store at startup before serving; missing digests are added, existing entries are left untouched (empty disables seeding)
--operator-keysstring""Nopath to a PEM bundle of pinned operator EC public keys; /allowlist writes (POST/PUT/DELETE) require an operator token signed by one of them (empty = writes disabled, reads still served)
--rate-limitfloat6410Nomax requests per second per source IP on attestation endpoints
--rate-burstint20Nomax burst size per source IP
--rate-limiter-max-entriesint10000Nomax entries in the per-IP rate limiter; once full, a new source is refused until entries idle out
--rate-limiter-evict-intervalduration1mNointerval for per-IP rate limiter eviction sweep
--rate-limiter-idle-timeoutduration5mNoidle duration before a per-IP rate limiter entry is evicted
--secrets-max-pathsint1024Nomax distinct secret paths held in memory across every workload; must be positive
--secrets-max-paths-per-workloadint64Nomax secret paths one allowlist entry may hold; must be positive and below --secrets-max-paths
--secrets-max-value-bytesint4096Nomax bytes in one secret value; must be at least 32, the size of every value the CDS generates
--sandbox-ledger-max-entriesint10000Nomax sandbox-to-inventory bindings held in memory; must be positive
--ratls-platformstring""YesTEE platform for the RA-TLS serving cert: sev-snp or tdx (the snp/az-snp/gcp-snp and az-tdx/gcp-tdx aliases are normalized)
--ratls-cert-ttlduration24hNoTTL of the RA-TLS serving certificate the CDS presents

c8s allowlist

Read and mutate the CDS-served allowlist that nri-image-policy enforces. It has two layers: a floor of image digests admitted by digest alone, and named workload entries that pin an init/main container set with per-container argv and path policy. Reads are unauthenticated; writes are signed with the operator EC private key whose public half the CDS pins (cds.operatorKeys, set by install --operator-keys). See The Allowlist for usage.

SubcommandArgumentsPurpose
listlist the current allowlist floor and workload entries
export[file]write the full allowlist as canonical JSON to a file (default stdout) for backup or re-upload
diff<file>show how an allowlist file differs from the live allowlist
lint<file|->validate an allowlist file and report semantic findings; never contacts the CDS
inspect-image<ref>resolve an image reference via crane and print its digest plus baked Entrypoint/Cmd; registry-only
add<digest> <image>add a single image digest to the floor (operator key required)
remove<digest> [<digest>...]remove one or more image digests from the floor (operator key required)
upload<file>atomically replace the entire allowlist — floor and workload entries — with the contents of a file (operator key required)
workload listlist workload entries
workload get<name>print one workload entry as canonical JSON
workload derive<name> <file|->print a workload entry built from a Pod, Deployment, StatefulSet or DaemonSet given as JSON; contacts nothing
workload apply<file|->upsert workload entries from a file, each replaced whole (operator key required)
workload edit<name>fetch a workload entry, edit it in $EDITOR, and apply the result (operator key required)
workload delete<name> [<name>...]delete one or more workload entries (operator key required)

Persistent flags, registered on every subcommand:

FlagTypeDefaultRequiredDescription
--urlstring""Yesrouter or direct CDS base URL; required by every subcommand that contacts the CDS (lint and inspect-image do not). A router front door is accepted only when its discovery document reports public_tls.mode=cds; a WebPKI front door is refused. A direct URL is verified by RA-TLS on the CDS serving cert. Plaintext http:// is refused without --insecure
--measurementsstring slicenilNoallowed SHA-384 hex launch measurement(s) of the attested endpoint (repeatable / comma-separated) — the router's value for a front door, the CDS's value for a direct URL; empty accepts any attested build on a read (UNSAFE) and is refused on a write
--measurements-filestring""Nofile of allowed launch measurements, one hex digest per line; merged with --measurements
--timeoutduration15sNoper-request timeout
--operator-keystring""Nooperator EC private key PEM file whose public key is pinned on CDS via --operator-keys (env C8S_OPERATOR_KEY; the flag wins); required for writes
-o, --outputstringtextNooutput format: text or json
--insecureboolfalseNodev/test only: allow a plaintext http:// CDS URL, skipping RA-TLS attestation of CDS

Per-subcommand flags:

FlagTypeDefaultRequiredDescription
--exit-codeboolfalseNodiff only: exit non-zero when the file and the live allowlist differ
--onlineboolfalseNolint only: also check each digest exists in its registry via crane
--strictboolfalseNolint, upload: treat lint warnings as fatal (lint errors already fail on their own)
--cvm-modestring""Nolint only: deployment-mode hint for warnings about mount and environment policies; use the mode targeted by the allowlist
--dry-runboolfalseNoadd, remove: print the intended change without calling CDS; upload: show the diff without replacing the allowlist; workload apply: show the diff without writing any entry
--forceboolfalseNoupload only: upload even if core c8s components are missing from the file
--requirestring slicenilNoupload only: component identifiers that must appear in the uploaded image refs (overrides the default set cds, ratls-mesh, nri-image-policy, attestation-api, nginx)
--labelstring""Noworkload derive only: label written into the derived entry
--secret-readstring arraynilNoworkload derive only: grant read on this secret path (repeatable); with none the derived entry carries no secrets block
--envstring""Noworkload derive only: environment policy for every container, any or deny
--env-filestring""Noworkload derive only: JSON file mapping container names to explicit environment policies, including exact values

c8s secrets

Write operator-supplied values into the CDS secret store, and report why a sandbox does or does not receive them. CDS releases a value to a pod when the containers running in that pod's sandbox match a workload entry whose secrets grant covers the path; the grant is written with c8s allowlist workload apply. Values are held in the CDS process and nowhere else, so a CDS restart empties the store. See Secrets.

SubcommandArgumentsPurpose
put<path>store a value at a secret path, read from stdin or --from-file
explainprint the release decision CDS reaches for one sandbox

put sends the bytes exactly as read, including any trailing newline, and prints the byte count. Both subcommands sign their request with the operator EC private key whose public half the CDS pins (cds.operatorKeys, set by install --operator-keys).

Persistent flags, registered on every subcommand:

FlagTypeDefaultRequiredDescription
--urlstring""Yesrouter or direct CDS base URL. A router front door is accepted only when its discovery document reports public_tls.mode=cds; a direct URL is verified by RA-TLS on the CDS serving cert. Plaintext http:// is refused without --insecure
--measurementsstring slicenilNoallowed SHA-384 hex launch measurement(s) of the attested endpoint (repeatable / comma-separated) — the router's value for a front door, the CDS's value for a direct URL; empty accepts any attested build on a read (UNSAFE) and is refused on a write
--measurements-filestring""Nofile of allowed launch measurements, one hex digest per line; merged with --measurements
--timeoutduration15sNoper-request timeout
--operator-keystring""Nooperator EC private key PEM file whose public key is pinned on CDS via --operator-keys (env C8S_OPERATOR_KEY; the flag wins). Both subcommands sign, so one of the two must be set
--insecureboolfalseNodev/test only: allow a plaintext http:// CDS URL, skipping RA-TLS attestation of CDS

Per-subcommand flags:

FlagTypeDefaultRequiredDescription
--from-filestring""Noput only: read the value from this file instead of stdin
--overwriteboolfalseNoput only: replace a value already at the path. Without it an occupied path is refused, and the error names what is there
--mesh-castring""Yesput only: PEM bundle of the mesh CA this CDS must serve, the same anchor c8s verify --mesh-ca takes. The write is refused unless every certificate CDS serves at /ca is in the bundle. Required unless --force; a plaintext --insecure endpoint is exempt
--forceboolfalseNoput only: write without checking the CDS mesh CA against --mesh-ca. Unrelated to --overwrite
--dry-runboolfalseNoput only: print the intended change without calling CDS
--sandboxstring""Yesexplain only: sandbox ID to report on. It is carried on the pod's certificate; c8s verify prints it
--jsonboolfalseNoexplain only: print the raw report as JSON

c8s volume

Build an encrypted volume, store its key in the CDS secret store, and present the image to a node as a disk. create packages --source into an erofs image, formats a dm-verity tree over it, encrypts the pair to --out, writes the key blob to --escrow-out, and puts the key at --path in the store; with --mutable it builds a writable ext4 of --size instead, with no integrity protection. It then prints the pod annotations and the allowlist grant to apply; it modifies no workload. The image is ciphertext and can reach the node by any route, including through the untrusted host, attached as a raw block device with disk serial c8s-vol-<name>. create needs mkfs.erofs and veritysetup on PATH, or mkfs.ext4 with --mutable. The key exists in exactly two places — the CDS process and the escrow file — and a key path is create-only: CDS refuses a --path that already holds a value. See Volumes.

SubcommandArgumentsPurpose
createbuild an encrypted volume image and store its key
attach<name>present a volume image on this node as a disk with serial c8s-vol-<name>, through LIO's loopback target
detach<name>remove a volume's disk from this node, leaving the image and the stored key alone

attach and detach run on the node as root, and are needed only where the hypervisor cannot give a disk a serial of its own — a QEMU/KVM node attaches the image with virtio-blk instead.

Persistent flags, registered on every subcommand:

FlagTypeDefaultRequiredDescription
--urlstring""Yesrouter or direct CDS base URL, verified as for c8s secrets; required by create and not read under --dry-run. attach and detach inherit it and never contact CDS
--measurementsstring slicenilNoallowed SHA-384 hex launch measurement(s) of the attested endpoint (repeatable / comma-separated); empty accepts any attested build on a read (UNSAFE) and is refused on the store write
--measurements-filestring""Nofile of allowed launch measurements, one hex digest per line; merged with --measurements
--timeoutduration15sNoper-request timeout
--operator-keystring""Nooperator EC private key PEM file whose public key is pinned on CDS via --operator-keys (env C8S_OPERATOR_KEY; the flag wins); required for the store write
--insecureboolfalseNodev/test only: allow a plaintext http:// CDS URL, skipping RA-TLS attestation of CDS

create flags:

FlagTypeDefaultRequiredDescription
--namestring""Yesvolume name; forms the device serial c8s-vol-<name>, so a DNS-1123 label of at most 12 characters
--sourcestring""Yesdirectory whose contents become the volume; required for an immutable volume, an optional preload with --mutable
--mutableboolfalseNobuild a writable ext4 volume instead of an immutable, dm-verity-protected one. A mutable volume has no integrity protection: the host can flip bits or roll it back undetected
--sizestring""Nomutable filesystem size, e.g. 50Gi; inferred from --source when one is given, required with --mutable and no --source, and refused without --mutable
--outstring""Yespath the encrypted image is written to; must not exist
--pathstring""Yessecret-store path for the key, e.g. /tenant-a/volumes/weights; absolute, clean, no wildcards
--escrow-outstring""Yespath the key blob is written to, mode 0600; must not exist. It is the only copy of the key outside CDS
--nodestring""Nonode holding the device; emitted as a nodeSelector on the printed annotations
--work-dirstring""Nodirectory for build intermediates (default: a temp dir); they are removed either way
--dry-runboolfalseNobuild the image and write the escrow file, but do not call CDS

attach and detach flags:

FlagTypeDefaultRequiredDescription
--imagestring""Yesattach only: path on this node to the encrypted image. The device serves the file opened here, not the path
--config-rootstring/sys/kernel/configNoconfigfs mount LIO is driven through
--jsonboolfalseNoattach only: print the name and serial as JSON

c8s cds-attest

Run the router attestation + over-encryption sidecar (the c8s-verify/v1 server side). Fronted by the router nginx (chart flag router.attest.enabled), it serves the LB's attestation at /.well-known/c8s/attest-pq (encrypted session) and /.well-known/c8s/attest-lb (ordinary TLS), runs the post-quantum handshake, and forwards decrypted tunnel traffic to the backend. It's a chart-managed component, not normally run by hand — see Consumer Verification for the protocol.

FlagTypeDefaultRequiredDescription
--session-max-agedurationNoAbsolute lifetime of an attestation session.
--hoststring127.0.0.1Nolisten host (loopback: nginx proxies to it)
-p, --portint8800Nolisten port
--log-levelstringinfoNolog level: debug, info, warn, error
--attestation-api-urlstring""Noattestation-api URL (production evidence source); one of --attestation-api-url or --evidence-fixture must be set
--platformstring""YesTEE platform: snp | az-snp | az-tdx | tdx
--generationstringgenoaNoAMD processor generation for the browser's bare-SNP verifier (--platform snp only, ignored otherwise): milan | genoa | turin
--serving-cert-filestring""Nopath to the LB serving-leaf PEM (the cert nginx presents); in cds front-door mode /.well-known/c8s/attest-lb binds report_data to this exact leaf DER, re-read per request to follow get-cert rotation
--mesh-identity-cert-filestring""NoTEE-held mesh leaf PEM whose possession both attestation endpoints prove, re-read per request. Separate from --serving-cert-file, which may name a host-visible public TLS credential
--mesh-identity-key-filestring""NoTEE-held mesh leaf private key matching --mesh-identity-cert-file, re-read per request
--mesh-identity-ca-filestring""Nomesh CA bundle that issued the identity leaf, re-read per request. All three --mesh-identity-* flags must be set; otherwise /.well-known/c8s/attest-pq returns 501 binding_unavailable
--expected-workloadstring""Nogate /readyz on the mesh identity leaf carrying a matched-workload stamp with this exact name; empty keeps /readyz unconditionally 200
--evidence-fixturestring""Nodev only: serve recorded TEE evidence from this file instead of the attestation-api
--session-ttlduration5mNopending-handshake TTL and established-session idle TTL
--read-header-timeoutduration5sNoHTTP read-header timeout
--upstreamstring""Nobackend base URL to forward decrypted traffic to (http:// rides the RA-TLS mesh; https:// does mTLS). Empty uses an echo backend (demo)
--upstream-castring""NoPEM CA bundle to verify an https upstream (the mesh CA)
--upstream-certstring""Noclient cert presented to an https upstream (the CDS-issued LB cert)
--upstream-keystring""Noclient key for --upstream-cert
--upstream-server-namestring""NoSNI / verification name for an https upstream

c8s allowlist-proxy

Publish the CDS allowlist API through router. Public TLS terminates at the router nginx; this process makes the second trust hop, verifying CDS's RA-TLS serving certificate before forwarding the request. Path, query, and Authorization header are forwarded byte-for-byte, so the operator token's method/path/body binding survives the hop. It routes /allowlist and /allowlist/ to CDS, answers /healthz itself, and binds loopback only. A chart-managed component, not run by hand — see c8s allowlist for the client side.

FlagTypeDefaultRequiredDescription
--hoststring127.0.0.1Nolisten host; must be a loopback IP (nginx is the public listener)
-p, --portint8801Nolisten port; 1–65535
--cds-urlstring""YesCDS base URL; must be an https (RA-TLS) origin with no credentials, path, query, or fragment
--cds-measurementsstring slicenilNoallowed CDS SHA-384 hex launch measurement(s) (repeatable / comma-separated); empty accepts any attested CDS (UNSAFE)
--cds-rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> CDS must additionally satisfy (repeatable / comma-separated); ignored when CDS presents SNP evidence, and empty pins no registers
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs, each matched as a whole image; any listed image may serve as CDS. Cannot be combined with --cds-measurements or --cds-rtmrs
--attestation-api-urlstring""Noattestation-api URL used to verify CDS evidence
--request-timeoutduration30sNotimeout for one request to CDS; must be positive
--read-header-timeoutduration5sNoHTTP request-header timeout; must be positive

c8s verify

Verify a deployed component's TEE attestation evidence (AMD SEV-SNP or Intel TDX) against the hardware signature chain plus a measurement, TCB, and policy check. Verification runs in-process with attestation-go (the Go port of the attestation-rs engine the cluster runs) — no container runtime is needed; a bare SEV-SNP report needs outbound HTTPS to AMD KDS (kdsintf.amd.com) to fetch its VCEK, bounded by --timeout. Takes a [target] (a URL or host:port) as its positional argument, or --url. c8s cds verify is the same command with CDS presets (--kind cds, default port 8443); --mode stays auto, which resolves to ratls-cert for a CDS target. See the verification guide for the end-to-end workflow.

FlagTypeDefaultRequiredDescription
--urlstring""Notarget URL or host:port (alternative to the positional argument)
--kindstringautoNocomponent being verified: cds, lb, workload, or auto
--modestringautoNoevidence mode: auto, ratls-cert, discovery, or attest-pq; any other value is a usage error
--discovery-pathstring/v1/discoveryNopath of the LB discovery document (discovery mode)
--server-namestring""NoTLS SNI server name (for port-forward / routed domains)
--timeoutduration15sNoper-attempt timeout (evidence fetch and AMD KDS collateral fetch)
--from-filestring""Noverify evidence from a saved PEM certificate or attestation-response JSON instead of dialing
--measurementsstring slicenilNoallowed SHA-384 hex launch measurement(s) (repeatable / comma-separated); empty = no pinning (UNSAFE). On TDX this pins MRTD only, so it covers the firmware alone; cannot be combined with --image-manifest or --measurements-config
--measurements-filestring""Nofile of allowed launch measurements, one hex digest per line; feeds the same allowlist as --measurements and carries the same exclusions
--image-manifeststring""Nobuild-artifact manifest of the expected TDX guest image (JSON object with mrtd, rtmr1, rtmr2, each 96 lowercase hex chars); pins all three registers exactly against that one manifest. Cannot be combined with --measurements, --measurements-file, --measurements-config, or a by-hand --rtmr 1=/--rtmr 2=. TDX evidence only — a policy error against SEV-SNP evidence
--expected-rtmr3string""NoDEPRECATED — use --rtmr 3=<sha384-hex>, which is the identical pin under identical rules. Retained so existing invocations keep working
--operator-pkeystring""Nopath to the operator public key PEM (the verbatim bytes the guest initrd hashed); derives the RTMR[3] pin as the bare operator-key seed SHA-384(0x00*48 ‖ SHA-384(pubkey)). Requires --image-manifest, and excludes the other two RTMR[3] spellings. TDX evidence only — a policy error against SEV-SNP evidence
--rtmrstring slicenilNoexpected TDX runtime measurement register(s) as <index>=<sha384-hex> (repeatable / comma-separated). Index 0 is rejected, 1 and 2 cannot be combined with --image-manifest, and 3 requires it. TDX evidence only — a policy error against SEV-SNP evidence
--measurements-configstring""Nomeasurements config listing the VM images this cluster runs; pins the target to those images and, for --kind cds, additionally fails unless the set served at /measurements is identical. Cannot be combined with --measurements, --measurements-file, or --image-manifest
--operator-keysstring""NoPEM bundle of expected operator public keys; verification fails unless the key set the attested target serves at /operator-keys matches it (--kind cds targets)
--sandbox-idstring""Noexpected CRI pod sandbox ID on the target's leaf; requires --mesh-ca
--workloadstring""Noexpected matched-workload name on the target's leaf; requires --mesh-ca, since CDS's signature on the leaf is what vouches for the stamp
--allowliststring""Nofile holding the exact canonical allowlist bytes as served by GET /allowlist; the leaf's stamped policy digest must equal SHA-256 of those bytes and the stamped name must resolve in the document. Requires --mesh-ca
--mesh-castring""NoPEM bundle of the CDS mesh CA; when set, the target's leaf must chain to it, which is what authenticates the reported sandbox ID. In attest-pq mode it also upgrades a responder-chosen chain anchor from a partial verdict to a verified one
--init-datastring""Noexpected init-data digest: SHA-256 hex of the init-data document the target guest must carry; verification fails unless the evidence commits exactly this digest
--allow-debugboolfalseNoaccept debug-enabled guests
--min-tcb-bootloaderuint0Nominimum bootloader TCB component (0–255); SEV-SNP evidence only, a policy error against TDX evidence
--min-tcb-teeuint0Nominimum TEE TCB component (0–255); SEV-SNP evidence only, a policy error against TDX evidence
--min-tcb-snpuint0Nominimum SNP firmware TCB component (0–255); SEV-SNP evidence only, a policy error against TDX evidence
--min-tcb-microcodeuint0Nominimum microcode TCB component (0–255); SEV-SNP evidence only, a policy error against TDX evidence
--expected-report-datastring""Nohex REPORTDATA / TPM-nonce anchor override for bare evidence files (1–64 bytes, exactly as bound by the producer)
-o, --outputstringtextNooutput format: text or json
--show-evidenceboolfalseNoprint the raw report fields

Exit codes are a CI contract: 0 verified · 1 usage · 2 verification/policy failed · 3 evidence unavailable (unreachable / unparseable) · 4 partially verified — the evidence verified, but a property it presents is not proven (a serving key the evidence does not attest, no observable handshake, or a responder-chosen chain anchor).

c8s measurements

Work with measurements config files. A measurements config pins the VM images a cluster accepts; each entry is one image, matched as a whole — a launch digest together with the runtime registers measured from the same build. One file describes one platform: tee is either sev-snp or tdx, and a cluster mixing SNP and TDX images is not supported.

derive reads the manifest.json of each built confidential-os-builder image and writes the config. An SEV-SNP image contributes one entry per vCPU variant, named <image>-smp<N>, because the launch digest covers one VMSA page per vCPU — so even a single-image SNP cluster needs a multi-entry config. A TDX image contributes one entry: its MRTD with RTMR[1] and RTMR[2]. RTMR[0] is never pinned, since it varies with the vCPU and memory shape.

lint loads a config, reports the platform and the entry count, and takes no flags.

derive flags:

FlagTypeDefaultRequiredDescription
--teestring""Noplatform to derive for, sev-snp or tdx; required when an image is built for both
--outstring""Nowrite the config to this path instead of stdout

c8s get-cert

Obtain a signed certificate via the CDS attestation flow. Generates an ECDSA P-256 key (or loads --key), builds a CSR for --san, and exchanges it for a signed chain over RA-TLS. Requires --cds-url, --attestation-api-url, and --san.

FlagTypeDefaultRequiredDescription
--ca-watch-intervaldurationNoInterval for refreshing the CDS CA certificate.
--cds-urlstring""YesURL of the CDS service (e.g. https://cds:8443); the scheme must be https, since CDS is reached over RA-TLS
--cds-measurementsstring""Nocomma-separated SHA-384 hex launch measurements for CDS RA-TLS verification (empty = accept any attested CDS, and refused outright with --workload-claims-guest, where the host writes the argv)
--cds-rtmrsstring""Nocomma-separated TDX RTMR pins <index>=<sha384-hex> (index 1, 2, or 3) CDS's RA-TLS certificate must additionally satisfy; ignored when CDS presents SEV-SNP evidence (empty = launch-digest pinning only)
--attestation-api-urlstring""YesURL of the node-local attestation-api (e.g. http://localhost:8400, or unix:// plus the on-node socket path the chart wires)
-o, --outstring""Nopath to write the signed certificate chain PEM (stdout if omitted)
--ca-outstring""Nopath to write just the mesh CA bundle PEM (the issuer certs trailing the leaf in the CDS chain), e.g. for nginx to serve at a discovery endpoint without a separate ConfigMap
--keystring""Nopath to a PEM private key to use for the CSR (ephemeral if omitted)
--key-outstring""Nopath to write the generated private key PEM (ephemeral keys only); an existing key at this path is reused
--sanstring""YesSubject Alternative Name for the certificate (IP address or RFC 1123 hostname; wildcards rejected)
-v, --verboseboolfalseNoenable debug logging
--renew-intervalduration0Nore-obtain the certificate at this interval (0 = run once and exit)
--renew-jitter-percentint20Noshorten each renewal delay by a random amount up to this percentage so certificates issued together do not renew in lockstep; 0 disables jitter (valid range: 0–99)
--unnamed-renew-intervalduration30sNowith --workload-claims and --renew-interval, renew this often (plus jitter) while the installed leaf carries no matched-workload stamp, then settle back to --renew-interval once named; 0 disables the fast poll, and any other value below 1s is rejected
--initial-retry-timeoutduration2mNoretry the first certificate request in-process for up to this long before failing, so a transient CDS/mesh outage during a roll does not crash the init container into kubelet backoff (0 = try once)
--initial-retry-intervalduration2sNodelay between in-process retries of the first certificate request
--reload-nginxbooltrueNoSIGHUP nginx after certificate renewal or watched file changes
--continue-on-initial-errorboolfalseNoin renewal mode, keep running when the first certificate request fails, retrying on a capped backoff until a certificate is issued; requires --renew-interval
--reload-watchstring arraynilNofile path to poll for changes and reload nginx when it changes (repeatable); requires --renew-interval
--reload-watch-intervalduration1mNopoll interval for --reload-watch paths; must be positive when --reload-watch is set
--discovery-outstring""Nopath to write JSON discovery metadata for the issued certificate and attestation evidence
--discovery-cds-cert-urlstring""Nopublic URL path where the CDS certificate PEM is served
--discovery-mesh-ca-urlstring""Nopublic URL path where the mesh CA PEM is served
--discovery-public-tls-modestringcdsNopublic TLS mode to report in discovery metadata: cds or webpki
--workload-claimsboolfalseNoRequest an inventory-signed sandbox token from the node NRI plugin before certificate issuance.
--workload-claims-timeoutduration5sNotimeout for the admission inventory request

c8s get-secret

Fetch the secrets this pod is granted and write each one to a file under --out-dir. Injected by the webhook as a native sidecar. It authenticates to CDS with the pod's CDS-issued certificate and a sandbox token redeemed from the node's admission inventory at a compiled-in endpoint, and CDS releases only once every main container in the sandbox is running — earlier attempts are refused and retried, so the files appear shortly after the workload starts and a consumer must wait for them. A path the store does not hold yet is created with a CDS-generated value, which does not survive a CDS restart. After writing, the process idles until the pod is torn down. See Secrets.

FlagTypeDefaultRequiredDescription
--cds-urlstring""Yesbase URL of CDS; must be https (RA-TLS)
--attestation-api-urlstring""Yeslocal attestation-api used to verify CDS's RA-TLS certificate; http(s):// or unix:// plus an absolute socket path
--measurementsstring slicenilNoSHA-384 hex launch measurement(s) CDS must present (repeatable / comma-separated); empty pins none (UNSAFE) and is refused under --workload-claims-guest
--rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> CDS must also satisfy (repeatable / comma-separated); ignored when CDS presents SEV-SNP evidence, and empty pins no registers
--certstring/run/c8s/certs/tls.crtNothe pod's CDS-issued certificate, presented to CDS
--keystring/run/c8s/certs/tls.keyNoprivate key for --cert
--secretstring slicenilYesNAME=/store/path to fetch; NAME is the filename written under --out-dir (repeatable). At least one is required, each NAME must be distinct and must not be a path
--out-dirstring/run/c8s/secretsNodirectory the secret files are written to; must be memory-backed
--file-modestring0640Nooctal mode for the written files
--attemptsint60Nohow many times to try before failing; must be positive
--retry-intervalduration5sNowait between attempts; must be positive
--request-timeoutduration10sNoper-request timeout against CDS; must be positive
--inventory-timeoutduration5sNotimeout for redeeming a sandbox token from the node's admission inventory; must be positive

c8s get-volume

Fetch the key for each encrypted volume this pod is granted and hand it to c8s volumed, which opens the device and mounts it into this pod — read-only for an immutable volume, read-write for a mutable one. Injected by the webhook as a native sidecar, with the same authentication, release rule, and retry behavior as c8s get-secret: the volume appears shortly after the workload starts. The key must already be in the store, put there by c8s volume create; nothing here creates one. Linux only — the subcommand is registered only in Linux builds of the CLI. See Volumes.

FlagTypeDefaultRequiredDescription
--cds-urlstring""Yesbase URL of CDS; must be https (RA-TLS)
--attestation-api-urlstring""Yeslocal attestation-api used to verify CDS's RA-TLS certificate; http(s):// or unix:// plus an absolute socket path
--measurementsstring slicenilNoSHA-384 hex launch measurement(s) CDS must present (repeatable / comma-separated); empty pins none (UNSAFE) and is refused under --workload-claims-guest
--rtmrsstring slicenilNoTDX RTMR pin(s) <index>=<sha384-hex> CDS must also satisfy (repeatable / comma-separated); ignored when CDS presents SEV-SNP evidence, and empty pins no registers
--certstring/run/c8s/certs/tls.crtNothe pod's CDS-issued certificate, presented to CDS
--keystring/run/c8s/certs/tls.keyNoprivate key for --cert
--volumestring slicenilYesNAME=/store/path to open; NAME selects the device by serial c8s-vol-<name> and names the mounted volume (repeatable). At least one is required and each NAME must be distinct
--socket-dirstring/run/c8s/workload-claimsNodirectory holding the node agent's socket, as this pod sees it; unused under --workload-claims-guest, where the daemon is in the guest
--attemptsint60Nohow many times to try before failing; must be positive
--retry-intervalduration5sNowait between attempts; must be positive
--request-timeoutduration10sNoper-request timeout against CDS and the node agent; must be positive
--inventory-timeoutduration5sNotimeout for redeeming a sandbox token from the node's admission inventory; must be positive

c8s volumed

Agent that opens encrypted volumes for the pods it serves. An injected c8s get-volume sidecar hands it a key over volumed.sock, created inside the admission inventory's socket directory; the daemon resolves the calling pod from kernel peer credentials, opens dm-crypt, stacks dm-verity for an immutable volume, and mounts the result into that pod and no other — read-only erofs when verified, read-write ext4 when mutable. The mount target is never taken from what the caller reports about itself. Teardown is driven by the pod's cgroup slice disappearing.

FlagTypeDefaultRequiredDescription
--socket-dirstring""Yeshost directory holding the admission inventory's socket, where this daemon creates volumed.sock. No default: the in-pod path a sidecar sees is not where the daemon serves. Required for the node shape, unused under --guest
--kubelet-rootstring/var/lib/kubeletNokubelet's root directory, holding per-pod volume directories
--cgroup-rootstring/sys/fs/cgroupNocgroup mount, where a pod's slice going away is what triggers teardown
--reap-intervalduration15sNohow often to tear down volumes whose pod has gone; must be positive
--max-mountsint64Nomaximum volumes open at once; must be positive

c8s cred-release

Issue a short-lived kube client certificate to a caller that proves possession of the operator key whose public half was bound into the CVM's launch identity. It serves POST /release-credential over RA-TLS — the endpoint c8s get-kubeconfig consumes — signing the caller's CSR with the cluster's client CA and returning a kubeconfig anchored to the serving CA. Both TEE platforms are served, and only the binding differs: on TDX the staged operator public key must hash to the RTMR[3] the measured initrd extended, SHA-384(0x00*48 ‖ SHA-384(pubkey)), read back from the guest's own tdx_guest sysfs; on SEV-SNP it must equal the HOSTDATA the launcher committed at launch, SHA-256(pubkey), taken from a self-report the local attestation-api verified. Startup fails closed on a mismatch, and --platform is required because RA-TLS is mandatory here. Baked as a systemd unit in the c8s node image; not run by hand. The CA defaults are the RKE2 paths — on kubeadm, set all three to /etc/kubernetes/pki/ca.crt and ca.key.

FlagTypeDefaultRequiredDescription
--listenstring:8443NoHTTPS (RA-TLS) bind address
--attestation-api-urlstringhttp://127.0.0.1:8400Nolocal attestation-api base URL: the source of the RA-TLS serving cert's quote and, on SEV-SNP, of the verified HOSTDATA self-report
--platformstring""YesTEE platform: tdx or snp; selects the operator-key binding checked at startup
--client-ca-certstring/var/lib/rancher/rke2/server/tls/client-ca.crtNocluster client-CA cert that signs kube client certs
--client-ca-keystring/var/lib/rancher/rke2/server/tls/client-ca.keyNocluster client-CA key
--server-ca-certstring/var/lib/rancher/rke2/server/tls/server-ca.crtNoCA that signs the apiserver serving cert; embedded in the released kubeconfig
--cert-ttlduration24hNolifetime of issued operator certs
--cert-orgstringsystem:mastersNoKubernetes group (cert Subject O) for the issued cert
--cert-cnstringoperatorNoKubernetes user (cert Subject CN) for the issued cert

c8s get-kubeconfig

Obtain an operator kubeconfig from a measured c8s CVM. The --image-manifest shape selects the platform and the gate pins every value it carries: on TDX the image tuple (MRTD, RTMR[1], RTMR[2]) plus RTMR[3] as the operator-key seed extended by each --workload-image digest in first-extend order; on SEV-SNP the reported launch digest must be one of the manifest's per-vCPU-count snp_variants digests and HOSTDATA must equal SHA-256 of the operator public key. SEV-SNP has no runtime-extend register, so --workload-image is rejected there. A locally generated CSR is then exchanged for a short-lived kube client certificate over the node's cred-release endpoint, and the kubeconfig is written to --out with mode 0600. Verification runs in-process with attestation-go, including the RA-TLS check on the cred-release dial. Requires --operator-key, --image-manifest, and --out, plus either --node, --vmi, or all of --attest-url, --release-url, and --apiserver-url.

FlagTypeDefaultRequiredDescription
--nodestring""Noguest host/IP that fills --attest-url, --release-url, and --apiserver-url with the standard ports (8400/8443/6443); each explicit URL flag overrides it. Mutually exclusive with --vmi
--vmistring""Noguest as a KubeVirt VMI [namespace/]name; its address is resolved through the current kubeconfig and used as --node, with the namespace defaulting to the kubeconfig context's. Mutually exclusive with --node
--attest-urlstring""Noattestation-api /attest URL
--release-urlstring""Nocred-release base URL
--apiserver-urlstring""Noapiserver URL written into the kubeconfig
--operator-keystring""Yesoperator ECDSA private key PEM; its public half is the one bound into the node's launch identity (TDX RTMR[3], SEV-SNP HOSTDATA), and it signs the credential-release request
--image-manifeststring""Yesprovenanced build-artifact manifest of the expected guest image — TDX: mrtd/rtmr1/rtmr2; SEV-SNP: snp_variants. Its shape selects the platform, and every value it carries is pinned
--workload-imagestring arraynilNodigest-pinned image ref (sha256:<hex> or name@sha256:<hex>; tags rejected) the node's measurer is expected to have extended into RTMR[3]; repeatable, in first-extend order, each image given once. Omit for a node that runs no measured workloads. TDX only
--contextstringc8sNokubeconfig cluster/context/user name
--tls-server-namestringc8s-cvmNokubeconfig tls-server-name: pins apiserver certificate verification to this SAN (baked into the node image's tls-san) instead of the dialed IP. Empty omits the field
--outstring""Yespath the kubeconfig is written to, mode 0600
--timeoutduration30sNoper-step network timeout
--release-waitduration2mNohow long to keep retrying while cred-release is not yet listening, since it comes up after the attest step; 0 fails on the first refused dial

c8s ratls-mesh

Run the RA-TLS L4 mesh proxy or its iptables side commands.

FlagTypeDefaultRequiredDescription
--kubeconfigstring""NoKubeconfig for pod resolver API access; empty uses the in-cluster service account.
--platformstringautoNoTEE platform: sev-snp, tdx, or auto (probes /dev/{tdx_guest,sev-guest})
--attestation-api-urlstring""YesURL of the local attestation-api (e.g. http://localhost:8400)
--outbound-portint15001Nooutbound listener port (intercepted app traffic)
--inbound-portint15006Noinbound listener port (RA-TLS from peer nodes)
--node-ipstring""Nothis node's IP; falls back to the NODE_IP env var, and startup fails if neither is set
--cert-dns-sanstring""NoDNS SAN placed on the CDS-issued mesh cert (must match CDS --dns-san-pattern; empty omits SANs). Not used for peer verification, which is attestation-based
--log-levelstringinfoNolog level: debug, info, warn, error
--dial-timeoutduration5sNoplain TCP dial timeout
--tls-dial-timeoutduration10sNoRA-TLS dial timeout
--dest-header-timeoutduration5sNoinbound destination header read timeout
--drain-timeoutduration30sNograceful shutdown drain timeout
--keepaliveduration30sNoTCP keepalive interval (0 to disable)
--idle-timeoutduration0Noclose connections idle longer than this (0=disabled)
--max-connsint0Nomax concurrent connections (0=unlimited)
--max-conns-per-sourceint0Nomax concurrent connections per source IP (0=unlimited)
--health-portint15021Nohealth/metrics HTTP port
--measurementsstring""Nocomma-separated hex SHA-384 launch measurements that mesh peers must match (empty = accept any TEE)
--rtmrsstring""Nocomma-separated TDX RTMR pins <index>=<sha384-hex> that mesh peers must satisfy (RTMR[1] guest kernel, RTMR[2] cmdline with the dm-verity root hash); SNP peers are unaffected. Empty = no RTMR pinning, so on TDX --measurements pins TDVF firmware only
--measurements-configstring""Nopath to a measurements config listing the VM images this cluster runs; each entry is matched as a whole image (launch digest plus, on TDX, that image's registers) and is accepted both as a mesh peer and as the CDS this proxy dials. Cannot be combined with --measurements, --rtmrs, --cds-measurements, or --cds-rtmrs, and its tee must match the platform this node attests on
--cert-ttlduration24hNoRA-TLS certificate lifetime, minimum 1m (rotates at 50%)
--rotation-timeoutduration30sNomax time for background certificate rotation
--cert-modestringself-signedNocertificate mode: self-signed, or cds (boots self-signed, upgrades to CDS-issued in background)
--cds-urlstring""NoCDS service URL for attestation and CA bundle retrieval; required with --cert-mode cds
--ca-certstring""Nopath to CA certificate file for peer verification
--ca-poll-intervalduration5mNointerval to poll CDS /ca for CA bundle updates
--cds-measurementsstring""Nocomma-separated SHA-384 hex launch measurements that the CDS RA-TLS peer cert must match; empty = accept any (UNSAFE outside development)
--cds-rtmrsstring""Nocomma-separated TDX RTMR pins <index>=<sha384-hex> that the CDS RA-TLS peer cert must satisfy on top of --cds-measurements; ignored when CDS presents SNP evidence. Empty = launch-digest pinning only
--cds-retry-backoffduration2sNoinitial backoff duration for CDS certificate upgrade retries
--cds-retry-max-backoffduration1mNomaximum backoff duration for CDS certificate upgrade retries
--cds-op-timeoutduration30sNoper-operation timeout for CDS certificate upgrade and CA bundle refresh
--session-cache-sizeint64NoTLS session cache size per node (0 disables session resumption)
--access-logbooltrueNoemit per-connection structured access log
--cert-pipeline-probe-urlstring""NoCDS /readyz URL for pipeline health probing (empty = disabled)
--cert-pipeline-probe-timeoutduration5sNoHTTP client timeout for cert pipeline health probe requests
--cert-pipeline-probe-intervalduration1mNointerval between cert pipeline health probe requests
--max-dest-header-sizeint256Nomaximum destination header size in bytes
--pipe-buffer-sizeint32768Nobuffer size for TCP pipe forwarding
--accept-error-thresholdint6410Noconsecutive accept errors before marking unhealthy
--health-read-timeoutduration5sNohealth server read timeout
--health-write-timeoutduration10sNohealth server write timeout
--metrics-update-intervalduration10sNointerval for resolver cache and cert expiry metric updates
--local-cidr-boot-timeoutduration1sNosynchronous retry budget at startup for host pod-network CIDR discovery; past it the mesh falls through to the async refresh loop and local-destination validation uses Kubernetes pod HostIP ownership until discovery recovers
--iptables-metrics-filestring/tmp/ratls-iptables-metrics.jsonNoshared file where iptables-sync publishes counters (empty disables)

c8s ratls-mesh iptables-sync

Watch Kubernetes pods and maintain the iptables/ipset rules that redirect mesh traffic.

FlagTypeDefaultRequiredDescription
--outbound-portint15001Nooutbound listener port
--uidint1337NoUID to exclude from redirect
--exclude-uidsstring0Nocomma-separated UIDs to skip (e.g. root=0 so kubelet/containerd can reach registries)
--exclude-source-namespacesstringkube-systemNocomma-separated local source namespaces excluded from transparent mesh interception
--node-ipstring slicenilNolocal node IP(s); repeat or comma-separate for dual-stack (one per family). Defaults to the NODE_IP env var. Each address must be a non-loopback, non-unspecified IP bound to a local interface
--resync-periodduration30sNoperiodic full ipset reconciliation interval
--watchdog-periodduration2sNointerval at which the base-chain jump rules are re-asserted at the head of their chain (bounds the race window against kube-proxy reinserting KUBE-SERVICES)
--ipset-maxelemint262144Nomaximum members per managed ipset
--cw-inbound-passthroughstringudp:53,tcp:53Nocomma-separated proto:source-port replies exempted from the always-on cw inbound guard, which drops FORWARD-path traffic to confidential.ai/cw pods. Each entry matches only a destination port in 32768-60999 and, for TCP, a reply segment shape. Empty = strict drop-all; DNS is the default
--ready-filestring""Nopath to write after initial ipset and iptables sync succeeds
--iptables-metrics-filestring/tmp/ratls-iptables-metrics.jsonNoshared file where iptables-sync publishes counters (empty disables)
--log-levelstringinfoNolog level: debug, info, warn, error

c8s ratls-mesh iptables-cleanup

Remove the iptables NAT rules and ipsets the mesh created.

FlagTypeDefaultRequiredDescription
--keep-guardboolfalseNokeep the fail-closed filter guard (the RATLS-MESH-CW and RATLS-MESH-CW-EGRESS chains, their FORWARD jumps, and the cw pod ipsets) while removing the interception NAT rules; the daemonset preStop hook sets it so a terminating mesh stays fail-closed. A full teardown removes the guard as well

c8s nri-image-policy

Run the nri-image-policy plugin. Uses the standard Go flag package, so the help output prints single-dash forms and both -config and --config parse; most configuration comes from the YAML config file rather than CLI flags.

FlagTypeDefaultRequiredDescription
--configstring/etc/nri/conf.d/image-policy.yamlNopath to config file
--health-addrstring:8080Nohealth check listen address
--read-timeoutduration5sNoHTTP server read timeout
--write-timeoutduration10sNoHTTP server write timeout

c8s probe-file

Exit 0 if <path> exists and is a non-empty file — a file-existence helper for distroless containers, where /bin/test is not available. One-shot by default (for a kubelet exec probe); with --wait it blocks until the path passes (or --timeout elapses), so it can be the entrypoint of an init container that gates a workload on a file another container writes — the exec-free equivalent of a startup probe when exec probes are denied by policy. The non-empty check rules out passing on a half-written file.

FlagTypeDefaultRequiredDescription
--waitboolfalseNoblock until <path> passes the check instead of probing once
--poll-intervalduration1sNohow often to re-check <path> in --wait mode
--timeoutduration0Nogive up (non-zero exit) after this long in --wait mode; 0 waits forever