[BAP] Bounded Authority · the Elixir reference

The reference signer, in Elixir.

bounded_authority_report_adapter is the holder/issuer companion signer the TypeScript package ports: it takes a {module, term()} key handle whose callbacks reach your own custody — an HSM, a KMS, an in-process test key — and produces the signed envelope. The private key never enters the library. The dependency is one-directional: this adapter depends on the protocol package, never the reverse; verifiers depend only on the protocol package, never on this adapter.

Issuersign_grant/3
grant
Holdersign_report/3
proof
Verifiercheck_envelope/2

The family lifecycle

Three protocols, one chain of evidence: what the agent is, what was agreed, what this call may do.

The signing surface

Six entry points, one shared signing tail, closed error atoms. The BoundedAuthorityReportAdapter.V3 module signs the four standard objects over ES256 with P-256 keys.

FunctionObjectRole
sign_report/3holder proof — the grant passes through untouched (major 1, Ed25519)holder
sign_local_loopback_report/3local-loopback application proof (ba+loopback-proof)holder
sign_anchor/3boundary anchorrole-agnostic
sign_key_transition/3key transitionrole-agnostic
sign_grant/3capability grantissuer-only, structurally gated
sign_content_assertion/3content assertion (ba+content-assertion)role-agnostic

What the reference guarantees

The properties the whole family inherits — enforced here first, ported verbatim.

Custody is the caller’s.

A signing library that touches key material becomes the most valuable target in your system.

The adapter only ever calls {module, term()} callbacks into your custody — and every sign path ends in a verify-against-the-public-key guard, so a misconfigured custodian fails loudly.

A holder cannot mint capability.

If the agent’s key can self-issue grants, the boundary is decorative.

sign_grant/3 resolves the issuer role atomically and fails closed before sign/2 is ever called — a holder handle cannot mint its own authority.

Nothing leaks in failure.

Error messages that narrate which check failed are reconnaissance gifts.

Closed error atoms, value-free telemetry — no key material, message bytes, or report content ever appears in an error or an event.

The family

One protocol, four repositories, two ecosystems — same wire bytes everywhere.

The protocol

The monorepo: wire specs, the errata, certified conformance corpora, the threat model.

The signer (TypeScript)

The npm port of this adapter — with the live envelope playground in your browser.

The verifier (TypeScript)

The npm verify side with its live bench — decode, check, tamper.

This repository

The Elixir reference signer. Docs, guides, recipes, and the upgrade path live on hexdocs.