Modules
Captures the message handed to sign/2 — the no-canonical-bytes-fork tripwire for sign_anchor/3. Implements key_identity/1 so sign_anchor reaches sign/2.
key_identity/1 calls exit/1 (a simulated HSM/key-server timeout). safe_callback's catch clause must contain it -> :invalid_key_handle, not a crash.
keyidentity/1 + public_key/1 succeed; sign/2 returns {:error, } -> :signing_failed.
key_identity/1 + public_key/1 return key A's material, but sign/2 signs with a DIFFERENT key B (a rotation/misconfiguration race). The verify_signature guard in the shared signing tail must reject this -> :signing_failed.
A key-handle whose sign/2 violates the {:ok,}|{:error,} contract (returns :ok). Cross-vendor closeout finding: sign_via_handle/2 was non-total; a non-tuple return raised CaseClauseError. The catch-all now maps it to :signing_failed.
Universal companion signer to BoundedAuthorityProtocol.
TEST-ONLY loader for BAP's packaged local-loopback profile corpus (0.3.0).
TEST-ONLY translator: the vector's typed-JSON array form to BAP's tagged
Json.value() tuple form (design §1.6 A).
TEST-ONLY loader + builder for RA2's conformance round-trip harness.
TEST-ONLY reference implementation of the BoundedAuthorityReportAdapter
key-handle behaviour.
The closed, value-free telemetry surface for the five signing entry points.
Test-only key-handle modules for the sign_report (RA1) + sign_anchor (RA4) suites.
TEST-ONLY keypair fixtures + an issuer-side grant-signing helper for RA1's round-trip test.
Captures the message handed to sign/2 — the no-canonical-bytes-fork tripwire.
Counts sign/2 calls — the C1 tripwire (asserts exactly one signing call).
A key-handle whose public_key/1 calls exit/1 (simulating a GenServer.call timeout in a production HSM/key-server callback). Cross-vendor round 2 blocking finding: rescue did not catch exits, so this crashed the caller. The catch clauses now contain it -> :invalid_key_handle.
A key-handle whose sign/2 always fails — exercises the :signing_failed path.
Captures the sign/2 message — the no-canonical-bytes-fork tripwire for sign_grant.
signing_identity/1 calls exit/1 (simulated HSM/key-server timeout). safe_callback's catch clause must contain it -> :invalid_key_handle, not a crash.
signingidentity/1 + public_key/1 succeed; sign/2 -> {:error, } -> :signing_failed.
The C1 tripwire for sign_grant: signing_identity/1 -> {:holder, ...}, and sign/2 counts calls. sign_grant MUST reject a :holder handle BEFORE sign/2, so sign_call_count/0 stays 0. (The mirror of sign_report's CountingKeyHandle, which asserts sign/2 is called exactly once — pointed the other way.)
The issuer-role handle for sign_grant tests: signing_identity/1 -> {:issuer, 'issuer-2026-07', pub}.
The atomic-snapshot drift tripwire for sign_grant (the design-adversarial TOCTOU fix). signing_identity/1 returns a consistent {:issuer, kid_a, pub_a} snapshot, then flips internal state so sign/2 signs with priv_b (a simulated post-snapshot rotation). The atomic snapshot means role+kid+pub cannot drift apart; the verify_signature guard catches the sign/2-vs-snapshot mismatch -> :signing_failed, never a silent false-success. The handle term is an Agent pid whose state is %{kid:, pub_a:, priv_a:, priv_b:, rotated:}.
The roleless tripwire: implements sign/2 + public_key/1 + thumbprint/1 + key_identity/1 but OMITS signing_identity/1. sign_grant must reject it as :invalid_key_handle (the UndefinedFunctionError from apply/3 is caught by safe_callback). key_identity/1 is included to prove the rejection is role-specific (signing_identity absent), not key-identity-specific.
signing_identity/1 returns the handle's pub A; sign/2 signs with a DIFFERENT key B. The verify_signature guard in the shared tail catches the sign/2-vs-snapshot mismatch -> :signing_failed.
Defense-in-depth tripwire for the atomic key_identity/1 snapshot.
key_identity/1 returns a consistent {key_id, pub_a} snapshot, then flips
internal state so sign/2 signs with key-b (a simulated post-snapshot
rotation). The atomic snapshot means key_id+public_key cannot drift apart;
the verify_signature guard catches the sign/2-vs-snapshot mismatch ->
:signing_failed. This is the rotation race a cross-vendor (Codex) probe
exploited under the separate-callback design, now caught at sign time.
A key-handle whose public_key/1 returns a short (non-32-byte) key. Cross-vendor closeout finding: a short key passed the is_binary guard then failed downstream as {:producer_error, :invalid}. The guard now requires 32 bytes, so this fails fast as :invalid_key_handle.
Captures the message handed to sign/2 — the no-canonical-bytes-fork tripwire for sign_key_transition/3. Implements key_identity/1 so sign_key_transition reaches sign/2.
key_identity/1 calls exit/1 (a simulated HSM/key-server timeout). safe_callback's catch clause must contain it -> :invalid_key_handle, not a crash (mirror of AnchorExitingKeyHandle).
Defense-in-depth tripwire for the atomic key_identity/1 snapshot (the transition
analogue of RacingKeyIdentityHandle). key_identity/1 returns a consistent
{key_id, pub_a} snapshot, then flips internal state so sign/2 signs with priv_b
(a simulated post-snapshot rotation). The atomic snapshot means key_id+public_key
cannot drift apart; the verify_signature guard catches the sign/2-vs-snapshot
mismatch -> :signing_failed.
key_identity/1 returns the handle's pub A; sign/2 signs with a DIFFERENT key B (a rotation/misconfiguration race). The verify_signature guard in the shared tail must reject this -> :signing_failed (the mirror of AnchorWrongKeyHandle).
A key-handle whose public_key/1 returns key A but whose sign/2 signs with a DIFFERENT key B (a rotation/misconfiguration race). Cross-vendor round 2 should-fix finding: the adapter validated only 64-byte length, not that the signature verifies against the resolved public key. The adapter now verifies the signature against the public key -> :signing_failed.
Mix Tasks
Preflight-checks a key-handle module against the adapter's behaviour contract.
Scaffolds a starter key-handle module — the holder-side integration point.