Skip to content

HTTP message signatures

Both SDKs sign and verify HTTP requests with the key behind an EID. The profile sits beside the Web Bot Auth row in OEIS-1 section 11.2: algorithm ed25519, keyid is the signer's did:key, covered components "@method" "@target-uri" "content-digest" (Content-Digest is RFC 9530 sha-256, omitted only for an empty body), label sig1, and created, expires and nonce all required. For a worked example with the Entity Gateway, read Sign HTTP requests as your entity.

The two implementations share the vectors in test-vectors/http-signature.json.

  • created no more than five minutes old (maxAge / max_age, default 300 seconds) and no more than five seconds in the future.
  • expires not in the past, and expires - created no more than maxAge.
  • nonce at least twenty-two characters (sixteen bytes in base64url).
  • Content-Digest equal to the SHA-256 of the body you pass, whenever the body is not empty.
  • keyid a canonical did:key; the public key comes from it, so no registry call is made.

Replay tracking is the caller's job: keep each nonce for the length of the window.

HttpSigError (Python openentity.errors, TypeScript @openentity/sdk) carries a .code: missing_headers, unknown_alg, bad_keyid, missing_nonce, digest_mismatch, created_in_future, created_too_old, expired, lifetime_too_long, bad_signature.

Return value of verify_request: {"did", "keyid", "created", "expires", "nonce"}.

http_sig_base(method: str, url: str, components: list[str], digest: str | None, params: str)
sign_request(method: str, url: str, body: bytes, private_key, did: str, *, created: int | None = None, expires_in: int = 60, nonce: str | None = None)
Sign a request. private_key is an Identity, a KeyPair or an Ed25519 seed. Returns Signature-Input, Signature and, for a non-empty body, Content-Digest.
verify_request(method: str, url: str, headers: Mapping[str, str], body: bytes, *, now: int | None = None, max_age: int = 300)
Verify a request signed by sign_request. Raises HttpSigError with .code. Nonce replay tracking is the caller's job.

Return value of verifyRequest: { did, keyid, created, expires, nonce }.

httpSigBase(method: string, url: string, components: string[], digest: string | undefined, params: string)
signRequest(o: { method: string; url: string; body?: Uint8Array; privateKey: KeyPair | Uint8Array; did: string; created?: number; expiresIn?: number; nonce?: string; })
Sign a request. privateKey is a KeyPair or an Ed25519 seed. Returns Signature-Input, Signature and, for a non-empty body, Content-Digest.
verifyRequest(o: { method: string; url: string; headers: Record<string, string>; body?: Uint8Array; now?: number; maxAge?: number; })
Verify a request signed by signRequest. Throws HttpSigError with .code. Nonce replay tracking is the caller's job.