Directory response self-signature
The directory response should carry its own HTTP Message Signatures, one per key, covering the request authority and the Content-Digest of the body, so verifiers can ignore mirrored or misattributed key sets. Advisory.
What this check verifies
The protocol draft recommends that the directory response itself is signed: one HTTP Message Signature per key in the set, made with that key, attached to the response as Signature and Signature-Input headers. A directory that signs must cover two components:
"@authority";req: the authority of the request that fetched the directory. Thereqflag marks a request component on a response signature.content-digest: the RFC 9530 digest of the response body, sent as aContent-Digestheader.
Each signature also carries created, expires, a keyid that is the key’s RFC 7638 JWK thumbprint, and the tag http-message-signatures-directory.
This check reads those response headers, rebuilds the signature base from every covered component, verifies the signatures against the keys in the directory body, and checks the Content-Digest against the body it received:
- No
Signature/Signature-Inputon the response: advisory warning, because signing is RECOMMENDED, not required. - A signature verifies and covers
"@authority";reqandcontent-digest, and the digest matches the body: pass. - A signature verifies but does not cover
content-digest: warning. The draft requires both components once a directory signs. - A signature verifies but its digest cannot be checked: warning. This happens when the body exceeds 256 KiB, or when a content-encoded (for example gzip) response does not match after decoding, since RFC 9530 digests the encoded bytes.
- A signature verifies, but the digest does not match the body, the
Content-Digestis malformed or uses no algorithm the checker supports (sha-256,sha-512), thekeyidis akidlabel instead of the thumbprint, or@authoritylacks thereqflag: fail, with the reason in the message. - The signature covers a field the response does not carry, such as
content-digestwithout aContent-Digestfield: fail. - A signature covers components the checker cannot rebuild for a response (for example a request component like
"@method";req), or uses a non-Ed25519 key: warning that names the limitation. - Signatures present but none verify, or all are expired: fail, because a broken self-signature is worse than none.
It never caps the grade and never changes the verdict.
Why it matters
The self-signature proves possession: whoever serves the directory also holds the private keys it advertises. Without it, anyone can mirror your key set at their own well-known path and pose as the operator of those keys; the keys are public, after all. A verifier that validates the response signature can ignore keys that arrive without proof of possession, which shuts down mirrored and misattributed directories.
Because the signature covers the request’s authority, a captured response cannot be replayed for a different host. Because it covers content-digest, it also binds the exact key set in the body: a signature lifted onto a different body no longer matches.
How to fix it
- At serve time, compute the SHA-256 digest of the exact response body and send it as
Content-Digest: sha-256=:<base64>:. - Sign the response with each key in the set, covering
("@authority";req "content-digest"), withcreated,expires, the thumbprint askeyid, and the taghttp-message-signatures-directory. Keep the window short; the headers are computed per response, so a few minutes is plenty. - The
directoryResponseHeadershelper in the 0.1.xweb-bot-authpackage covers"@authority";reqonly, so its output earns the warning above. The signature base is three lines ("@authority";req: <host>,"content-digest": <field value>,"@signature-params": <inner list and parameters>), so building it by hand and signing it with the key is straightforward. - A static file host cannot set per-request signatures. Serve the well-known path from a small handler (a Worker or equivalent) when you want this pass; until then the check stays an advisory warning.
This site’s own directory does this; check webbotauth.net and compare the response headers.
References
- The Web Bot Auth protocol draft (draft-ietf-webbotauth-httpsig-protocol-00, Appendix B.1) defines the response signing mechanism, covered components, tag, and validation rules; Appendix E.2.3 has a test vector. It replaces the earlier directory draft.
- RFC 9421 defines response signatures and the
reqcomponent flag. - RFC 9530 defines the
Content-Digestfield. - How grading works explains how advisory checks affect the score.
How the checker scores this
- Tier
- JWKS directory
- Role
- Advisory. Failing this never caps the grade or changes the verdict.
- Point deduction
- A failure deducts 25 points; a warning deducts 6.