Certifying & Locking
Certifying (DocMDP) vs approval signatures, certify-then-approve workflows, and FieldMDP field locking
Mudrit produces two kinds of signature. An approval signature (the default) says "I sign this"; a certifying signature additionally declares, through the PDF DocMDP transform, what changes stay permitted afterwards — and locks anything else.
Approval vs certifying
By default sign_pdf makes an approval signature. Call .certify(…) to make the signature a
certifying (DocMDP) one instead; .approval() restores the default explicitly.
use mudrit_pdfsign::prelude::*;
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.approval() // the default — an ordinary signature
.build();use mudrit_pdfsign::prelude::*;
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.certify(Certify::FormsAndSignatures) // DocMDP /P level 2; must be the first signature
.build();The three certification levels map to the DocMDP /P value — what a later editor may still change
without invalidating the certification:
Certify variant | DocMDP /P | Allows after certifying |
|---|---|---|
Locked | 1 | Nothing — no changes at all |
FormsAndSignatures | 2 | Form filling and additional signatures |
FormsSignaturesAndAnnotations | 3 | Form filling, signatures, and comments / annotations |
A certifying signature must be first
Only the first signature in a document can certify — DocMDP describes the document from that
signature onward. Certify::Locked forbids any later change; the other two allow specific later
signatures. Certification is ignored for Method::MultiChained.
Certify, then approve
A common workflow: one party certifies the document (locking structure but allowing further
signatures), and a second party later appends an approval signature. Because the certification
was made at FormsAndSignatures (or …AndAnnotations), the appended signature is permitted and
both stay valid.
// party A certifies at /P level 2 (forms + signatures allowed)
let certified = sign_pdf(&pdf, &signer_a, &cfg_certify)?;
// party B appends an approval signature — sign_pdf detects the existing signature and appends
let approved = sign_pdf(&certified, &signer_b, &cfg_approve)?; // both validsign_pdf detects that the input is already signed and appends an incremental revision rather
than rebuilding the file (which would break the existing signatures). See the certify_then_approve
example.
Field locking (FieldMDP)
Where DocMDP governs the whole document, FieldMDP locks specific form fields at signing time —
so filled fields can't be altered after this signature. The lower-level add_locked_signature
applies a FieldMDP field-lock together with LTV and a timestamp for explicit control:
use mudrit_pdfsign::add_locked_signature;
let signed = add_locked_signature(&input, page, rect, field, &signer, tsa)?;Certification can't follow an existing signature
add_locked_signature uses a FieldMDP field-lock rather than DocMDP, because a certifying signature
must be first and can't be added after an existing signature. It also matches the previous
cross-reference type (classic table vs cross-reference stream) so the appended revision stays valid
in Adobe.