Split out of #431, which stays closed: its code deliverable shipped and works. This is the gap that code cannot close on its own.
The problem
Azure Trusted Launch presents two vTPM attestation-key certificate hierarchies concurrently at NV index 0x01C101D0. Measured on hardware:
|
D2s_v5, eastus, 2026-07-31 |
D2s_v7, eastus2, 2026-08-01 |
| Certificate size |
1596 bytes |
994 bytes |
| Issuer |
Azure Cloud Virtual TPM CA - 11 |
Global Virtual TPM CA - 03 |
| AIA extension |
present, 4 caIssuers URIs |
absent entirely |
| Chain to a pinnable root |
yes, reaches Azure Virtual TPM Root Certificate Authority 2023 |
no |
cmcp_verify/tpm_roots.py pins only the 2023 root, which the CA-11 hierarchy reaches over AIA. On a host presenting Global Virtual TPM CA - 03 there is no AIA to walk, and tpm2_getcap handles-nv-index confirmed the intermediates are not stored elsewhere in NV as a fallback. So the chain cannot be assembled at all and verify_tpm_quote fails with "AK chain root is not among the supplied trusted TPM roots".
That failure is correct: key provenance genuinely cannot be established on such a host with what we have. But the consequence is that cMCP's TPM provenance story works on some Azure VMs and not others, with no way for an operator to tell in advance. Details and the corrected doc are in #452.
What is needed
- Obtain the
Global Virtual TPM CA - 03 certificate and its chain up to a self-signed root, from a Microsoft-published source that can be cited. It is not fetchable from the AK certificate itself, since there is no AIA.
- Pin that root alongside
AZURE_VTPM_ROOT_2023_PEM, keyed by platform so trusted_roots_for can return both for Azure.
- Confirm on hardware that a host presenting this hierarchy then verifies end to end. That means provisioning until a VM of that generation is drawn, which is not directly selectable;
D2s_v7 in eastus2 produced one on 2026-08-01.
- Decide what a deployment does when neither root matches: fail closed is the current behaviour and is probably right, but the error should name the unrecognised issuer so an operator can act on it rather than reading a generic chain failure.
Why not just walk AIA
There is nothing to walk. This is the constraint that makes the issue a sourcing problem rather than a code problem, and it is why it cannot be fixed the way #449 and #450 fixed the CA-11 path.
Open question for whoever picks this up
Whether Microsoft publishes the Global Virtual TPM CA - 03 intermediate and root in a durable, linkable location. If not, this becomes the same shape as the client firmware TPM vendor-root problem in the RFC's section 6: a dependency only the platform vendor can resolve. In that case the honest outcome is to document Azure TPM provenance as hierarchy-dependent rather than to keep implying it is universal.
Related: #431 (closed, shipped the chain-carrying code), #452 (the hardware finding), #439 section 6.
Split out of #431, which stays closed: its code deliverable shipped and works. This is the gap that code cannot close on its own.
The problem
Azure Trusted Launch presents two vTPM attestation-key certificate hierarchies concurrently at NV index
0x01C101D0. Measured on hardware:D2s_v5, eastus, 2026-07-31D2s_v7, eastus2, 2026-08-01Azure Cloud Virtual TPM CA - 11Global Virtual TPM CA - 03Azure Virtual TPM Root Certificate Authority 2023cmcp_verify/tpm_roots.pypins only the 2023 root, which the CA-11 hierarchy reaches over AIA. On a host presentingGlobal Virtual TPM CA - 03there is no AIA to walk, andtpm2_getcap handles-nv-indexconfirmed the intermediates are not stored elsewhere in NV as a fallback. So the chain cannot be assembled at all andverify_tpm_quotefails with "AK chain root is not among the supplied trusted TPM roots".That failure is correct: key provenance genuinely cannot be established on such a host with what we have. But the consequence is that cMCP's TPM provenance story works on some Azure VMs and not others, with no way for an operator to tell in advance. Details and the corrected doc are in #452.
What is needed
Global Virtual TPM CA - 03certificate and its chain up to a self-signed root, from a Microsoft-published source that can be cited. It is not fetchable from the AK certificate itself, since there is no AIA.AZURE_VTPM_ROOT_2023_PEM, keyed by platform sotrusted_roots_forcan return both for Azure.D2s_v7in eastus2 produced one on 2026-08-01.Why not just walk AIA
There is nothing to walk. This is the constraint that makes the issue a sourcing problem rather than a code problem, and it is why it cannot be fixed the way #449 and #450 fixed the CA-11 path.
Open question for whoever picks this up
Whether Microsoft publishes the
Global Virtual TPM CA - 03intermediate and root in a durable, linkable location. If not, this becomes the same shape as the client firmware TPM vendor-root problem in the RFC's section 6: a dependency only the platform vendor can resolve. In that case the honest outcome is to document Azure TPM provenance as hierarchy-dependent rather than to keep implying it is universal.Related: #431 (closed, shipped the chain-carrying code), #452 (the hardware finding), #439 section 6.