Signature-Agent header
A Signature-Agent header points verifiers at the directory that holds your keys; it should be present and a well-formed structured-field dictionary.
What this check verifies
A Web Bot Auth request carries a Signature and a Signature-Input header, and usually a Signature-Agent header that names the directory holding the signing key. Since the -05 drafts the value is an RFC 8941 structured-field dictionary whose member values are quoted strings holding a URI:
Signature-Agent: agent2="https://example.com"
The older serialization, a bare quoted string ("https://example.com"), is explicitly marked as legacy in the draft’s examples. The checker accepts both, passes the dictionary form cleanly, and notes the legacy form so you know an update is recommended.
The directory draft allows three URI schemes for member values: https (recommended), http, and data (an inline directory). The check warns when the header is present but not parseable as either form, or when a member value is not an https/http/data URI. When the header is absent the check warns too, but only as advice, because the architecture draft only requires signature-agent to be covered by the signature when the header is sent at all.
The header has a second effect. If you send it, signature-agent becomes a required covered component, checked under Required components covered.
Known limitation: the paste-headers verifier recognizes data: scheme members as well-formed but does not resolve inline directories; paste the key set into the Directory field instead.
Why it matters
Signature-Agent tells a verifier where to fetch your public keys. Without it, a verifier has to already know which directory belongs to your agent, which only works for agents it has seen before. With it, any verifier can resolve keyid against the named directory and check the signature with no prior arrangement.
If the header is present but malformed, a strict verifier may reject it or read the wrong value, and the request fails to verify even when the key and signature are otherwise fine. The dictionary form also matters for intermediaries: the member key is what the covered component references ("signature-agent";key="agent2"), which is how a proxy can relabel a signature without breaking it.
How to fix it
- Send the header as a structured-field dictionary with the directory URL as a quoted-string member:
Signature-Agent: agent2="https://example.com"
- Use an HTTPS URL that hosts the directory at the well-known path, the same origin a verifier will fetch to resolve
keyid. - Cover the member in
Signature-Input("signature-agent";key="agent2"). Sending the header but leaving it uncovered is a covered-components failure. - If you still send the legacy string form, plan the move to the dictionary form; the draft keeps the old form only for backward compatibility.
If your agent does not send the header at all, that is allowed. This check only warns, and the rest of the signature can still verify against a directory the verifier already knows.
References
- RFC 9421 defines HTTP Message Signatures, including the
SignatureandSignature-Inputheaders. - RFC 8941 defines structured field values, including dictionaries and string items.
- The web-bot-auth directory draft defines the Signature-Agent header (dictionary form, allowed URI schemes); the architecture draft marks the string form as legacy.
- How grading works explains how advisory checks affect the score.
How the checker scores this
- Tier
- Signature
- Role
- Advisory. Failing this never caps the grade or changes the verdict.
- Point deduction
- A failure deducts 30 points; a warning deducts 8.