Skip to content

refactor(tpm): delegate NV certify parsing to Agent Manifest - #601

Merged
imran-siddique merged 1 commit into
agentrust-io:mainfrom
noah-ing:refactor/canonical-nv-certify-parser
Sep 2, 2026
Merged

refactor(tpm): delegate NV certify parsing to Agent Manifest#601
imran-siddique merged 1 commit into
agentrust-io:mainfrom
noah-ing:refactor/canonical-nv-certify-parser

Conversation

@noah-ing

@noah-ing noah-ing commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

What

  • Retire cMCP's duplicate TPMS_ATTEST / TPMS_NV_CERTIFY_INFO wire parser and delegate parsing to agent_manifest.parse_tpm_nv_certify.
  • Preserve cMCP's public parse_nv_certify() return shape and ValueError contract while using the canonical parser's exact-buffer and union-type checks.
  • Verify AK signatures over the canonical inner TPMS_ATTEST bytes when evidence arrives in TPM2B_ATTEST transport framing.
  • Add a checksummed two-certify swtpm reference pair that exercises the released parser, certificate-chain check, TPM signature envelopes, phase bindings, index identity, and extend relation end to end.

Why

Agent Manifest PR agentrust-io/agent-manifest#304 added the canonical NV-certify parser in release 0.11.2 and explicitly enabled cMCP to retire its remaining local wire parser. cMCP already requires agent-manifest>=0.11.2, so keeping both implementations only preserves a trust-boundary split.

The implementations had also developed observable framing differences: the local parser rejected valid size-prefixed TPM2B_ATTEST input and did not require nvContents to consume the complete signed structure. This completes the downstream migration without introducing a new dependency or public API.

Security impact

TPM wire parsing now has one authority across Agent Manifest and cMCP. For size-prefixed transport, signature verification covers parsed.attest.raw—the inner structure signed by the AK—not the unsigned two-byte transport length. Quote/NV type confusion, truncation, and undeclared trailing data remain fail-closed.

cMCP still owns the gateway-specific two-certify phase binding, same-index check, expected gateway digest, and extend relation. The configured AK trust-root and signature requirements are unchanged.

The reference corpus is software-TPM evidence under a synthetic test CA. It does not establish physical TPM or TEE provenance, vendor enrollment, EK-to-AK activation, hardware key residency, requester/TPM co-location, boot state, or runtime integrity.

Test plan

  • pytest passes — 1,474 passed, 6 pre-existing environment-gated hardware skips; 86.95% coverage in an autocrlf=true clean checkout.
  • ruff check passes.
  • mypy passes across 65 source files.
  • Manual test performed (described below).

Additional verification:

  • 33 focused tests pass on Python 3.11, 3.12, and 3.13.
  • Bandit reports no issues; pip-audit --skip-editable reports no known dependency vulnerabilities.
  • Wheel and sdist build, pass twine check, install independently, import outside the checkout, and pass the installed CLI smoke.
  • Strict MkDocs build passes.
  • No-cache Docker build passes; the runtime imports Agent Manifest 0.11.2 and runs as UID/GID 10001.
  • Gitleaks reports zero findings; detect-secrets passes after excluding the documented public TPM fixture bytes and qualifying-data digests.

Manual producer path:

  1. Started a fresh swtpm 0.7.3 instance and created a restricted RSA-2048 RSASSA/SHA-256 AK with tpm2-tools 5.6.
  2. Defined and seeded a SHA-256 TPM_NT_EXTEND index, certified its pre-value, extended the gateway digest, and certified its post-value.
  3. Wrapped the exact AK public key in a synthetic test certificate, then removed all private CA material, TPM state, and object contexts.
  4. Verified both bare and size-prefixed forms, exact index Name and contents, post == SHA256(pre || gateway_digest), replay rejection under a new nonce, signature-tamper rejection, and every committed artifact checksum.

DCO sign-off

Signed-off-by: Noah Ingwers <98993329+noah-ing@users.noreply.github.com>
@noah-ing
noah-ing requested review from a team as code owners September 2, 2026 02:34
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Sep 2, 2026
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The migration to the Agent Manifest parser is a clean delegation, the swtpm reference corpus and the expanded unit coverage are welcome additions, and all functional checks are green. Thanks Noah.

@imran-siddique
imran-siddique merged commit 415b50d into agentrust-io:main Sep 2, 2026
12 of 13 checks passed
@noah-ing

noah-ing commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the detailed review and for carrying this through #602 and the 0.4.1 release. I especially appreciated the careful scope correction and the authorship credit. Working through the verifier boundary and reproducing the issue concretely taught me a great deal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants