BoundedAuthorityReportAdapter. Conformance. VectorCase
(Bounded Authority Report Adapter v0.5.0)
Copy Markdown
View Source
TEST-ONLY loader + builder for RA2's conformance round-trip harness.
Loads BAP's published grant-holder-proof.json vector (at the pinned dep ref)
once, decodes it, and builds the ExpectedRequest (bars i / iii / iv) /
ExpectedGrant (bar i-grant) / TrustedIssuer structs BAP's
check_envelope/2 + verify_grant/3 consume.
The three non-obvious pieces (design §1.6 — all first-hand verified)
- (A) Typed-tuple translation.
cast_argumentsMUST be BAP's taggedJson.value()form, not a raw map. The vector carries the typed form as a JSON array["type", value];Tag.from_json/1translates it. No type guard on the object/array arms —:json.decodeyields maps for JSON objects, andEnum.mapover a map yields{k,v}tuples. - (B) Synthesized
:bounds. The vector'sexpected_contextcarries nobounds; the structs require it (@enforce_keys).V1.Bounds.maximum/0is synthesized (BAP's default). - (C) Per-case nonce derivation. The shared
expected_context.nonceis{"required": "challenge-001"}, butpositive_cases.nonce_absentis a declared-VALID case whose proof payload carries NO nonce. Deriving the nonce expectation from the SHARED context reds that case; the expectation is derived PER CASE from the proof payload's nonce presence.
The selector_denied sub-cases carry their OWN typed_cast_arguments (a
different ba_req), so cast_arguments is derived per case when present.
Summary
Functions
The expected_context block (shared across the published cases).
Builds an %ExpectedGrant{} for bar (i-grant) — the grant-only verifier
surface. No nonce field on ExpectedGrant; bounds synthesized.
Builds an %ExpectedRequest{} for a published case.
The 32-byte raw issuer public key — the verifier's TRUST ANCHOR.
The %TrustedIssuer{} from the vector's expected_context.
The tagged Json.value() form of the vector's top-level cast_arguments,
via Tag.from_json/1. Verified: RequestDigest.digest_raw of this value
matches the vector's published ba_req.
The decoded published vector.
Functions
The expected_context block (shared across the published cases).
Builds an %ExpectedGrant{} for bar (i-grant) — the grant-only verifier
surface. No nonce field on ExpectedGrant; bounds synthesized.
Builds an %ExpectedRequest{} for a published case.
case is either :top_level (the top-level envelope) or a case map from the
vector (received_member_order_variant, a positive_cases / negative_cases
entry, a selector_denied sub-case). The builder:
- derives
cast_argumentsfrom the case's OWNtyped_cast_argumentswhen present (selector_denied carries a distinctba_req), else from the top-levelrequest.typed_cast_arguments; - derives
noncePER CASE (design §1.6 C): if the case's proof payload has a"nonce"key,{:required, that_nonce}; otherwise:not_required(the sharedexpected_context.noncewould rednonce_absent); - synthesizes
bounds: V1.Bounds.maximum/0(design §1.6 B); - carries the shared expected_context's request fields.
The 32-byte raw issuer public key — the verifier's TRUST ANCHOR.
Sourced from expected_context.trusted_issuer.public_key_base64url (the
authoritative trust anchor the verifier is configured with), NOT from
public_keys.issuer.raw_base64url (the signer's own published key). The two
match in the published vector, but sourcing from the expected_context means
a hypothetical signer-key/context-key mismatch fails the trust-anchor check
rather than silently verifying against the signer key (cross-vendor CV-trust
finding).
The %TrustedIssuer{} from the vector's expected_context.
The tagged Json.value() form of the vector's top-level cast_arguments,
via Tag.from_json/1. Verified: RequestDigest.digest_raw of this value
matches the vector's published ba_req.
The decoded published vector.