Skip to main content

Overview

The primitives.verify() function verifies HTTP Signature (RFC 9421) on incoming requests. It can either use a provided public key or automatically discover it via the Signature-Agent header.
For tool providers, consider using tool.verify() instead, which adds FQDN trust validation. Use primitives.verify() when you need low-level verification control or custom trust logic.

Signature

Parameters

HttpMethod
required
The HTTP method of the request being verified.Valid values: 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD', or any custom string.
string
required
The full URI of the request being verified (e.g., https://api.example.com/users).
HeaderBag
default:"{}"
The HTTP headers from the incoming request. Should include Signature, Signature-Input, and optionally Signature-Agent.
PublicJwk
default:"undefined"
The public key to use for verification. If not provided, the key will be discovered via the Signature-Agent header.

Return Value

Returns a Promise that resolves to a VerifyResult object:
string
The unique identifier of the agent that signed the request (extracted from Signature-Agent).
string
The key ID (thumbprint) of the public key used to verify the signature.
PublicJwk
The public JWK that was used to verify the signature.
string
The well-known URL where the public key was discovered (only present if auto-discovered).

Example - Auto-Discovery

Example - With Provided Public Key

Example Output

Public Key Discovery

When publicJwk is not provided, the verification process:
  1. Parses Signature-Agent: Extracts the agent’s discovery URL from the Signature-Agent header
  2. Builds Well-Known URL: Constructs https://{uid}.{host}/.well-known/http-message-signatures-directory
  3. Fetches Keys: Makes a GET request to the well-known endpoint
  4. Selects Key: Finds the key matching the keyid from Signature-Input
  5. Verifies: Uses the discovered key to verify the signature

Signature Expiration

If the Signature-Input includes an expires parameter, the signature is checked for expiration:

Error Handling

Common Errors

  • Missing Signature-Input: The Signature-Input header is missing or malformed
  • Expired Signature: The signature’s expires timestamp is in the past
  • Missing Public JWK: No public key provided and auto-discovery failed
  • Invalid Signature: The cryptographic signature verification failed (tampered request or wrong key)

Verification Flow

  1. Parse Headers: Extract and parse Signature, Signature-Input, and Signature-Agent
  2. Check Expiration: Validate the signature hasn’t expired (if expires is present)
  3. Resolve Public Key:
    • Use provided publicJwk if given
    • Otherwise, discover via Signature-Agent well-known endpoint
  4. Build Signature Base: Reconstruct the signature base string from the request
  5. Verify: Use Ed25519 to verify the signature against the public key
  6. Return Result: Return agent info and verification details

Localhost Support

When the Signature-Agent hostname is localhost or 127.0.0.1, the verification automatically handles port mapping: