# RequestSeal v0.2.0 - Table of Contents

> Sign and verify HTTP requests and responses in Elixir: RFC 9421 HTTP Message Signatures, Web Bot Auth for AI agents, JWS/JWE, digests and replay protection, with Plug (including Phoenix), Req, Finch and Ash integrations.

## Pages

- [Changelog](changelog.md)
- [LICENSE](license.md)
- [NOTICE](notice.md)

- Start here
  - [RequestSeal](readme.md)

- Guides
  - [Develop RequestSeal](getting-started.md)
  - [Sign and verify HTTP messages](signing-and-verifying.md)
  - [Verify webhook signatures in Phoenix and Plug](phoenix-and-plug.md)
  - [Sign Req and Finch requests and verify responses](req-and-finch.md)
  - [Map verified requests to Ash actors and tenants](ash.md)
  - [Webhooks with ash_hooks](ash-hooks.md)
  - [Sign and verify Web Bot Auth agents](web-bot-auth.md)
  - [Reject repeated signed requests](replay-protection.md)
  - [Discover trusted public keys over HTTPS](key-discovery.md)
  - [Sign JWS and encrypt JWE envelopes](jose.md)
  - [Keep signing keys behind a handle](key-custody.md)
  - [Testing and evidence](testing.md)

- Reference
  - [Domain glossary](glossary.md)
  - [Standards and counterpart contracts](standards.md)

- Design and decisions
  - [ADR 0001: Own one native standards library](0001-library-boundary.md)
  - [ADR 0002: Preserve lossless HTTP evidence before interpretation](0002-lossless-http-and-structured-fields.md)
  - [ADR 0003: Make profiles source-bound and ambiguity fail-closed](0003-source-bound-profiles.md)
  - [ADR 0004: Keep key custody external and discovery controlled](0004-key-custody-and-discovery.md)
  - [ADR 0005: Claim replay atomically for the complete authenticated envelope](0005-atomic-replay-envelope.md)
  - [ADR 0006: Return layered verification facts and bounded safe diagnostics](0006-verification-results-and-observability.md)
  - [ADR 0007: Keep adapters optional and byte-preserving](0007-framework-and-proxy-adapters.md)
  - [ADR 0008: Separate exact development identity from proven consumer compatibility](0008-toolchain-and-compatibility.md)
  - [ADR 0009: Make an independent corpus the Elixir–TypeScript semantic contract](0009-cross-language-corpus.md)
  - [ADR 0010: Treat documentation and Livebooks as tested public interfaces](0010-dx-and-livebooks.md)
  - [ADR 0011: Keep application replay identity and public-source provenance explicit](0011-public-contract-provenance.md)
  - [ADR 0013: Keep named application profiles in extension packages](0013-extension-profile-boundary.md)
  - [RequestSeal architecture](architecture.md)
  - [RequestSeal threat model](threat-model.md)

- Livebooks
  - [Executable Livebooks](livebooks.md)
  - [Inspect RequestSeal](environment.md)
  - [Verify a published HTTP signature](rfc-ed25519.md)

- Contributing
  - [Contributing](contributing.md)
  - [Security and disclosure](security.md)
  - [Release and maintenance runbook](releases.md)

## Modules

- [RequestSeal.Message.Error](RequestSeal.Message.Error.md): Bounded message-construction errors. No supplied bytes appear in errors.
- [RequestSeal.SignatureBase.Error](RequestSeal.SignatureBase.Error.md): Bounded signature-base errors, without supplied bytes or partial output.

