Why we stopped paying for DocuSign: PAdES digital signatures in 40 lines of Python
Electronic signature vendors have built multi-billion dollar businesses charging per "envelope" for something that has been an open international standard in the PDF specification for over 15 years.
When you pay for DocuSign or Adobe Sign, you are paying for three things:
- A visual stamp on a PDF page.
- A cryptographic digest binding the document to a signer identity.
- An email relay that routes the document between parties.
In the AI agent era, having human employees manually drag boxes on a screen inside a proprietary SaaS portal makes zero architectural sense.
Here is how you implement an open, compliance-ready PAdES digital signature pipeline in an agent execution sandbox.
The Standards: SES, AES, and PAdES#
Under international legal frameworks (such as EU eIDAS and US ESIGN/UETA), digital signatures exist in three tiers:
- Simple Electronic Signatures (SES): A visual signature image or typed stamp on a page combined with audit metadata (timestamp, email, IP address). This is what 90% of web contracts and vendor onboarding questionnaires require.
- Advanced Electronic Signatures (AES / PAdES): The PDF itself carries a cryptographic PKCS#7 / CMS signature dictionary (
/Sig,/ByteRange,/Contents), signed with an X.509 certificate. If a single byte of the PDF is altered after signing, Adobe Acrobat and Apple Preview flag the document as tampered. - Qualified Electronic Signatures (QES): Backed by a verified Trust Service Provider hardware token.
The Visual Stamping Engine#
To place a digital signature badge onto an enterprise PDF without manual coordinate guessing, we use PyMuPDF to locate the exact placeholder anchors:
import pymupdf
def stamp_signature(pdf_path, out_path, signer_name, signer_email, sec_id):
doc = pymupdf.open(pdf_path)
# Locate target page and signature anchor
page = doc[-1] # or specific page
anchor_words = [w for w in page.get_text("words") if "Signature:" in w[4]]
if anchor_words:
w = anchor_words[0]
# Bounding box directly to the right of 'Signature:' label
sig_rect = pymupdf.Rect(w[2] + 10, w[1] - 15, w[2] + 160, w[3] + 10)
# Stamp vectorized digital badge
page.insert_image(sig_rect, filename="signature_badge.png")
# Align printed name on the exact label baseline
name_words = [w for w in page.get_text("words") if "Print" in w[4]]
if name_words:
nw = name_words[0]
page.insert_text((nw[2] + 40, nw[3]), signer_name, fontsize=10.5, fontname="helv")
doc.save(out_path)Adding Cryptographic Integrity (PAdES)#
For Advanced Electronic Signatures, we sign the PDF byte-range using pyHanko with an organizational certificate:
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import fields, signers
def sign_pades(input_pdf, output_pdf, key_file, cert_file):
signer = signers.load_crypto(key_file, cert_file, key_passphrase=None)
with open(input_pdf, 'rb') as inf:
w = IncrementalPdfFileWriter(inf)
fields.append_signature_field(w, sig_field_spec=fields.SigFieldSpec(sig_field_name='Signature1'))
with open(output_pdf, 'wb') as outf:
signers.sign_pdf(
w, signers.PdfSignatureMetadata(field_name='Signature1'),
signer=signer, output=outf
)The Economics of Agentic Signing#
When an agent handles signing:
- Zero per-envelope SaaS fees: Documents are signed using open cryptographic primitives in local execution sandboxes.
- Zero data exfiltration: Sensitive passports, tax IDs, and confidential vendor contracts never touch third-party cloud aggregators.
- End-to-end automation: Inbound emails are parsed, populated, cryptographically signed, and returned in under a minute without human context-switching.