Helm values

Chart values and defaults for external CDS trust, allowlist seeding, injected mesh images, policy measurement, encrypted volumes, and the router.

c8s install passes its computed values as the last Helm -f file. Precedence is chart defaults, then your -f files in order, then computed values. An installer flag wins on the keys it sets; lists are replaced.

This reference covers values commonly set by hand. The full chart defaults are in internal/helmchart/c8s/values.yaml in the C8s repository.

Without -f, omitting --operator-keys requires --force. Supplying -f skips that guard; the values file may supply cds.operatorKeys or leave the router to use keys from the verified CDS. The external CDS still requires operator keys in its measured launch configuration. Effective-value preflight checks and applicable chart validations still run. See Choosing the install shape.

Trust pinning

CDS runs in an external confidential VM. These values configure the cluster's clients of that CDS; its measured c8s-cds/v1 launch configuration supplies its operator keys, inventory subnets, leaf DNS rules, and initial workloads. Its node policy governs singleton admission and supplies the default node set for Genesis, the signed command that starts a high-availability (HA) cluster. Genesis can select a different initial admitted node set with --nodes. See c8s cds config.

ValueDefaultEffect
node.bakedfalseRender components for a measured node image whose launch configuration supplies CDS address and pins.
nriImagePolicy.bakedfalseUse the NRI plugin binary, registration, and boot configuration supplied by the node image; requires attestationApi.cvmMode=bare-metal.
cds.address""External CDS endpoint as host:port, with a lowercase DNS name or IPv4 address. Set with --cds-address.
cds.measurementsConfig""JSON content of the schema-version-2 CDS pin, binding its guest image and exact launch configuration bytes. --cds-pin <file> reads the file.
cds.operatorKeys""PEM content of the public-key bundle the router uses to verify route manifests. --operator-keys <file> reads the file.

nriImagePolicy.baked can be true while node.baked is false: the node image supplies NRI while Helm deploys cluster components. For node.baked: false, chart validation requires the CDS pin. It also validates the address when nriImagePolicy.baked: false, where the chart writes the node's boot configuration. A baked NRI plugin takes the address from launch staging; with node.baked: true, both address and pins come from the measured launch configuration.

The router prefers launch-configured operator keys, then cds.operatorKeys, then keys fetched from the verified CDS. Changing this Helm bundle changes router verification; the external CDS authorizes writes using the keys bound into its own measured configuration. CDS identity pins, the node identities CDS admits, and the node identities external verifiers accept are separate policies. Signed high-availability (HA) policy updates can change the live node identities CDS admits.

With values-supplied pins, the <release>-measurements ConfigMap contains cds.json, plus cds-address when the chart supplies the node address. A copy of cds.json is rendered in c8s-router when the router is enabled. The node installer stages the inputs for NRI, which mounts /run/c8s/cds-pins.json into injected credential clients and /run/c8s/router-cds-pins.json into the router. The router Deployment carries the checksum/measurements-config rollout annotation.

Injected mesh image

ValueDefaultEffect
armtlsMesh.image.repositoryghcr.io/confidential-dot-ai/armtls-meshImage for the per-pod mesh endpoint.
armtlsMesh.image.tag""Consumer-supplied image tag; set a tag or digest.
armtlsMesh.image.digest""Exact image digest; the installer resolves component digests by default.
armtlsMesh.image.pullPolicyIfNotPresentPull policy for chart-rendered mesh containers. Webhook-injected mesh containers always use IfNotPresent.

The webhook injects the endpoint into every pod selected by its namespace selector, without requiring confidential.ai/cw. Applications serve ordinary TCP or HTTP inside the pod; platform containers hold the mesh credentials at /etc/c8s/certs. The confidential.ai/cw annotation names workload/service intent. Its annotation contract is listed in Workload annotations.

Allowlist seeding

ValueDefaultEffect
nriImagePolicy.bootstrapAllowlist.workloads{}Named workload entries included in the chart's seed artifact. An entry with a chart-derived name replaces that generated entry.
nriImagePolicy.bootstrapAllowlist.deriveComponentsfalseDerive component entries from pinned image digests and rendered container shapes. c8s install --resolve-digests=true enables this and is the installer default.
nriImagePolicy.refresh.interval5sInterval between allowlist polls. Admission uses the previous policy until the next successful refresh. A baked plugin uses its image's interval.
nriImagePolicy.policy.modefail-closedDeny containers outside the policy. audit logs denials but admits the containers.
nriImagePolicy.measurePoliciesfalseExtend TDX RTMR[3] with pulled policy digests before applying them; a no-op on SNP.

The chart renders <release>-allowlist-seed with allowlist-seed.json. Generate the release/options-matched artifact with c8s install --allowlist-seed-out before creating the external CDS configuration; this mode stops before installation. c8s cds config new --allowlist-seed incorporates it into the measured configuration, and CDS seeds those workloads before serving. Live changes use signed c8s allowlist commands. Editing the chart's seed ConfigMap does not update the external CDS. See Seeding and bootstrap.

