Digital Signatures
Digitally signed PDFs are legally sensitive artifacts. PDFCanon uses a detect → reject by default → explicit override policy to ensure you never accidentally destroy a signature without intending to.
Default behavior: reject
By default, PDFCanon rejects any PDF that contains digital signatures. Normalization modifies the byte structure of the document, which invalidates any existing digital signature. Silent removal would destroy evidence.
When a signed PDF is submitted, the response is:
{
"status": "REJECTED",
"failure": {
"code": "SIGNED_PDF",
"message": "PDF contains digital signatures which would be invalidated by normalization.",
"stage": null
}
}
Detection
PDFCanon detects signatures by inspecting:
/AcroFormsignature fields (/Sig,/Signature)/ByteRangeand/Contentsdictionary entries- Document-level signature dictionaries (
/DocMDP,/FieldMDP)
The decision is always taken against the bytes you submitted. Detection runs at stage 2, before
structural repair (stage 3) rewrites the file with qpdf --remove-acroform and shifts every byte
offset. A policy evaluated after that rewrite would be evaluated against a document that can no
longer prove it was signed — every mode would silently behave as if the input were unsigned.
Signature handling modes
You can override the default reject behavior by passing the signed_pdf_policy form field in your normalization request. The available modes are:
| Mode | Behavior |
|---|---|
reject (default) | Reject signed PDFs and return a REJECTED status |
strip | Remove signature fields and proceed with normalization. Returns a SIGNATURE_REMOVED warning. |
preserve | Return the submitted file byte-for-byte, without normalization. Useful for inspection-only workflows. |
Always use strip mode explicitly and intentionally. The removal of digital signatures is a destructive, irreversible operation. PDFCanon will never silently strip signatures.
Strip mode response
When strip mode is used, normalization proceeds and the response includes a warning that names what was removed:
{
"status": "SUCCESS",
"warnings": [
{
"code": "SIGNATURE_REMOVED",
"message": "Signature structures were removed (signature field 'Signature1', /AcroForm/SigFlags). The document's authenticity can no longer be verified via its original signatures."
}
]
}
If the document only carries a signature indicator that has no removable structure left, the
warning code is SIGNATURE_STRIP_NOOP and the document is left untouched — the report never claims
a removal that did not happen.
Preserve mode response
preserve short-circuits the pipeline. The output artifact is the submitted document byte-for-byte,
and it is recorded under the hash of those exact bytes, which is verified to equal the submitted hash
— never assumed from it. No mutating stage runs. If the submitted bytes cannot be parsed before
normalization, the raw bytes are scanned for signature markers; when none are found the run proceeds
with a SIGNATURE_INSPECTION_INCONCLUSIVE warning instead of failing.
If the bytes on disk are no longer the submitted bytes — only possible if a pipeline stage
rewrote the document before the policy was reached — the run fails with
PRESERVE_HASH_MISMATCH rather than publishing an artifact under a hash its contents do not have.
Why reject-by-default?
- Digital signatures are legally binding artifacts
- Normalization rewrites document byte structure, which always invalidates signatures
- Silent removal could destroy evidence in legal, compliance, or archival contexts
- Explicit intent prevents accidental data destruction
Most document security systems reject signed documents by default. PDFCanon follows this convention.
Tamper detection and signatures
Even when a signed PDF is rejected, tamper analysis runs before rejection and is reflected in the response. An ORPHANED_SIGNATURE_FIELD anomaly may be detected when a signature field exists but has no valid binding — this can indicate document tampering.
See POST /api/normalize for the full tamperAnalysis response schema.