Obtain launch measurements

Get the SHA-384 launch digest to pin — derived from the image build manifests, published with an image, recomputed with sev-snp-measure, or read off a live attestation report — and work out which c8s flag wants which party's digest.

A measurement is the SHA-384 launch digest of a confidential VM — a hash the TEE hardware (AMD SEV-SNP or Intel TDX) computes over the exact launch state (firmware, guest kernel, and the kernel command line, which embeds the dm-verity root hash of the rootfs). The *measurements flags in c8s take one or more of these hex strings, and --measurements-config takes a JSON file that lists them per image. Because a reproducible image always yields the same digest, pinning it means "accept only this exact, audited image — nothing else."

Four ways to get the value, best first.

Derive it from the image build manifests

For images built for c8s, c8s measurements derive reads each image's manifest.json and writes a measurements config — the JSON file that pins every image the cluster accepts:

c8s measurements derive ./out/<IMAGE_DIR> --out measurements.json

On AMD SEV-SNP it emits one entry per vCPU variant of the build; on Intel TDX it emits the image's MRTD with the RTMR[1] and RTMR[2] measured from the same build. Feed the file to c8s install --measurements-config and to c8s verify --measurements-config.

Use the digest published with the image

The self-managed node image publishes its predicted launch digest in manifest.json. Pin the digest for the exact image version you deploy. A reproducible build lets you independently check that published value against the image you audited.

Recompute it with sev-snp-measure

To independently verify the published value (or for a custom image), recompute the expected digest yourself with AMD's sev-snp-measure from the launch components — the OVMF firmware, the guest vmlinuz, and the kernel cmdline (which carries the dm-verity root_hash) — at the same vCPU count the VM launches with. An SEV-SNP digest covers one VMSA page per boot-time vCPU, so the count is an input, not a detail:

# illustrative — see the sev-snp-measure docs for the exact flags for your image
sev-snp-measure --mode snp --vcpus <N> \
  --ovmf OVMF.fd \
  --kernel vmlinuz \
  --append "<KERNEL_CMDLINE_INCLUDING_ROOT_HASH>" \
  --output-format hex

<N> is the count you launch at. The node image ships one measured IGVM per supported count and publishes a digest for each in snp_variants — see the node CVM launch contract. A reproducible build yields the same digest that's in the manifest; a mismatch means the image isn't what you think it is. (sev-snp-measure is AMD-specific. On Intel TDX the equivalent launch values are the MRTD plus RTMR[1] and RTMR[2], which the build manifest carries and c8s measurements derive reads — the guest kernel and the command line holding the dm-verity root hash live in those two registers, so a TDX pin covers the image only when it carries all three values from one build.) To use this as a post-deploy cross-check — recompute, pin, then verify a live node reports the same digest — see Independently recompute the measurement.

Read it from a live attestation report (inspect, then pin)

To see what a running component actually measures, read the launch_digest from its evidence: get-cert --discovery-out discovery.json … writes the attestation evidence and measurement for the issued certificate, and the attestation-api's verify result returns claims.launch_digest. Use this to inspect what's running — but in production pin the published or recomputed value above, not merely whatever a node reports, or you've only achieved trust-on-first-use.

Node CVMs on stock Azure images

A self-managed Azure CVM boots platform firmware that Azure manages, so nothing ships a manifest.json for it and no predicted digest is published. For this shape, the live report is the supported source: install unpinned, read M from the measurement: line of c8s verify, then re-run c8s install --measurements <M> — the loop step 5 of the first cluster tutorial closes. This is trust-on-first-use: the pin binds the platform image you first observed, so read M again whenever Azure rolls that image and verification starts failing.

Which flag wants which digest

Each flag wants the digest of a different party:

FlagPin the launch digest of…
cds.measurements (--measurements)the workloads and peers allowed to attest to the CDS — and, reused, the inventories the CDS dials for sandbox digests
ratlsMesh.measurementsthe mesh peers allowed to connect
--cds-measurements (get-cert and ratls-mesh cds mode) and allowlist.pull.cds_measurements (nri-image-policy)the CDS itself
--measurements (c8s allowlist)the endpoint the CLI connects to — router on the default public route, or the CDS on a direct URL
measurements in c8s-verifythe user-facing LB enclave
--measurements-config (cds.measurementsConfig + ratlsMesh.measurementsConfig)every VM image the cluster runs, each as a whole image — the file replaces both measurements lists above
--rtmrs (cds.rtmrs + ratlsMesh.rtmrs)the TDX registers of those same images: RTMR[1] the guest kernel, RTMR[2] the command line

On a Node-as-CVM install, c8s install --measurements <M> fills the first two rows in one pass — the node image's digest from its manifest.json — so the mesh is pinned from first boot rather than accept-any-then-tighten. A --measurements entry that is not valid hex fails CDS startup rather than silently unpinning the sandbox callback.

Measurements identify confidential nodes. On a host without a CVM, there is no node launch digest to pin.

See also