- Core
  - [RequestSeal](RequestSeal.md): HTTP message signatures under explicit caller policy and custody.
  - [RequestSeal.AcceptSignature](RequestSeal.AcceptSignature.md): RFC 9421 Section 5 signature requests and nonce challenges.
  - [RequestSeal.Body](RequestSeal.Body.md): Caller-owned body availability, without implicit reads or replayability.
  - [RequestSeal.Crypto](RequestSeal.Crypto.md): OTP cryptographic primitives over exact signature-base bytes, for custodians.
  - [RequestSeal.Crypto.Error](RequestSeal.Crypto.Error.md): Bounded primitive and public-key errors, containing no supplied material.
  - [RequestSeal.Digest](RequestSeal.Digest.md): [RFC 9530](https://www.rfc-editor.org/rfc/rfc9530.html) content/representation digests and preference fields, using OTP hashes.
  - [RequestSeal.Digest.Error](RequestSeal.Digest.Error.md): Bounded digest failures without body, field, or algorithm input bytes.
  - [RequestSeal.Error](RequestSeal.Error.md): Bounded failures from `RequestSeal.verify/3`, `RequestSeal.sign/4`, `RequestSeal.Policy.new/1`, `RequestSeal.Ash.scope/2`, `RequestSeal.Profile`, quorum verification, and signature negotiation.
  - [RequestSeal.FieldOccurrence](RequestSeal.FieldOccurrence.md): One ordered HTTP field occurrence, before normalization (RFC 9421 Section 2.1).
  - [RequestSeal.Message](RequestSeal.Message.md): Lossless HTTP message values for later component derivation.
  - [RequestSeal.Policy](RequestSeal.Policy.md): Explicit generic RFC 9421 acceptance policy; no implicit profile or required choices.
  - [RequestSeal.Quorum](RequestSeal.Quorum.md): Explicit composite RFC 9421 verification policy.
  - [RequestSeal.Quorum.Verification](RequestSeal.Quorum.Verification.md): Complete composite verification facts, returned only after all selected checks.
  - [RequestSeal.SignatureBase](RequestSeal.SignatureBase.md): Exact ordered RFC 9421 Section 2 signature-base construction.
  - [RequestSeal.StructuredFields](RequestSeal.StructuredFields.md): Bounded RFC 8941 / RFC 9651 parsing and canonical serialization.
  - [RequestSeal.StructuredFields.Error](RequestSeal.StructuredFields.Error.md): Bounded Structured Fields errors, containing no input bytes.
  - [RequestSeal.StructuredFields.Schema](RequestSeal.StructuredFields.Schema.md): Explicit field type restrictions and RFC revision (RFC 9651 Section 2).
  - [RequestSeal.StructuredFields.Value](RequestSeal.StructuredFields.Value.md): Ordered Structured Fields data (RFC 9651 Section 3).
  - [RequestSeal.TransportFacts](RequestSeal.TransportFacts.md): Enumerated caller declarations about HTTP transport.
  - [RequestSeal.Verification](RequestSeal.Verification.md): Complete facts for one explicitly selected HTTP signature profile.

- Keys and custody
  - [RequestSeal.Custody](RequestSeal.Custody.md): Caller-owned signing, secret verification, key unwrapping, and public metadata.
  - [RequestSeal.Custody.Context](RequestSeal.Custody.Context.md): Absolute monotonic millisecond deadline and original caller PID.
  - [RequestSeal.Custody.Error](RequestSeal.Custody.Error.md): Bounded custody failures. No exception, reference, key, socket path, peer text,
or input bytes are retained. Only `:deadline_exceeded` and
`:custodian_unavailable` are retryable; callers decide whether replay is safe.
  - [RequestSeal.Custody.Local](RequestSeal.Custody.Local.md): Caller-owned OTP private keys and symmetric secrets, held in sensitive processes.
  - [RequestSeal.Custody.SSHAgent](RequestSeal.Custody.SSHAgent.md): Non-exporting signing through a caller-selected OpenSSH agent Unix socket.
  - [RequestSeal.KeyHandle](RequestSeal.KeyHandle.md): Caller-owned, algorithm-bound signing, verification, or key-unwrapping capability.
  - [RequestSeal.KeyIdentity](RequestSeal.KeyIdentity.md): Internal trusted key equivalence, redacted from default inspection.
  - [RequestSeal.PublicKey](RequestSeal.PublicKey.md): Public-only RSA, P-256, P-384, and Ed25519 key formats and algorithm binding.

- Discovery
  - [RequestSeal.Discovery](RequestSeal.Discovery.md): Explicit bounded HTTPS discovery of HTTP Message Signatures Directories, JWKS
and Client ID Metadata Documents. Construct a `Discovery.Source` from trusted
caller configuration. A message/key ID never defines a URL to fetch.
  - [RequestSeal.Discovery.Cache](RequestSeal.Discovery.Cache.md): Optional caller-started bounded discovery cache; no timers or background refresh.
  - [RequestSeal.Discovery.Error](RequestSeal.Discovery.Error.md): Bounded discovery failures, containing only `reason` and `retryable`.
  - [RequestSeal.Discovery.KeySet](RequestSeal.Discovery.KeySet.md): Bounded source-bound public keys, freshness and directory proof status.
`revision` is SHA-256 over the fetched JSON bytes, not an origin-assigned sequence.
`lookup/3` accepts IDs under the source's explicit `key_id` mode and an algorithm
allowlist. Default IDs are computed RFC thumbprints; directory-assigned IDs
never replace cryptographic identity or thumbprint revocation. It rejects stale, revoked, incompatible or malformed entries. Key
restrictions remain enforced by `PublicKey`. Snapshot lookup uses system time;
the cache's `:clock` supports caller-controlled time for resolution/fetching.

  - [RequestSeal.Discovery.Resolution](RequestSeal.Discovery.Resolution.md): Public key and explicit discovery provenance. `key_id` is the selected
lookup ID; `thumbprint` is always the computed cryptographic identity. `algorithm` is the selected
cryptographic algorithm; `asserted_algorithm` is the source's HTTP token, if
present. Neither the source nor a possession proof establishes a principal or
authorizes an operation. Default inspection hides key material and provenance.
`revision` is the resolved KeySet's SHA-256 revision, propagated by lookup.
`expires_at` bounds the key/proof lifetime; KeySet separately bounds HTTP cache
freshness. Access fields explicitly when applying caller trust policy.

  - [RequestSeal.Discovery.Source](RequestSeal.Discovery.Source.md): Caller-configured discovery trust root. `new/1` requires `:type` (`:directory`,
`:jwks_uri`, or `:cimd`) and `:location` (HTTPS URL, at most 2,048 bytes).
A directory origin expands to `/.well-known/http-message-signatures-directory`.
CIMD requires a nonempty path; URLs reject userinfo, fragments and dot segments.
For CIMD, pass `:location` with exactly the spelling of the document's
`client_id`, including scheme/host case, any trailing host dot and explicit
port. The client ID comparison is exact; origin normalization for fetching
and same-origin checks never changes that comparison.

- Replay
  - [RequestSeal.Replay](RequestSeal.Replay.md): Atomic whole-envelope replay port with caller-owned stores and commitments.
  - [RequestSeal.Replay.AshOnetime](RequestSeal.Replay.AshOnetime.md): Recommended durable replay store over `AshOnetime.Transaction.nonce/2`.
  - [RequestSeal.Replay.Claim](RequestSeal.Replay.Claim.md): Bounded caller uniqueness and exclusive retention end in Unix seconds.
  - [RequestSeal.Replay.ETS](RequestSeal.Replay.ETS.md): Local atomic replay store owned by a caller-supervised GenServer.
  - [RequestSeal.Replay.Error](RequestSeal.Replay.Error.md): Bounded replay boundary failures, without adapter diagnostics or caller bytes.
  - [RequestSeal.Replay.Postgres](RequestSeal.Replay.Postgres.md): Optional Postgrex atomic replay adapter. The caller owns connections and DDL.
  - [RequestSeal.Replay.Receipt](RequestSeal.Replay.Receipt.md): Successful atomic claim; contains no namespace, uniqueness value, or store reference.
  - [RequestSeal.Replay.Store](RequestSeal.Replay.Store.md): Caller-owned replay adapter and reference. Importing it starts nothing.

- JOSE
  - [RequestSeal.JOSE](RequestSeal.JOSE.md): Bounded compact JOSE envelopes over OTP cryptography.
  - [RequestSeal.JOSE.Error](RequestSeal.JOSE.Error.md): Closed, redacted JOSE errors. Only `:deadline_exceeded` is retryable.
  - [RequestSeal.JOSE.JWE](RequestSeal.JOSE.JWE.md): Compact RFC 7516 encryption with explicitly pinned algorithms and AES GCM.
  - [RequestSeal.JOSE.JWE.Result](RequestSeal.JOSE.JWE.Result.md): Authenticated compact JWE plaintext. Recipient integrity establishes no origin or principal.
  - [RequestSeal.JOSE.JWS](RequestSeal.JOSE.JWS.md): Compact RFC 7515 signatures over exact protected and payload segments.
  - [RequestSeal.JOSE.JWS.Result](RequestSeal.JOSE.JWS.Result.md): Verified compact JWS. Header, protected segment and payload require explicit access.
  - [RequestSeal.JOSE.KeyManagement](RequestSeal.JOSE.KeyManagement.md): Custodian-side RFC 7518 key wrapping primitives over OTP.
  - [RequestSeal.JOSE.Nested](RequestSeal.JOSE.Nested.md): Verify exactly one compact JWS inside one authenticated compact JWE.

- Web Bot Auth
  - [RequestSeal.WebBotAuth](RequestSeal.WebBotAuth.md): Source-bound HTTP request signing and verification for
[draft-ietf-webbotauth-httpsig-protocol-00](https://www.ietf.org/archive/id/draft-ietf-webbotauth-httpsig-protocol-00.html).
  - [RequestSeal.WebBotAuth.Policy](RequestSeal.WebBotAuth.Policy.md): Explicit policy for `draft-ietf-webbotauth-httpsig-protocol-00`.
  - [RequestSeal.WebBotAuth.Verification](RequestSeal.WebBotAuth.Verification.md): Complete protocol-00 envelope facts after every selected signature succeeds.

- Integrations
  - [RequestSeal.Adapter.Error](RequestSeal.Adapter.Error.md): Bounded HTTP adapter failures, always nonretryable. `message/1` includes only
the reason and random correlation token; inspection excludes source details.
  - [RequestSeal.Ash](RequestSeal.Ash.md): Explicit caller-owned identity mapping for Ash policies and actions.
  - [RequestSeal.Ash.Scope](RequestSeal.Ash.Scope.md): Caller-bound actor, tenant, and bounded verification context for Ash actions.
  - [RequestSeal.AshHooks](RequestSeal.AshHooks.md): Optional ash_hooks inbound RFC 9421 verification bridge (Elixir 1.20).
  - [RequestSeal.AshHooks.Http](RequestSeal.AshHooks.Http.md): ash_hooks HTTP adapter signing final method, URL, headers, and body bytes.
  - [RequestSeal.Finch](RequestSeal.Finch.md): Optional finalized Finch translation and signing. No pool is started or owned.
  - [RequestSeal.Plug](RequestSeal.Plug.md): Optional Plug/Phoenix integration with explicit origin and verification policy.
  - [RequestSeal.Plug.Capture](RequestSeal.Plug.Capture.md): Capture a bounded request before destructive parsing or origin/IP rewriting.
  - [RequestSeal.Plug.SignResponse](RequestSeal.Plug.SignResponse.md): Sign final buffered response bytes in a Plug `before_send` callback.
  - [RequestSeal.Plug.Verify](RequestSeal.Plug.Verify.md): Verify the immutable captured request under an explicit policy and label.
  - [RequestSeal.Req](RequestSeal.Req.md): Optional Req final-attempt signing and verification before body decoding.

- Profiles
  - [RequestSeal.Profile](RequestSeal.Profile.md): Shared HTTP signature pipeline for profiles owned by extension packages.

