Verify a connection
Check CDS against approved pins, then use TEErminator to enforce the TDX worker image, launch document, routes and policy history on the application connection.
Verify independently approved inputs before sending private requests. These steps continue the TDX deployment and public test workload from Run a workload. A Kubernetes Ready condition or a publicly trusted HTTPS certificate alone does not establish these identities.
Prepare approved inputs
Use c8s, TEErminator,
Python 3 and jq on your client machine.
Keep these approved inputs from setup:
worker-manifest.jsonandworker-image.json.- The exact
worker.yaml. cds/cds-pin.json,operator.pub, andmesh-ca.pem.render/allowlist-seed.json.
Obtain these through your trusted approval process, independently of the endpoint being checked.
For the unchanged first-workload journey, construct its expected admitted worker set by binding the reviewed worker image to the exact launch document:
set -euo pipefail
LAUNCH_DIGEST="$(sha384sum worker.yaml | cut -d ' ' -f 1)"
jq --arg digest "$LAUNCH_DIGEST" \
'.schema_version = "2" | .measurements |=
map(. + {launch_file_digest: $digest})' \
worker-image.json > worker-pin.json
c8s measurements lint worker-pin.jsonExpect lint to succeed. If additional worker documents or images have been admitted, use the independently approved complete current set for the CDS served-policy check below. The worker-image policy and TEErminator's build manifest are different file formats; TDX pins must include MRTD, RTMR[1] and RTMR[2] from the same reviewed build.
Export the current canonical allowlist and signed route manifest through the pinned CDS connection:
c8s allowlist export candidate-allowlist.json \
--url https://cds.example.com:8443 --image-policy-file cds/cds-pin.json
c8s routes show --raw --operator-keys operator.pub \
--url https://cds.example.com:8443 --image-policy-file cds/cds-pin.json \
> candidate-routes.jsonReview:
- The complete allowlist, including platform entries and
demo-nginx. - The routes' host, path, backend, revision, and validity.
After approval, save the exact bytes as approved-allowlist.json and
approved-routes.json. An authenticated fetch or valid operator signature
does not replace approval.
Keep every intermediate canonical allowlist that this worker has applied since
boot, plus the policy issuing the router's mesh leaf. For the unchanged journey,
these are the initial seed and the exported workload policy. If you published
other policies, approve and include their archived bytes as additional
--pin-policy arguments below. Each argument accepts a canonical policy file
or its sha256:<64 lowercase hex> digest. Preserve the bytes: reformatting
changes the digest. A missing or unapproved history entry causes refusal.
Check CDS identity and current worker admission
c8s cds verify https://cds.example.com:8443 \
--image-policy-file cds/cds-pin.json \
--served-policy-file worker-pin.json \
--operator-keys operator.pub -o json > cds-verdict.json
jq -e '.verified == true and .measurement_pinned == true' cds-verdict.jsonRequire command exit 0 and true. This checks:
- The CDS image and exact launch configuration.
- Current admitted worker identities.
- The operator key set.
CDS's serving certificate carries issuance-time evidence; this is not a fresh application-channel check.
c8s verify returns 1 for invalid inputs, 2 for failed verification/policy,
3 for unavailable evidence or collateral, and 4 for a partial verdict.
Retain the verdict and investigate warnings.
Enforce pins on the application connection
Point api.example.com at the router worker, using trusted client DNS or a
local hosts entry. Compute the TDX RTMR[3] seed from the exact approved worker
document. This is the launch-file seed before measured policy extensions.
Save the calculation as rtmr3-seed.py in the directory containing the approved
worker.yaml:
import hashlib
from pathlib import Path
launch = Path('worker.yaml').read_bytes()
assert launch, 'worker.yaml must contain the approved launch document'
print(hashlib.sha384(bytes(48) + hashlib.sha384(launch).digest()).hexdigest())Run the calculation, then configure and start the proxy:
RTMR3_SEED="$(python3 rtmr3-seed.py)"
ROUTE_DIGEST="$(c8s routes digest approved-routes.json)"
teerminator certs add mesh-ca.pem
teerminator remote add 127.0.0.1:8080 https://api.example.com \
--mode attest-lb --image-manifest worker-manifest.json \
--expected-rtmr3 "$RTMR3_SEED" --route-digest "$ROUTE_DIGEST" \
--pin-policy render/allowlist-seed.json \
--pin-policy approved-allowlist.json
teerminator status --timeout 30s
teerminator startRequire all of the following for this remote:
Verified.specific-clustertrust.- The approved route digest.
- A pinned policy history.
status can exit successfully while a remote reports Partial or Failed;
inspect the reported status. A successful remote add only saves configuration.
Do not send private requests on a partial verdict. The daemon enforces attestation and the configured pins as it forwards.
In a second terminal, send the public test request through the local proxy:
curl --fail --show-error --connect-timeout 5 --max-time 30 \
http://127.0.0.1:8080/Expect the nginx welcome page. A mismatched image, launch seed, route or policy blocks forwarding. TEErminator binds evidence to the exact upstream TLS leaf and reuses a passing verdict for up to one minute, bounded by its certificate expiry; inspect warnings and the re-attestation behavior for your requirements.
Its TDX vendor-status check is opt-in through --tdx-tcb-status; an unset value
checks quote signatures and the PCK chain without fetching current Intel status.
Understand the assurance boundary
This path verifies the router worker, its launch document, policy history, mesh CA and applied route. The router authenticates the backend workload under its mesh and policy checks. This is not direct backend-leaf evidence or proof of the physical GPU processing a request. Guest boot GPU checks and shared worker isolation have the limits described in Operate.
The seed and policy-history example is TDX-specific. AMD SEV-SNP needs its approved vCPU-specific launch measurement and launch-document HOST_DATA pin; it has no equivalent runtime policy-history register. Do not reuse TDX flags. These commands are source-checked; confidential hardware and live endpoint checks must run against your deployment.