Obtain launch measurements
Prepare approved node and router identity policies from build and deployment records, and keep the external CDS image and configuration pin separate.
Prepare the expected identities before deploying c8s. On AMD SEV-SNP, the image pin
contains a SHA-384 launch digest. On Intel TDX, it contains the firmware measurement
(MRTD) together with runtime measurement registers RTMR[1] and RTMR[2] from the same
build. An MRTD-only pin leaves the guest kernel and rootfs unmeasured by that policy.
Image measurements alone do not pin mutable policy or deployment configuration. Keep the node identities admitted by the Certificate Distribution Service (CDS), the router's node identity, and the external CDS's own image/configuration identity separate. See the trust root for their trust boundaries.
Prerequisites
- The
c8sCLI on your workstation'sPATH. - Approved image and deployment records from your image producer or operator. Retain the exact build's manifest and boot artifacts together, including the selected SEV-SNP vCPU variant when applicable. A manifest's presence does not establish its provenance.
- For managed Azure nodes without a compatible build manifest, the complete policies described under Node CVMs on stock Azure images.
Derive policies for measured c8s images
Use this path when you have the image producer's reviewed manifest.json. For an existing
deployment, obtain its retained launch policies from the operator; generating new launch
keys creates a different identity.
Extract the image values
c8s measurements derive '<NODE_MANIFEST_JSON>' --tee '<NODE_TEE>' \
--out node-images.json
c8s measurements lint node-images.jsonReplace <NODE_MANIFEST_JSON> with the exact node build's manifest path and <NODE_TEE>
with sev-snp or tdx, matching that build. A build directory containing manifest.json
also works. --tee selects the platform when the manifest contains both.
The command converts manifest values into a JSON image policy: one entry per SEV-SNP vCPU
variant, or a TDX entry containing MRTD, RTMR[1], and RTMR[2]. Multiple inputs must use the
same platform. Successful linting prints ok: with the platform and image count; it checks
the policy format, not the build's provenance or measurement calculation.
Retain node-images.json to inspect the extracted image values. The next step reads the
manifest again and generates policies with the new deployment's launch-key bindings.
For an independent calculation, use the exact build's
firmware, kernel, initrd, command line, and platform-specific launch procedure. A tool such
as sev-snp-measure is a possible SEV-SNP calculation tool, but a generic kernel invocation
is not a verified recipe for the current IGVM artifacts. Obtain the producer's procedure
and compare its result with the manifest's matching vCPU variant. On TDX, compare the whole
MRTD/RTMR[1]/RTMR[2] tuple. See
independent recomputation.
Bind a new node deployment and its CDS
For a new cluster using the measured c8s node image, generate its launch bundle. This example uses SEV-SNP for both the node and CDS:
c8s node launch-config new --out node-bundle --cluster-id '<CLUSTER_ID>' \
--image-manifest '<NODE_MANIFEST_JSON>' --vcpus '<NODE_VCPU_COUNT>' \
--cds-address '<CDS_HOST>:8443' \
--cds-image-manifest '<CDS_MANIFEST_JSON>' --cds-platform sev-snp \
--cds-vcpus '<CDS_VCPU_COUNT>' \
--cds-node-cidr '<NODE_CIDR>' --cds-allowlist-seed '<COMPONENT_SEED_JSON>'Replace the placeholders with these prepared inputs:
<CLUSTER_ID>: the cluster name you assign, as an RFC 1123 label.<NODE_MANIFEST_JSON>and<CDS_MANIFEST_JSON>: manifests from the approved node and CDS build bundles. The CDS runs in its own confidential VM (CVM).<NODE_VCPU_COUNT>and<CDS_VCPU_COUNT>: supported counts from the respective manifests. Retain the matching IGVM boot artifacts for launch.<CDS_HOST>: the planned CDS DNS name or IPv4 address, reachable by its clients on TCP8443.<NODE_CIDR>: the subnet holding node inventory addresses CDS may contact. Repeat--cds-node-cidrfor additional subnets; exclude the baked image's pod and service ranges,10.52.0.0/16and10.53.0.0/16.<COMPONENT_SEED_JSON>: the matching release'sallowlist-seed-snp.json, supplied with your approved node build inputs.
node-bundle must not exist. The command generates launch keys, join credentials, a signed
c8s-launch/v2 server document, and these policy artifacts:
server.jsonbinds the node image and server launch key. Use it for the router when the router runs on that server.peers.jsonbinds the node image under the server and agent launch keys. Review the whole admitted set, including the agent identity even when this command creates only a server.cds-config.yamlis the external CDS'sc8s-cds/v1launch configuration. It includes the node policy, operator public key, component seed, and inventory subnets.cds-pin.jsonbinds the CDS image and the exactcds-config.yamlbytes. Keep this pin separate fromserver.jsonandpeers.json.
Protect the generated private keys and join credentials. The CDS configuration is host-readable
and carries public inputs; keep private keys and secrets out of it. Optional tenant workloads
enter the generator through --tenant-workloads, which adds them to the CDS configuration.
For TDX nodes, supply their manifest, omit --vcpus, and use the matching release's
allowlist-seed-tdx.json for <COMPONENT_SEED_JSON>. Obtain that seed with your approved
node build inputs. For a TDX CDS, use its manifest, --cds-platform tdx, and omit
--cds-vcpus. The CDS and nodes can use different platforms; the component seed matches
the nodes. See the
node CVM launch contract
for agents, launch-media bindings, and the remaining launch inputs.
Check and retain the generated policies
c8s measurements lint node-bundle/server.json
c8s measurements lint node-bundle/peers.json
c8s measurements lint node-bundle/cds-pin.jsonRequire each command to succeed, then review the image values and launch bindings against your intended deployment. Retain the policies with the approved manifests and launch inputs. Linting establishes that the documents parse; live attestation establishes whether a target matches them.
Node CVMs on stock Azure images
For AKS or another Azure node image without a compatible build manifest, obtain two complete JSON image policies from your trusted image producer or deployment operator before preparing the external CDS or installing c8s:
nodes-policy.json: the exact set of node launch identities CDS may admit.router-pin.json: the identities acceptable for nodes hosting the router. Reuse the node policy only when its entire set is acceptable for the router.
Require the provider-specific image values and applicable launch bindings for your deployed node image and configuration. On TDX, require the full MRTD/RTMR[1]/RTMR[2] tuple. The manifest conversion above requires a compatible producer manifest; this guide does not establish an Azure-specific procedure for calculating these policies from a stock image. If your producer or operator cannot supply approved values, this prerequisite remains unmet.
c8s measurements lint nodes-policy.json
c8s measurements lint router-pin.jsonSuccessful parsing does not approve those identities. Independently review their provenance and deployment scope. A running node's report can show observed values for comparison; accepting those values solely because that node reports them is trust-on-first-use. Do not use a responder's own claimed policy to approve it. Review replacement values through the same process when the provider changes the node image.
Pass nodes-policy.json to c8s cds config new --node-pins as part of
Install c8s. That procedure generates
the separate CDS configuration and cds-pin.json, launches and verifies CDS, retains the
mesh CA, and installs using --cds-address with --cds-pin.
Check each target against its own policy
After launch, check the external CDS with its own pin and the independently intended current node set:
c8s cds verify 'https://<CDS_HOST>:8443' \
--image-policy-file '<CDS_PIN_JSON>' --served-policy-file '<NODE_POLICY_JSON>'<CDS_HOST> is the actual external CDS endpoint. <CDS_PIN_JSON> is the generated CDS
image/configuration pin: node-bundle/cds-pin.json for the measured-node path, or
cds-bootstrap/cds-pin.json from the installation procedure. <NODE_POLICY_JSON> is
node-bundle/peers.json or your approved nodes-policy.json, provided it still describes the
intended current set. The measured configuration supplies singleton CDS's node policy and
the default for high-availability (HA) Genesis, the signed initialization decree that starts
the HA cluster. Genesis can select another set, and later signed commands can change it.
When either selects a different set, use the independently approved current node policy
instead of the generated initial policy. --served-policy-file explicitly compares that
live served set; the CDS identity check alone does not perform this comparison.
For the router, retain mesh-ca.pem through the
pinned CDS CA procedure,
replacing cds-pin.json in that procedure with the <CDS_PIN_JSON> path selected above.
Then verify with the approved router-node policy:
c8s verify 'https://<ROUTER_ADDRESS>:443' --kind lb \
--server-name '<ROUTER_SNI_NAME>' \
--image-policy-file '<ROUTER_POLICY_JSON>' --mesh-ca mesh-ca.pemReplace <ROUTER_ADDRESS> with the router's reachable address and <ROUTER_SNI_NAME>
with its TLS Server Name Indication (SNI) name, such as its configured certificate hostname.
--server-name selects SNI; this command does not check certificate hostname equality.
<ROUTER_POLICY_JSON> is node-bundle/server.json
for the baked server's router, or your approved router-pin.json. Use a direct network path
or a load balancer that passes TLS through to the router. Keep the CDS pin for the CDS check.
Require verification exit code 0 and inspect warnings. Router discovery evidence describes
certificate issuance and is not fresh evidence from this verification attempt. See
Verify a deployment for fresh checks, verdict scope,
and failure handling.