Metadata
Signature properties, signing time and time zone, and document /Info + XMP — all grouped into one Metadata struct
Everything a viewer surfaces about a signature — the Signature Properties panel and the document's
Document Properties — is grouped into one Metadata struct on
SignConfig. The most common fields have builder shortcuts; the rest are set through
.metadata(Metadata { .. }).
Signature properties
/Reason, /Location, and /ContactInfo are the free-text fields Adobe shows in the signature's
properties. /Name (the signer) defaults to the certificate's CN — override it only when you
want a display name different from the certificate subject.
use mudrit_pdfsign::prelude::*;
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.reason("Approved for disbursement")
.location("New Delhi")
.contact("accounts@example.com")
.name("Finance Department") // optional — omit to use the certificate CN
.build();Prop
Type
Signing time and time zone
The signing time /M and the visible stamp's Date: label are generated from the real wall clock.
The default zone is IST (+05:30); change it with .tz_offset(secs) (pass 0 for UTC) or set an
exact /M string via Metadata::signing_time.
// no tz_offset → the auto /M and visible date use IST (+05:30)
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.build();let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.tz_offset(0) // UTC instead of the default IST
.cms_signing_time(true) // also emit the PKCS#9 signingTime CMS attribute
.build();let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.metadata(Metadata {
signing_time: Some("D:20260717093000+05'30'".into()), // exact /M; tz_offset ignored
..Metadata::default()
})
.build();Prop
Type
When to enable cms_signing_time
It is off by default on purpose: PAdES prefers the PDF /M entry plus a signature
timestamp over a self-asserted CMS attribute. Enable it only for legacy
.p7s / CMS consumers that expect a signingTime attribute inside the SignerInfo. .tz_offset is
ignored when signing_time is set explicitly.
Document properties (/Info + XMP)
Document-level metadata is set through DocInfo on
Metadata::document. Title / Author / Subject / Keywords are simple Options (None = leave
untouched); Creator ("Application") and Producer ("PDF Producer") use
MetaField so you choose whether to keep, replace, or append.
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.metadata(Metadata {
document: DocInfo {
title: Some("Q3 Report".into()),
author: Some("Acme Corp".into()),
subject: Some("Quarterly results".into()),
keywords: Some("finance, q3, signed".into()),
creator: MetaField::Set("Acme Sign 2.0".into()), // replace the Application
..DocInfo::default() // producer keeps its Append tag
},
..Metadata::default()
})
.build();Prop
Type
Mudrit writes both /Info and XMP
Mudrit writes both the /Info dictionary and the catalog's XMP /Metadata packet — which is
what Acrobat's Document Properties actually reads. Tools that update only /Info leave stale XMP
behind, so Acrobat shows the old values; Mudrit keeps the two in sync, so your values show, not the
input's.
The Mudrit / SDK tag
Because Mudrit signs (does not author) the PDF, creator and producer default to Append:
the input's originals are kept and the SDK tag Mudrit <version> (Trexolab) — derived from
Cargo.toml — is appended ("{orig}; {tag}"), never replaced. Customize the appended tag with
.app_tag("…"):
let cfg = SignConfig::builder()
.place("F", [350, 60, 560, 160])?
.app_tag("Acme Sign 2.0") // appended to /Producer and /Creator, keeping the originals
.build();The tag lands on both the /Info dict and the XMP packet. For per-field control (replace one, keep
the other), set MetaField::Set(..) / MetaField::Keep through .metadata(…) instead.