Data Processing Agreement (DPA)
Draft, awaiting counsel review. Standard SCCs-aligned DPA
template adapted to Muntin Ledger's actual sub-processor list and
data flows. Customers may execute this electronically as part of
account creation; enterprise customers may negotiate amendments.
Last updated: 2026-05-10 (draft) · Version: 0.2 (post-pivot)
Disponible en español:
docs/es/dpa.md. En caso dedivergencia entre ambas versiones, prevalece la inglesa hasta que
un revisor bilingüe certifique la paridad. Routing details in
This Data Processing Agreement ("DPA") supplements the Terms of Service between Muntin Digital LLC ("Muntin," the Processor) and Customer (the Controller). It governs Muntin's processing of Personal Data on Customer's behalf and applies in addition to the Privacy Policy.
1. Definitions
"Personal Data," "Processor," "Controller," "Sub-processor," "Data Subject," and "Processing" carry the meanings assigned to them by GDPR Article 4. "Personal Data Breach" follows GDPR Article 4(12).
"Customer Data" means data that Customer or its authorised users upload, paste, snap, or forward to the service, including invoice files and any extracted records derived from them.
2. Subject matter and duration
Muntin processes Customer Data solely to perform the services in the Terms of Service. Processing continues for the duration of Customer's subscription. On termination, Muntin deletes Customer Data within 30 days, with the exceptions listed in Section 8.
3. Nature and purpose of processing
Muntin reads vendor invoices and stores extracted records in the Customer's Muntin Ledger. Specific operations:
- Receive document uploads and store ciphertext in residency-pinned
object storage.
- Run the docling open-source engine to recover document layout,
table structure, and reading order.
- Run a deterministic extraction engine that resolves vendors
against a seeded catalog, applies per-vendor templates the operator has confirmed, and falls back to a synonym dictionary + position heuristics. No third party processes invoice content. No LLM is in the customer-data path. The CI gate scripts/no-llm-ci.sh fails any commit that imports an LLM SDK or reaches an LLM HTTP endpoint.
- Run a PII scrubber (
tools/pii-scrubber/) that strips PII-class
strings (SSNs, US phone numbers, emails, ACH-shaped account numbers) from Sentry error events and from audit-log target references before persistence.
- Validate the result against a canonical schema and persist the
encrypted record in Customer's Muntin Ledger.
- Compute insights (vendor spend trends, price-hike anomalies,
duplicate-bill detection) from the persisted records using deterministic SQL queries. Insight outputs ("verdicts") are stored alongside the records that generated them.
- **Export to Customer's accounting system or CSV file on Customer's
instruction.** CSV download is built in to every paid tier and available via GET /v1/exports/csv. QuickBooks and Xero connectors ship in private beta; they are optional and one-way.
- Maintain an append-only, hash-chained audit log accessible to
Customer.
4. Categories of Data Subjects
- Customer's employees and authorised users (signup data).
- Customer's vendors (invoice metadata: vendor name, address, tax ID).
- Anyone whose Personal Data appears in invoice content (rare).
5. Categories of Personal Data
- Account credentials (email).
- Vendor identifiers (name, address, tax ID).
- Banking identifiers when Customer's invoices include them (account
numbers, routing numbers; scrubbed from logs by tools/pii-scrubber/ per Section 3 above).
- Payment terms and remit-to addresses.
6. Sub-processors
The full list is at docs/sub-processors.md. Muntin gives Customer 30 days' advance email notice of any additional or replacement sub-processor. Customer has the right to object; Muntin will work in good faith to find an alternative or, if that is impossible, allow Customer to terminate without penalty.
7. Cross-border transfers
US-only at GA: Customer Data is processed and stored in AWS us-east-2 and Cloudflare US edge locations. EU residency is a phase-4 deliverable; until then, EU customers should not store GDPR-restricted data unless they accept transfer to the United States under the appropriate Standard Contractual Clauses ("SCCs").
When EU residency lands, Customer Data for EU-region workspaces stays in eu-central-1 and Cloudflare EU edge locations. The SCCs (Module 2: Controller-to-Processor) attach to this DPA by reference.
8. Customer rights and assistance
Muntin assists Customer in fulfilling Data Subject requests under GDPR Articles 15–22:
- Access (Art. 15): every workspace can download a CSV at any
time via Settings → Export & integrations → Download CSV (live; no rate-limit beyond the per-org daily cap). For full structured export including the audit log, the signed-JSON path lands during MVP private beta (week 7 per PLAN.md); until then, requests are fulfilled manually by privacy@muntin.digital within five business days.
- Rectification (Art. 16): every extracted field is editable in
the review pane.
- Erasure (Art. 17): live records are removed within 60 seconds
of the delete action; audit log entries referencing them are content-tombstoned (target reference replaced with a hash) so chain integrity survives. _Tombstoning lands as part of the ingest-and-deletion path in MVP weeks 7–10; until then deletes remove the live record but leave the audit row's target_ref unchanged. Customers requiring full Art. 17 compliance should email privacy@muntin.digital for the manual purge._
- Restriction (Art. 18): customers can pause processing of any
workspace via Settings → Privacy.
- Portability (Art. 20): the CSV download is the portability
artifact for invoice records; the signed JSON export covers the full structured payload + audit log.
- Object (Art. 21): close the account; we delete within 30 days.
Exception: Muntin retains audit log metadata and ciphertext for the minimum period required to honour Customer's hash-chain verification rights and any applicable financial-records regulation, even after live data is purged.
9. Security measures
Muntin implements appropriate technical and organisational measures appropriate to the risk under GDPR Art. 32. The architecture splits Customer Data into two classes with two distinct controls:
(a) Scanned documents (PDFs, images). Transmitted over TLS 1.3 and stored as objects in cloud object storage (Cloudflare R2), which encrypts all objects at rest with provider-managed keys. They are processed only by the extraction pipeline and retained per the retention policy. They are NOT end-to-end encrypted: Muntin's infrastructure can technically access scanned documents server-side. Client-side end-to-end encryption (per-document AES-256-GCM DEKs wrapped by a device-derived User Master Key the servers never possess) is a roadmap item and is not yet implemented; this DPA will be amended when it ships.
(b) Structured ledger rows (vendor names, totals, dates, line items, GL classifications, integration metadata). Stored as cleartext in a relational database scoped by per-org Row Level Security. This class is what enables the cross-device sync and the insights engine the product delivers.
The cryptographic primitives are open and auditable:
- TLS 1.3 in transit (HSTS preload enrolled). Shipped.
- Cloud object storage (Cloudflare R2) encryption at rest with
provider-managed keys for scanned documents. Shipped.
- _Opt-in document lock (implemented in code and tests; opt-in;
not yet independently verified in production):_ after the one-time server-side extraction read, each retained scanned original is encrypted with a per-document AES-256-GCM Data Encryption Key. The DEK is wrapped to the user's X25519 identity PUBLIC key via an ephemeral-X25519 + HKDF-SHA256 envelope, with document_id bound as Additional Authenticated Data. The servers hold only the public key and cannot reopen a locked document; the plaintext is discarded once the locked copy is written. The structured ledger remains server-readable by design (it powers sync and search). A customer who does not enable the lock keeps the retention-policy behaviour for the unencrypted original.
- The X25519 identity secret key is sealed with AES-256-GCM under
a User Master Key derived on the user's device by Argon2id (memory 64 MiB, time 4 iterations, parallelism 2; 16-byte per-user salt) from a 12-word BIP-0039 recovery phrase (128 bits of entropy). The server never sees the phrase or the User Master Key. Losing the phrase makes locked documents unrecoverable; the structured ledger is unaffected.
- Audit chain: append-only hash chain over every privileged access.
Customer-verifiable chain head published every six hours.
- Docling extraction worker: ephemeral per-job Fly Machines with
read-only rootfs, dropped Linux capabilities, non-root user, core dumps disabled at both RLIMIT_CORE and container ulimit -c levels. Machine terminates after each document.
- Per-document JWT signed HMAC-SHA256 by Muntin's API authorizes
one specific docling Machine to process one specific document within a five-minute window; replay against a different Machine or document is rejected.
Other measures:
- Bring-Your-Own-Key (BYOK): not applicable to the E2EE class
(Customer's devices are the only keyholder). Enterprise-tier Customers seeking additional control over the cleartext structured-ledger class may contract for BYOK as a Phase 4 deliverable.
- Production access controls: named-customer ticket, two-person
approval, time-boxed credentials, surfaced into Customer's audit log within 24 hours.
- Vulnerability management: dependency scanning, signed container
images (cosign), SBOMs per release.
- Cross-platform parity: today the production surface is Web Crypto.
Pinned byte-level parity test vectors run on every commit; the native iOS (CryptoKit) and Tauri desktop (Rust) implementations light up against those same vectors as they ship in Phase 1B.
- Incident response: runbooks at
runbooks/, tested quarterly. - See docs/threat-model.md for the full threat
model.
10. Breach and integrity-event notification
This Section covers two distinct notification obligations. Both apply independently; one does not displace the other.
10.1 Personal Data Breach (GDPR Art. 33): 72 hours
Muntin notifies Customer of a Personal Data Breach affecting their data without undue delay and in any case within 72 hours of becoming aware. The notification will include the nature of the breach, categories and approximate volume of records affected, and the measures taken or proposed to mitigate.
10.2 Audit-chain integrity event: 24 hours
Separate from Section 10.1, Muntin commits to a 24-hour notification window for any audit-chain integrity event. A chain-integrity event is any of the following observed in production:
- (a) A
verifyChainfailure (perapps/api/src/lib/audit.ts)
returning valid: false with a non-null broken_at_seq.
- (b) A tombstone applied to an audit row by Muntin staff under
legal process (e.g. court order, valid subpoena), where the tombstone replaces a target reference with a hash and the row's presence is preserved for chain continuity.
- (c) An attestation 4xx response that survives the 5-minute retry
budget defined in the docling startup-attestation flow.
For any such event, Muntin notifies the Customer's primary contact within 24 hours of internal confirmation. The notification will include:
- The
event_hash(or, for category (c), the failing attestation
identifier).
- The
seqrange of audit rows affected. - The remediation status (contained, in progress, resolved) and the
next expected update time.
This 24-hour clause applies even when no Personal Data is implicated — the audit chain is itself a customer commitment, and a break in it is a notifiable event on its own terms. When an event meets the definitions of both 10.1 and 10.2, both notifications are owed; the 24-hour clock is the binding earlier deadline for the chain-integrity facts, and the 72-hour Art. 33 notification follows with the personal-data specifics.
The operational detail of these notifications — incident channel naming, status-page posting, the 15-minute paging SLA, on-call rotation — is documented in runbooks/incident-response.md and, for cross-tenant events specifically, in runbooks/tenant-isolation-incident.md.
11. Audit rights
Customer may, no more than once per 12-month period, request evidence of Muntin's compliance with this DPA. Muntin will provide:
- Current SOC 2 Type I or Type II report (when issued; see
PLAN.md for the timeline).
- Penetration-test summaries.
- The most recent annual transparency report.
On-site audits are available to enterprise-tier customers under separate written arrangement.
12. Human-in-the-loop commitment
Every extracted verdict requires an operator's explicit confirmation before it commits to the Customer's ledger. Muntin does not operate any automated decision-making pathway that produces legal effects or similarly significant effects on a data subject under GDPR Article 22.
How the path works in practice:
- The deterministic engine in
services/extract/engine.pyreads an
invoice, resolves the vendor against the seeded catalog, applies the per-vendor template the operator has confirmed for that vendor, and produces a draft verdict.
- The Customer's operator reviews the draft in the review pane and
either approves it, edits the fields, or rejects it. Only an approved verdict writes to the ledger and to the audit chain.
- No verdict is auto-posted to QuickBooks Online, Xero, or any other
downstream system at private beta. Posting is initiated by the operator on a per-record (or batch-confirmed) basis.
If Muntin ever introduces an automated path that posts verdicts without operator confirmation — for example a future "post nightly" feature — Muntin commits to at least 90 days' advance notice to Customer plus a corresponding update to the Privacy Policy before that path is enabled for the Customer's workspace. Customers will retain the right to keep the operator- confirmed path; auto-posting will not be the only option.
EU AI Act stance. As a deterministic system with mandatory human review at the verdict step, Muntin Ledger is not a "high-risk AI system" under Annex III of the EU AI Act. The IBM docling open-source layout engine is used only to recover document layout and reading order; it does not draw inferences about the data subject. Muntin will reassess this stance if and when the EU AI Act's general-purpose-AI provisions enter into force, or if Muntin materially changes its processing in a way that brings it into the Act's high-risk scope. Any reassessment that affects Customer's risk posture will be disclosed under the same 90-days-notice process described above.
This Section restates, for the Controller record, the human-in-the-loop commitment that also appears in the Privacy Policy.
13. Liability
Liability under this DPA is governed by the limitation in the Terms of Service.
14. Term
This DPA enters into force on the effective date of the underlying Terms of Service and remains in force for as long as Muntin processes Customer Data.
15. Signatures
This DPA is executed by acceptance of the Terms of Service. For enterprise customers requiring a wet signature: legal@muntin.digital.