Every layer of the signing process is secured: transport encryption, storage encryption, OTP identity verification, PKCS#7 digital sealing, hash-chained audit logs, and strict tenant data isolation. Not security theater — technical enforcement at every level.
TLS 1.2+ for all API calls and the signing page. No plain-HTTP fallback. HSTS enforced.
Documents stored in Cloudflare R2 with AES-256 encryption at rest. Storage keys are per-document — no shared encryption keys across tenants.
Every signer verifies identity with a time-limited one-time code sent to their email or phone before accessing the document. Prevents unauthorized access via forwarded links.
All queries scope by app_id and tenant_id. Cross-tenant data access is architecturally impossible — not just policy-enforced.
A CA-issued PKCS#7 signature is applied to the entire document after signing completes. Any byte-level modification after sealing invalidates the signature — detectable in any PDF reader.
Every signing event is appended to an append-only, hash-chained log. UPDATE and DELETE grants on the log table are revoked at the database level. Tampering with any row breaks the chain.
SHA-256 hashes of both the original and sealed PDFs are stored. Any copy of the document can be verified against the stored hashes even after the file is deleted.
Webhook POST bodies are signed with HMAC-SHA256. Receivers verify the X-GetSigned-Signature header before processing to ensure the event originated from GetSigned.
How GetSigned addresses each category of signing security risk.
After all signers complete, GetSigned flattens the signature fields into the PDF, appends an audit certificate page, and applies a CA-issued PKCS#7 digital signature to the entire file. The PKCS#7 signature covers every byte of the document — if any byte changes (content, metadata, a pixel, a character), the digital signature becomes invalid. This is verifiable by anyone with the document using Adobe Reader or any PDF validator. No special software or API access is needed to verify the document.
Each signer receives a unique, independently generated tokenized link (a short-TTL signed JWT scoped to exactly one envelope and one signer). The links are not guessable or derivable from each other. After the token is used to complete signing, it is invalidated. Additionally, OTP verification is required before the document is displayed — so even if a link were forwarded, the recipient would need access to the registered email or phone to complete the OTP step.
It is tamper-evident, not tamper-proof. "Tamper-proof" would require physical access controls beyond what a software system can provide. "Tamper-evident" means: (1) UPDATE and DELETE grants on the audit_log table are revoked at the database level, so the application role cannot modify rows; (2) each row hashes the previous row — a hash chain — so any modification of a historical row produces a detectable break in the chain; (3) the hashes are also embedded in the sealed PDF, making comparison against the stored chain possible even from an offline document.
Documents are stored on Cloudflare R2 with AES-256 encryption at rest. Storage keys are generated per-document — there are no shared encryption keys across envelopes or tenants. Documents are only accessible through the GetSigned API with a valid bearer token scoped to the correct application and tenant. No public or anonymous access to document storage is possible.
Every database query that touches envelopes, documents, signers, fields, or events is scoped by both app_id and tenant_id. This is enforced at the repository/data-access layer, not just at the API layer — there is no query path that can return results across tenant boundaries. This is considered the top-priority security invariant in the system architecture.
Every envelope is secured at every layer automatically. No security configuration required.
Get free API keys →