Exact ordered RFC 9421 Section 2 signature-base construction.
build/3 consumes a validated RequestSeal.Message and one signature's
parameterized Inner List, either serialized bytes or a
RequestSeal.StructuredFields.Value of type :inner_list. It returns
{:ok, bytes} or a bounded RequestSeal.SignatureBase.Error, never a partial
base. Components and all parameters retain their order; equivalent component
identifiers with reordered parameters reject. The final "@signature-params"
line has no trailing newline. This function performs no signing, verification,
key operation, body read, network request, or authorization.
All nine derived components are supported. @request-target, @path, and
@query preserve percent-encoded octets. @target-uri assembles the preserved
target URI without normalizing it. Only @authority and @scheme normalize
host/scheme case and the HTTP(S) default port. Origin-form requests need the
caller's explicit :scheme/:authority for these three origin components;
absolute-form requests provide them in the raw target. Host and Forwarded
fields never supply missing origin facts. Authority/asterisk-form target URIs
have empty paths (RFC 9110 Section 7.1); @path normalizes an empty path to /.
req requires a response with its validated original :related_request.
@query-param requires the canonical encoded name, rejects duplicate decoded
names, and preserves empty values. Parsing uses UTF-8 form semantics; encoding
uses RFC 9421 Section 2.2.8's percent-encode-after-encoding operation and its
published vectors (%20 for spaces, uppercase hex, no double decoding), under
the January 2024 URL Standard referenced by that RFC. Invalid UTF-8 rejects.
Field values trim only HTTP OWS, preserve internal bytes, and combine ordered
occurrences with comma-space. Capture must already have removed HTTP/1.1
obsolete folding: Message rejects CR/LF. bs wraps each trimmed occurrence
separately, including non-ASCII octets. Without bs, non-ASCII bytes reject.
tr selects only trailers; unavailable or pending trailers reject. For fields
whose unquoted commas make occurrence boundaries significant, callers must
select bs (RFC 9421 Sections 2.1.3 and 7.5.6).
Options:
:field_schemas— map of lowercase field names to explicit Structured Fields schemas, default%{}.sfandkeyrequire this knowledge.keyrequires a Dictionary schema and strictly serializes only the selected member. Schemas apply equally to headers, trailers, and the related request; the field's public specification selects its revision, never the input's syntax.:max_components— positive ceiling, default/maximum 256.:max_bytes— positive ceiling for the final base, default/maximum 1,048,576.
The Structured Fields parser's documented ceilings also apply to signature
parameters and sf/key fields (including 65,536 serialized bytes).
Unknown/duplicate options, malformed direct values, unknown or incompatible
component parameters, wrong parameter types, and unavailable components reject.
Extension signature metadata retains RFC 8941 types; registered created and
expires require Integers, and nonce, alg, keyid, and tag require Strings.
Successful construction establishes bytes only, not authentication.
Summary
Functions
Build one ASCII signature base from preserved message facts and ordered parameters.
Functions
@spec build( RequestSeal.Message.t(), binary() | RequestSeal.StructuredFields.Value.t(), keyword() ) :: {:ok, binary()} | {:error, RequestSeal.SignatureBase.Error.t()}
Build one ASCII signature base from preserved message facts and ordered parameters.