signatures
Signed requests and responses between a runner and the platform.
Every request a runner sends, and every response the platform returns, carries
an HTTP Message Signature (RFC 9421) made with Ed25519 and a Content-Digest
of its body (RFC 9530). The covered components are fixed:
- a request covers its method, path, query and body digest;
- a response covers its status and body digest, and the method, path, query, body digest and signature of the request it answers. The request's signature carries its nonce, so a response answers exactly one request and cannot be replayed as the answer to another, even an identical one.
The signature's created time must lie within MAX_SKEW_SECONDS of the
verifier's clock, and every signature carries a random nonce. Ed25519 is
deterministic, so without the nonce two identical requests in one second
would carry identical signatures. A verifier that remembers the signatures it
has seen for that long refuses a replayed message.
Verification is strict: a message whose Signature-Input is not exactly the
one this module would write, for the expected components, is refused. Only
this protocol's two parties speak it, so there is nothing to negotiate.
ParsedSignature
dataclass
¶
A message's signature, read but not yet verified.
RequestParts
dataclass
¶
What a signature covers of a request.
ResponseParts
dataclass
¶
What a signature covers of a response.
SignatureError
¶
Bases: Exception
A message's signature or digest does not hold.
content_digest(body)
¶
Return the Content-Digest field value for a body (SHA-256).
new_nonce()
¶
Return a random nonce for one signature.
parse_signature(headers)
¶
Read a message's signature without verifying it.
The caller looks up the key named by keyid and passes it to
:func:verify_request or :func:verify_response. Anything malformed
raises SignatureError, never another exception.
sign_request(key, keyid, request, created)
¶
Return the headers that sign a request.
sign_response(key, keyid, response, request, request_signature, created)
¶
Return the headers that sign a response to request, signed with request_signature.
signature_base(covered, params)
¶
Return the signature base for covered components and their values.
covered holds each component identifier as it is serialised (for
example '"@method"' or '"@path";req') with its value.
signature_params(components, created, keyid, nonce=None)
¶
Return the @signature-params value for covered components.
verify_request(parsed, headers, request, public_key, now)
¶
Verify a request's digest and signature, or raise SignatureError.
verify_response(parsed, headers, response, request, request_signature, public_key, now)
¶
Verify a response to a request signed with request_signature, or raise SignatureError.