Policy measurement requires attestationApi.enabled: true and the default nriImagePolicy.hostPaths.runtimeDir: /run/nri-image-policy so certificate producers can read the policy-measurement journal. The chart refuses opt-in for node.baked; the stock baked image leaves it disabled. Measurement failure retains the current policy. At journal capacity, new policy digests are refused until reboot; already-recorded digests remain eligible. NRI logs pull loop: allowlist refused; keeping current policy with an error reporting how many policies the node measured since boot and that its certificates cannot carry more. The error instructs the operator to reboot to accept further new digests.

Encrypted volumes

ValueDefaultEffect
volumed.enabledfalseDeploy the node agent that opens and mounts encrypted-volume devices; c8s install --volumes enables it.
volumed.maxMounts64Maximum live volumes per node.
volumed.reapInterval15sHow often teardown checks which pods have gone.
volumed.nodeSelector{}Confine the daemon to the nodes that carry volume devices.

The front door (router)

The router runs in c8s-router, independently of the Helm release namespace.

ValueDefaultEffect
router.enabledtrueDeploy nginx and the cds-attest sidecar, including application routing.
router.attest.enabledtrueServe attestation and tunnel endpoints under /.well-known/c8s/. --attest=false disables them; the sidecar still routes application requests.
router.allowlist.enabledtruePublish the CDS allowlist API through the front door.
router.publicTLS.modecdsPublic certificate source: cds for a CDS-issued mesh leaf, webpki for a Kubernetes Secret, or acme for an in-pod ACME issuer requiring attestationApi.cvmMode=bare-metal.
router.publicTLS.secretName""WebPKI TLS Secret in c8s-router; required for webpki mode.
router.hostPort.enabledtrueBind nginx's TLS listener to a node host port. Disable when another ingress owns that port.
router.hostPort.https""Host port; empty selects 443.
router.strategy{}Baked nodes always use Recreate. Otherwise an explicit strategy wins; empty selects Recreate with hostPort, or RollingUpdate with maxSurge: 1 and maxUnavailable: 0 without hostPort.
router.cors.enabledfalseApply the configured CORS policy to application and protocol endpoints.
router.cors.protocolEndpointstrueWide-open CORS on protocol endpoints when router.cors.enabled is false.
router.san[]nginx hostnames; empty selects <release>-router.c8s-router.svc. The first name is the CDS-issued mesh certificate identity and must match CDS leaf DNS rules.
router.routing.port8802Loopback port of the routing listener nginx proxies to.
router.routing.readTimeout3600snginx timeout between reads and writes to the routing listener; must outlive the longest non-streaming completion.
router.routing.maxRequestBodyBytes1048576Maximum body size for ordinary HTTP requests routed by nginx, in bytes; larger bodies receive 413. Baked nodes use the signed launch field router.maxRequestBodyBytes.
router.routing.backendTimeout1hRouted-request inactivity timeout; a tunnelled request gets this duration in total for its backend call.
router.routing.pollInterval30sRoute-manifest poll interval; keep below half the manifest's maxAgeSeconds.
router.routing.tunnelBudget""Per-replica buffer budget, such as 64Gi. Empty uses 75% of the sidecar's cgroup memory limit, with a 152Mi floor (three 8 MiB record copies plus four 32 MiB response copies), or 32Gi without a limit.
router.routePublication.enabledfalsePublish the applied signed manifest at /.well-known/c8s/routes; requires router.attest.enabled. Node-image rendering enables it for baked nodes.

A baked router takes public hostnames and TLS selection from its launch configuration; router.publicTLS.mode stays cds in the chart. In webpki mode, the front door uses a host-visible Secret key and supports attest-pq, which establishes an attested encrypted tunnel. It refuses attest-lb, which binds attestation to the certificate of an ordinary TLS connection. Both nginx and cds-attest mount that Secret. In ACME mode, the certificate chain is at /etc/c8s-acme-tls/cert.pem, with private key and account state under /etc/c8s-acme-key.

Routes come from the operator-signed manifest stored by CDS, written with c8s routes or c8s install --upstream. Before a manifest is applied, application requests receive 503; unmatched hosts or paths receive 404. Workload backends use the injected mesh endpoint. Its CDS-stamped workload name must match the route. When the router's certificate carries a CDS-issued allowlist-digest stamp, the backend's allowlist digest must also match the router's allowlist digest. The application serves HTTP behind that endpoint without mounting its key.

The configurable body cap applies to ordinary nginx-routed HTTP requests. Tunnel requests have an 8 MiB limit on the encoded, sealed record, including envelope and encryption overhead, so the usable application payload is smaller. Backends can impose additional limits. nginx's 16 KiB protocol-handshake body cap and the 32 MiB buffered tunnel-response limit are separate. Increasing the ordinary HTTP body cap changes neither tunnel limits nor tunnel buffering.

Baked routers always use Recreate. Other installs default to Recreate when hostPort is enabled, interrupting the node-IP front door during restart. For those installs, disabling hostPort selects the rolling defaults unless router.strategy overrides them. Expose the router Service through a reachable ingress for your deployment.

Scheduling

ValueDefaultEffect
hostNamespacePolicy.enabledtrueEnforce workload restrictions on host namespaces, host privilege, and hostPath volumes, preserving the node admission-inventory boundary.

See also