Repository navigation
fix(trace_verify,tools): enforce registry-anchor-v1 surrogate/number rules, reject private JWKs, and harden MMR/JSON parsing - #147
Conversation
dinakarjs
left a comment
There was a problem hiding this comment.
Reviewed exact head f1ea2ff (full commit attached to this review). Checked strict MMR integer/proof boundaries, the public-JWK/base64url restrictions, duplicate-member parsing in the CLI/tool paths, and sorted-key anchor profile validation without replacing the separate signing canonicalizer. Local full unittest suite: 415 tests passed; Ruff passed. Hosted CI and CodeQL succeed. ClusterFuzzLite remains action_required and is not represented as executed evidence. No blocking finding.
rajnisht7
left a comment
There was a problem hiding this comment.
the fixes looks good, sorted-key profile checks, private JWK + canonical x, MMR exact-int, and loads_unique on the four named tools all check out. Scripts and new tests pass on this head.
One thing needs to be addressed:
- Profile walk now runs before json.dumps, but there’s no cycle detection. A self-referential dict hangs instead of failing closed. kindly detect cycles by identity, return a clear error, allow shared-but-acyclic objects, and add tests for cyclic dict/list in both _verify.py and tools/verify_inclusion.py.
Note: as-transmitted still returning raw_bytes without a profile check is consistent with the docs and existing design (exact bytes, no re-serialization). Tool intake already rejects out-of-profile claims, and we already have coverage that as-transmitted preserves exact bytes including whitespace/key order.
Follow-up (non-blocking):
- Surrogate wording can stay aligned with “unpaired” (behavior is fine in Python).
- is_already_anchored / load_published_entries / _registry_is_chained still use plain json.loads on published NDJSON; loads_unique there would match the hardening but is outside the #146 scope.
|
Thanks @rajnisht7! Addressed in the latest commit: |
|
Cycle detection looks correct, active-set + exiting frames in both copies, shared-but-acyclic objects still allowed, clear error. Tests exercise both implementations. needs follow up (non blocking):
|
…rules, reject private JWKs, and harden MMR/JSON parsing (agentrust-io#146) - Enforce registry-anchor-v1 section 1 profile rules (no floats, no integers outside -(2^53-1)..2^53-1, no unpaired UTF-16 surrogates U+D800..U+DFFF in object keys or strings, and cycle detection) in anchor_profile_violation and canonical_claim_bytes across src/trace_verify/_verify.py, tools/verify_inclusion.py, tools/anchor.py, and tools/batch_anchor.py, while documenting the as-transmitted exact-raw-bytes contract. - Reject RFC 7517 / RFC 7518 / RFC 8037 private or symmetric JWK parameters (d, p, q, dp, dq, qi, oth, k) and non-canonical base64url x encodings in src/trace_verify/_signature.py and tools/validate_producers.py. - Require exact int (type(v) is int, rejecting bool and IntEnum) in src/trace_verify/_mmr.py proof deserialization, builders (including inclusion_proof size), and verifiers. - Reject duplicate JSON object member names via loads_unique in tools/verify_inclusion.py, tools/verify_checkpoint_chain.py, tools/validate_registry.py, tools/validate_producers.py, tools/anchor.py (_registry_is_chained), and tools/batch_anchor.py (is_already_anchored, load_published_entries). Closes agentrust-io#146 Signed-off-by: Raghuvar Karthik Durga <177662415+drk-ram@users.noreply.github.com>
7bade9b to
fbb2c1e
Compare
|
Thanks @rajnisht7! Addressed all four follow-up items in |
What and why
Closes #146.
Fixes four verification and
registry-anchor-v1parity bugs acrosssrc/trace_verify/andtools/:registry-anchor-v1section 1 profile rules incanonical_claim_bytesandanchor_profile_violation:U+D800..U+DFFF) in string values and object keys, detect circular references (active: set[int]), and walk(list, tuple)inanchor_profile_violation.anchor_profile_violationinsidecanonical_claim_bytesacrosssrc/trace_verify/_verify.py,tools/verify_inclusion.py,tools/anchor.py, andtools/batch_anchor.py, raisingValueErroron floats, integers outside[-9007199254740991, 9007199254740991], unpaired surrogates, circular references, andRecursionError/TypeError, while preserving the explicitas-transmittedcontract (raw_bytesreturned verbatim without re-serialization).x:d,p,q,dp,dq,qi,oth,k) and non-canonical 32-byte base64urlxencodings (including non-zero trailing padding bits) insrc/trace_verify/_signature.py(validate_public_key_jwk/verify_claim_signature) andtools/validate_producers.py.intin MMR proof deserialization, builders, and verifiers:type(v) is int(rejectingbool,IntEnum,str, andfloat) inInclusionProof.from_dict,ConsistencyProof.from_dict,inclusion_proof,consistency_proof,verify_inclusion, andverify_consistencyinsrc/trace_verify/_mmr.py.loads_unique(object_pairs_hook) intools/verify_inclusion.py,tools/verify_checkpoint_chain.py,tools/validate_registry.py,tools/validate_producers.py,tools/anchor.py(_registry_is_chained),tools/batch_anchor.py(is_already_anchored,load_published_entries), andsrc/trace_verify/_signature.py.Validation
python -m unittest discover -s tests -q— passed (416 tests)python -m pytest tests/test_mmr_core.py tests/test_cli_duplicate_members.py tests/test_trace_verify_pkg.py tests/test_signature.py -q— passed (95 passed, 74 subtests passed)python -m ruff check src/ tools/ tests/— passed (All checks passed!)python tools/validate_registry.py— passed (OK: 3 day file(s) valid)python tools/validate_producers.py— passed (OK: 3 producer key file(s) valid)Registry impact
registry/Existing entries are append-only. If you are changing one, say why here: mirrors
and auditors may already have observed the current commit hashes, and a rewrite
diverges them.
Checks
pytestpassestools/validate_registry.py,tools/validate_producers.py)docs/anchor-format.mdis updated in the same PR, and existing inclusion proofs still verify