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.
| Value | Default | Effect |
|---|---|---|
node.baked | false | Render components for a measured node image whose launch configuration supplies CDS address and pins. |
nriImagePolicy.baked | false | Use 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
| Value | Default | Effect |
|---|---|---|
armtlsMesh.image.repository | ghcr.io/confidential-dot-ai/armtls-mesh | Image 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.pullPolicy | IfNotPresent | Pull 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
| Value | Default | Effect |
|---|---|---|
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.deriveComponents | false | Derive component entries from pinned image digests and rendered container shapes. c8s install --resolve-digests=true enables this and is the installer default. |
nriImagePolicy.refresh.interval | 5s | Interval between allowlist polls. Admission uses the previous policy until the next successful refresh. A baked plugin uses its image's interval. |
nriImagePolicy.policy.mode | fail-closed | Deny containers outside the policy. audit logs denials but admits the containers. |
nriImagePolicy.measurePolicies | false | Extend 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
| Value | Default | Effect |
|---|---|---|
volumed.enabled | false | Deploy the node agent that opens and mounts encrypted-volume devices; c8s install --volumes enables it. |
volumed.maxMounts | 64 | Maximum live volumes per node. |
volumed.reapInterval | 15s | How 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.
| Value | Default | Effect |
|---|---|---|
router.enabled | true | Deploy nginx and the cds-attest sidecar, including application routing. |
router.attest.enabled | true | Serve attestation and tunnel endpoints under /.well-known/c8s/. --attest=false disables them; the sidecar still routes application requests. |
router.allowlist.enabled | true | Publish the CDS allowlist API through the front door. |
router.publicTLS.mode | cds | Public 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.enabled | true | Bind 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.enabled | false | Apply the configured CORS policy to application and protocol endpoints. |
router.cors.protocolEndpoints | true | Wide-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.port | 8802 | Loopback port of the routing listener nginx proxies to. |
router.routing.readTimeout | 3600s | nginx timeout between reads and writes to the routing listener; must outlive the longest non-streaming completion. |
router.routing.maxRequestBodyBytes | 1048576 | Maximum 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.backendTimeout | 1h | Routed-request inactivity timeout; a tunnelled request gets this duration in total for its backend call. |
router.routing.pollInterval | 30s | Route-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.enabled | false | Publish 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
| Value | Default | Effect |
|---|---|---|
hostNamespacePolicy.enabled | true | Enforce workload restrictions on host namespaces, host privilege, and hostPath volumes, preserving the node admission-inventory boundary. |
See also
- Install C8s — installation inputs and checks.
- CLI reference →
c8s install— flags that set chart values. - Pin multiple measurements — trust policies for measured images.
- Workload annotations — per-pod configuration.