Repository navigation
fix(verify/tdx,embodied_action): enforce hex format in verify_tdx_measurement and guard non-dict inputs in verify_embodied_action_evidence (#803) - #806
Conversation
|
🟡 Contributor Check: MEDIUM
Automated check by AgenTrust Contributor Check. |
5f35696 to
6513313
Compare
carloshvp
left a comment
There was a problem hiding this comment.
Reviewed exact head 65133135cee9c487036649a2997ca95c53fd81c2 in an isolated checkout.
The measurement parser now requires the declared lowercase SHA-384 format, malformed report data follows the controlled mismatch path, and embodied-action evidence rejects malformed containers and digest values without treating receipt validity as proof of policy authorization or physical completion. No blocking finding in the changed paths.
Local hash-locked Python 3.12.10 validation: 2,528 unit tests passed, 20 skipped; pip check, Ruff, mypy and Bandit passed. All PR commits have sign-offs. git diff --check notes one extra blank line at test_tdx_verify.py EOF, a nonblocking cleanup. Hosted CI and required maintainer gates still need completion.
Reviewed with OpenAI Codex.
noah-ing
left a comment
There was a problem hiding this comment.
Reviewed current head 65133135cee9c487036649a2997ca95c53fd81c2. The new shape guards treat a supplied but malformed TRACE Claim like no Claim at all. With the repository’s valid signed ROS2 evidence fixture, claim_json={"trace": None, "gateway": None} returns verified=True, no failures or warnings, and omits all policy, catalog, and agent cross-bindings. The added test currently asserts that success. Please preserve None as the explicit no-Claim mode, but return a nonverified result when a supplied Claim has malformed sections, and add a negative regression for that distinction. This is a fail-closed helper-contract concern; I have not shown a bypass of the documented flow that verifies the full TRACE Claim first.
The TDX format changes behaved as intended. Local exact-head validation: 2,528 unit tests passed, 20 skipped; focused negative fixture replay passed. Hosted CI is blocked by the existing locked-dependency audit, and required governance checks remain outstanding.
|
Thanks @noah-ing and @carloshvp! Updated |
|
Thanks for the follow-up. I checked head |
dinakarjs
left a comment
There was a problem hiding this comment.
I prepared a signed adoption companion addressing the outstanding review finding: dinakarjs#6
Validation: unit suite 2547 passed/6 skipped; conformance+integration+confinement 114 passed/23 skipped. Ruff on src/tests, strict mypy and Bandit passed. All five malformed-identity parameter cases fail by assertion when just this fix is removed; valid/absent controls pass with the repair.
Please cherry-pick/adopt the companion and request independent re-review of the resulting head. I have contributed the follow-up and am not approving my own contribution.
|
Thanks @noah-ing! Distinguished absent |
|
Thanks @dinakarjs and @noah-ing! Adopted @dinakarjs's signed companion commit |
a59495d to
2411f8f
Compare
noah-ing
left a comment
There was a problem hiding this comment.
Reviewed exact head 2411f8f33811a9afdd63cfe80968527330d8c483. The supplied-but-malformed gateway.agent_identity cases now fail explicitly, while an absent identity remains optional; valid and mismatched identities behave as expected. I replayed nine cases against the signed ROS2 evidence fixture with receipt checking enabled. The focused tests passed (64/64), as did the full unit suite (2,533 passed, 20 skipped), Ruff, mypy, dependency and whitespace checks. This resolves my requested change, so I approve this scoped verifier fix. The normal hosted checks and merge gates still need to complete.
carloshvp
left a comment
There was a problem hiding this comment.
Reviewed exact head 2411f8f33811a9afdd63cfe80968527330d8c483 in an isolated checkout.
The updated source additionally rejects a supplied malformed Claim context and malformed present agent identity, while keeping the explicit no-Claim receipt-only mode and optional absent identity. The measurement, digest and container guards remain intact. Current receipt/Claim binding tests pass with valid controls; the reported receipt facts remain distinct from authorization and physical completion. No blocking finding in the updated paths.
Independent validation in a fresh repository-hash-locked Python 3.12.10 environment: 2,533 tests passed, 20 skipped; pip check, configured Ruff, mypy, Bandit and diff whitespace checks passed. Commit sign-offs are present. Hosted CI and applicable independent maintainer/security gates remain separate prerequisites to merge.
Reviewed with OpenAI Codex.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
rajnisht7
left a comment
There was a problem hiding this comment.
overall changes looks good, one gap still needs hardening:
current checks correctly reject non-string / empty / odd-length / non-hex. After that we still do:
expected_rd = bytes.fromhex(report_data_hex[:REPORT_DATA_SIZE * 2])so any pure-hex string longer than 128 chars is accepted as long as the first 128 match the actual 64-byte REPORT_DATA. The suffix is silently dropped and verification can still pass. reproduced it too with 130 / 168 / much longer inputs
short values are intentionally supported (zero-padded), so the missing piece is an upper bound:
len(report_data_hex) > REPORT_DATA_SIZE * 2->treat as report_data_mismatch.kindly add that check and a small regression (valid 128 hex + extra "aa" → fail, not verify). The quote path has the same [:128] pattern.
noah-ing
left a comment
There was a problem hiding this comment.
Updating my earlier approval in light of @rajnisht7's new finding at current head c2920f4ae450876923a15df513a5d491e3eed93c. I independently reproduced it: the direct TDX helper accepts a matching 128-character report_data_hex with additional hex bytes appended, records report_data as verified, and silently ignores the suffix. The quote path also truncates the supplied value. I did not establish a bypass of the full Claim path, which supplies a canonical 64-byte value.
Please reject inputs longer than 128 hex characters before decoding, retain the intended support for shorter zero-padded values, and add a negative regression for a valid value plus aa in the direct and quote paths. This is a scoped change request on the input-length contract; my earlier approval should not be read as covering this newly established gap.
…rt_data bound in TDX verifiers and fail closed on malformed embodied-action inputs (agentrust-io#803) - Require lowercase sha384:<96 hex chars> format and <=128 hex characters for report_data in verify_tdx_measurement and verify_tdx_quote before decoding, preserving zero-padding for shorter values. - Fail closed when supplied claim_json or gateway.agent_identity is malformed in verify_embodied_action_evidence while keeping claim_json=None as explicit receipt-only mode. - Add negative regression tests for oversized 130-char report_data_hex in both direct and quote TDX paths and malformed embodied-action claim sections. Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
c2920f4 to
d897245
Compare
|
Thank you @rajnisht7 and @noah-ing! Rebased onto
|
noah-ing
left a comment
There was a problem hiding this comment.
Reviewed exact head d897245d57139b9db7cd09e83357a73d37cef08f. Both the direct TDX measurement helper and quote verifier now reject report_data_hex longer than 128 characters before decoding, while retaining the intended shorter zero-padded inputs. The committed valid-value-plus-aa regressions require a failed result and no verified report_data field.
In a fresh Python 3.12.14 environment installed from the repository's hash-locked development requirements, the focused TDX direct, quote and embodied-action selection passed (75 passed, 2 skipped). Ruff passed on the touched TDX source and tests. This resolves my earlier overlong-input changes request, so I approve this scoped repair on this head. The result does not establish a full-Claim bypass or hardware validation; substantive hosted checks and the maintainer gate still need their normal disposition.
There was a problem hiding this comment.
Reviewed commit d897245d57139b9db7cd09e83357a73d37cef08f.
TDX measurement and nonce formats are checked before use. Embodied-action verification refuses non-object inputs and a supplied claim with missing or malformed required policy/catalog bindings; the digest lengths now match the selected hash algorithm.
Focused tests: 75 passed, 2 skipped; repository Ruff, mypy and configured Bandit pass. This is software verifier/parser evidence. Required hosted checks and the independent security review requirement remain in force.
What
Enforce
^sha384:[0-9a-f]{96}$measurement format and valid hexreport_data_hexinverify_tdx_measurement, and guard non-dict inputs and exact digest lengths inverify_embodied_action_evidence.Why
Closes #803.
Security impact
Ensures malformed TDX measurement strings or
report_data_hexvalues are classified accurately (invalid_measurement_formatandreport_data_mismatch), and prevents unhandledAttributeError/TypeErrorwhenverify_embodied_action_evidencereceives non-dict inputs or malformedclaim_jsonstructures.Test plan
pytestpasses (pytest tests/unit/test_tdx_verify.py tests/unit/test_embodied_action_evidence.py -q)ruff checkpasses (ruff check src/cmcp_verify/tdx.py src/cmcp_verify/embodied_action.py tests/unit/test_tdx_verify.py tests/unit/test_embodied_action_evidence.py)mypypasses (mypy src/cmcp_verify/tdx.py src/cmcp_verify/embodied_action.py)DCO sign-off
Developer Certificate of Origin (https://developercertificate.org).