Skip to content

Completion Certificate and Archival

When the last required party signs, FoxCLM produces one final artifact: the executed PDF - the contract body followed by an Electronic Signature Audit Certificate page - and archives it immutably. This is the document you hand to a counterparty, an auditor, or a court. It is distinct from the live audit trail: the audit trail is a queryable log inside the app, the certificate is a self-contained proof-of-completion stamped onto the document itself.

Electronic Signature Audit Certificate - the completion page appended to every fully-signed contract

When it is generated

The certificate is built once, automatically, when the contract reaches full signature (finalizeOnCompletion in contractSignatures.ts). No user action, no "generate certificate" button - a contract cannot be executed without one. If the certificate render fails for any reason, the body PDF is still archived (best-effort, logged); the certificate never blocks execution.

It collects only audit data already captured at sign time - nothing new is asked of anyone at completion. Phone numbers are masked to the last four digits; the raw values stay in the erasable audit tables, never on the certificate.

The header block

FieldWhat it proves
Document / Contract numberWhich contract this certifies
Envelope IDAn opaque identifier for the whole signing package (the analogue of a DocuSign Envelope ID), tying every mark to one signing event
Document SHA-256The fingerprint of the exact signed bytes. Any later alteration of the contract changes this hash - the single most important line for tamper detection
Certificate generatedUTC timestamp the certificate was built
Retained untilThe end of the immutable retention window (see Archival below)

Per-signer block

Each signer gets a card. Witnesses render as nested cards under the signer they attest to. The fields present depend on what was captured - a signer who passed ID verification shows more than one who signed with an email code alone:

  • Email and Activity - link opened, signed, per-event timestamps (all UTC)
  • Signature - the drawn image (sealed into the PDF, see below) or the typed name in a script font
  • Signature ID vs Session ID - a Signature ID is anchored to a verified identity and is stable across that workspace's contracts; a Session ID is a per-session reference for an unverified signer and is labelled (unverified - no email/SMS identity). The reference itself (e.g. 4F92-A1B3-8C7D) is derived from immutable audit fields, so it is reproducible without exposing internal IDs or the secret signing-link token
  • Verification - the OTP channel used (email / SMS one-time code), with the masked phone if SMS
  • ID verification - Shufti Pro reference and timestamp, when ID verification was on for the transition
  • IP address, Location (geo city/country), Device (parsed user-agent plus the raw string)
  • Consumer disclosure - when and to what consent text the signer agreed
  • Witness Proximity - distance between witness and signer, computed from captured geolocation. A witness more than 100 km from the signer is flagged red ("unusually far for an in-person witness") - co-presence is the whole point of witnessing

Envelope summary

A master table at the foot lists the lifecycle events for the whole package - Sent for signature, All parties signed, Sealed and archived - each with a UTC timestamp. This is the one-glance chronology of the signing.

The footer restates the integrity claim: the certificate is generated from the signing audit trail, and the document hash uniquely identifies the signed bytes.

Signature image sealing

Drawn signatures are burned into the executed PDF (both the contract body and this certificate) at seal time. Once sealed, FoxCLM nulls the standalone signature image from the database, keeping only its hash. The signature exists exactly where it has legal meaning - on the document - and nowhere else as a loose, exfiltratable asset.

Archival

The executed PDF is stored in contract_executed_archives, separate from the pre-signature body snapshot. Two storage modes (contractArchive.ts):

ModeWhere the bytes liveImmutable?
s3_worm (production)S3 Object Lock bucket; the row keeps the key, version, and retention_until; pdf_bytes is NULLYes - cannot be overwritten or deleted before retention_until, even by an account admin
db_fallback (dev / S3 unconfigured)pdf_bytes blob in the databaseNo - the server logs a warning that this is not immutable

Set CONTRACT_ARCHIVE_MODE=s3 with a WORM bucket for any deployment where an executed contract could be litigated over.

Retention and the right to erasure

WORM immutability and data-subject erasure rights (HK PDPO, GDPR) pull in opposite directions. FoxCLM resolves the tension by splitting the artifact from the erasable PII:

  • The immutable artifact - the executed PDF and its hash - lives in WORM under a bounded retention (the Retained until date on the certificate).
  • Erasable audit PII - IP address, user-agent, phone, precise geolocation - stays in the regular tables, not locked in WORM.

A purge routine (contractArchive.ts) can drop the executed-PDF bytes and the erasable PII while keeping the signature and audit hash, so an erasure request can be honoured without destroying the proof that a valid signature existed. See the Privacy Policy retention section for the customer-facing statement.

FoxCLM Documentation