feat(a2a-trust-header): Week 3 dual-provider consumer verifier + canonical schema#6
Open
aeoess wants to merge 6 commits into
Open
Conversation
Draft 2020-12 schema at schema/a2a-trust-header.schema.json lock of the Week 1 agreement with MolTrust for A2A#1742 x-agent-trust header: trust_level / attestation_count / last_verified / evidence_bundle / delegation_chain_root, all required. delegation_chain_root is pattern-constrained to sha256:<hex> OR uri:https://... per the self-describing form agreed in #1742. additionalProperties: true so providers can emit vendor-specific sibling fields without coupling the canonical contract. Refs: a2aproject/A2A#1742
Private workspace package. Deps:
- agent-passport-system ^2.0.0 (canonicalizeJCS helper, SDK verifier)
- @noble/ed25519 ^2.0.0 (verifier uses this instead of APS SDK so
MolTrust-shaped fixtures verify without a hard APS-SDK dependency)
- ajv ^8.0.0 + ajv-formats ^3.0.0 (canonical schema validation,
including format: date-time on last_verified)
.gitignore: node_modules/
Week 2 verify.ts imported canonicalizeJCS + verify from the absolute path /Users/tima/agent-passport-system/src/index.js, which broke for any consumer running outside Tima's laptop, including MolTrust and CI. Replace with npm-resolved 'agent-passport-system' import. Behavior is otherwise identical: same named imports, same verifier logic, same 6/6 fixture round-trip on disk-identical fixtures. Also replace the absolute DIR constant with a module-relative path derived via fileURLToPath(import.meta.url) + dirname so the verifier is fully portable. Refs: a2aproject/A2A#1742
Synthetic MolTrust-shaped emissions MolTrust replaces with their real
fixtures when they ship Week 3 on their side. Every fixture:
- carries the canonical 5-field composite header directly on
header_value (trust_level / attestation_count / last_verified /
evidence_bundle / delegation_chain_root)
- is marked _placeholder: true and
_replace_with_real_moltrust_emission: true
- is Ed25519-signed with a deterministic test seed (tail 0xAA,
documented in generate-placeholder.ts); public half embedded on
every fixture for round-trip verification
- uses RFC 8785 JCS canonicalization (same as APS) so both
providers share canonicalization conventions
Fixtures:
1. trust-trajectory-decay.json trust_level 4 -> 3 -> 2
2. attestation-accumulation.json attestation_count 2 -> 7 -> 15
3. shared-happy-path-moltrust.json same chain + root as APS
happy-path.json, re-signed
The generator is committed so MolTrust can see exactly how the shape
was constructed. Replacement workflow documented in README.md.
Refs: a2aproject/A2A#1742
consumer-verify.ts validates BOTH APS and MolTrust-shaped fixtures
against the canonical 5-field composite schema locked in Week 1.
Discovers every *.json at the top of a2a-trust-header/ (excluding
_keys.json, package*.json, tsconfig.json, anything prefixed with _)
and under moltrust-placeholder/. For each fixture:
1. Classify issuer (aps | moltrust | unknown) by inspecting
header_value.issuer / did / attestation kid prefixes /
agent_card trust signals.
2. Derive canonical composite view. MolTrust fixtures carry the
5 fields directly on header_value (derivation=direct). APS
fixtures reduce attestations[] into the 5-field composite
(derivation=aps-synthesized).
3. Schema-validate the composite via ajv (Draft 2020-12), with
ajv-formats so format: date-time actually fires at runtime.
4. Verify every Ed25519 signature encountered (delegation links,
attestations, agent_card trust signals, deny receipts, MolTrust
inline emission signature, trajectory entries). Uses
@noble/ed25519 verifyAsync so MolTrust-side consumers do not need
the APS SDK for signature verification.
5. Recompute delegation_chain_root from inline chains. Mismatch is
reported but not a failure when fixture declares
format_variant: true (Week 2 drift case).
Exit codes:
0 = all fixtures pass
1 = any signature or chain-root failure
2 = any schema failure
First run: 6/6 APS pass, 3/3 MolTrust placeholder pass, exit 0.
Refs: a2aproject/A2A#1742
Adds Week 3 section covering:
- canonical 5-field composite schema (location, field contracts,
self-describing delegation_chain_root, additionalProperties: true)
- composite view derivation (direct for MolTrust, aps-synthesized
for APS) so the same schema covers both provider shapes
- consumer verifier contract, usage, output row shape, exit codes
- MolTrust placeholder fixture catalog with a clear replacement
workflow MolTrust follows when they ship Week 3 on their side
- placeholder signing-key disclosure (deterministic test seed,
replace before production)
- Ed25519 / JCS canonicalization conventions shared across providers
Week 2 content preserved verbatim under a new "Week 2" heading.
Refs: a2aproject/A2A#1742
This was referenced Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Week 3 of the Week 1 (schema lock) → Week 2 (APS fixtures, PR #2) → Week 3 arc for the A2A
x-agent-trustheader under a2aproject/A2A#1742.This PR turns the Week 1 schema lock into runnable artifacts and adds MolTrust-shaped placeholder fixtures so the consumer verifier can exercise both provider shapes end-to-end before MolTrust ships their half.
What landed
a2a-trust-header/schema/a2a-trust-header.schema.json): Draft 2020-12. 5 required fields:trust_level/attestation_count/last_verified/evidence_bundle/delegation_chain_root.delegation_chain_rootis pattern-constrained to the self-describingsha256:<hex>ORuri:https?://…form.additionalProperties: trueso providers can emit vendor-specific sibling fields without coupling the canonical contract.a2a-trust-header/consumer-verify.ts): discovers every fixture at the top ofa2a-trust-header/and undermoltrust-placeholder/, classifies each by issuer (APS / MolTrust / unknown), derives the canonical composite view (direct for MolTrust-shape, synthesized for APS-shape), schema-validates via ajv + ajv-formats, and verifies every Ed25519 signature via@noble/ed25519(no APS SDK dependency for signature verification, so MolTrust-side consumers can run it as-is). Emits per-fixture compliance rows and aggregate summary. Exit codes:0all-pass,1signature/chain-root failure,2schema failure.a2a-trust-header/moltrust-placeholder/):trust-trajectory-decay.json(4→3→2),attestation-accumulation.json(2→7→15),shared-happy-path-moltrust.json(re-signs the APS happy-path chain under the MolTrust placeholder key). All marked_placeholder: true/_replace_with_real_moltrust_emission: true. Signed with a deterministic test seed (tail0xAA), public half embedded for round-trip verification. Generator committed so MolTrust can see exactly how the shape was constructed.Week 2 → Week 3 diff
schema/a2a-trust-header.schema.json, Draft 2020-12verify.ts)consumer-verify.ts) + Week 2 round-trip@noble/ed25519for signaturesThe Week 2
verify.tsabsolute-path import (/Users/tima/agent-passport-system/src/index.js) was replaced with a portableimport 'agent-passport-system'so any consumer, including MolTrust and CI, can run it. Week 2 round-trip is byte-identical otherwise: 6/6 fixtures still pass.MolTrust placeholder replacement workflow
When MolTrust ships Week 3 on their side:
moltrust-placeholder/with their real emission. Keep filenames so the consumer verifier picks them up automatically._placeholder/_replace_with_real_moltrust_emissionfields.moltrust_signing_keywith production kid + pubkey and re-sign every emission under that key.npx tsx consumer-verify.ts. All 9 fixtures (6 APS + 3 MolTrust real) must pass schema + signature + chain-root checks, exit 0.The consumer verifier does not implement MolTrust import weighting (0.3 weight, 45-day half-life,
POST /identity/resolvebefore import) — that is a downstream policy decision. What this PR guarantees is the preconditions weighting sits on top of: every 5-field composite is schema-conformant, cryptographically verifiable, and chain-root consistent.Verification output
Not touched
happy-path.json,drift-explicit-flag.json,revocation-mid-chain.json,shared-card-crossorg.json,trust-level-ascending.json,trust-level-descending.json),_keys.json, orgenerate.ts. Locked at the hashes committed in PR feat(a2a-trust-header): APS Week 2 fixture set per A2A#1742 #2.Refs