PactLink Signature Verification Specification

Every PactLink pact signature is a detached-payload JWS (RFC 7515) over the canonical SHA-256 hash of the published brief plus the deal’s document content hashes, with an independent RFC 3161 timestamp. This document describes how a third-party can verify a signature offline using only the artifact and the public verification key catalog for the deal.

Artifact

An artifact JSON contains:

{
  "jws": "<compact JWS, RFC 7515>",
  "tsaToken": "<base64 RFC 3161 TimeStampToken>",
  "tsaAuthority": "<URL of the TSA that issued the token>",
  "signedAt": "<RFC 3339 timestamp PactLink recorded>"
}

Canonical hash

The JWS payload is the canonical hash, computed as:

SHA-256(
  "brief:" + briefVersion + "\n" +
  briefContentHash +
  for each documentContentHash in sort_ascending(documentContentHashes):
    "doc:" + documentContentHash
)

Document hashes are sorted in ascending byte order so two parties with the same document set produce the same canonical hash regardless of upload order.

Verification steps

  1. Fetch GET /api/public/verification-keys/{dealRoomId} for the public JWK of each signatory.
  2. For each candidate key, run compactVerify(jws, jwk) with algorithm ES256. Success identifies the signer.
  3. Inspect the protected header: sub, dealRoomId, and briefVersion must match what you expect.
  4. Validate the RFC 3161 TSA token against the TSA’s public certificate chain.

A reference offline verifier is shipped at scripts/verify_signature.ts in the PactLink repository.