Letterpier · Data processing agreement
Version 0.1 (draft) · Last updated 30 September 2026
https://app.letterpier.com/legal/dpa
Data processing agreement
Auftragsverarbeitungsvertrag (AVV)
Under Article 28 GDPR. Applies when access is granted.
Contents (18)
This agreement is concluded between the customer as controller and Michael Ketzer (“we”) as processor. Where the customer itself processes personal data on behalf of its own clients, it acts as processor and we are its subprocessor; the customer then ensures that its instructions and this agreement are consistent with its own agreement with its controller. This agreement forms part of the terms of service and is accepted together with them, by the customer’s confirmation in text form. This is electronic form within the meaning of Article 28(9) GDPR.
Its subject matter is our provision of Letterpier under the terms, for the customer. It runs for as long as the terms do, and beyond that for as long as we still process personal data for the customer.
The customer is responsible for the lawfulness of the processing and for the rights of the data subjects.
We send, receive, store and log transactional email for the customer; deliver webhooks to the customer’s endpoints; and check the DNS records of the customer’s domains. The details are in Annex 1.
The types of personal data and the categories of data subjects are listed in Annex 1.
We process personal data only on the customer’s documented instructions, including with regard to transfers to third countries. The customer’s API calls, dashboard settings and retention setting are documented instructions. Further instructions are given in text form.
We inform the customer if we believe an instruction infringes data protection law.
If the law of the Union or of a Member State requires us to process personal data in another way, we inform the customer of that requirement before processing, unless that law prohibits this on important grounds of public interest.
Everyone we authorise to process the customer’s personal data has committed themselves to confidentiality or is under an appropriate statutory obligation of confidentiality.
Today, only the operator has access. Staff of OVH and Neon can have access only under their own data processing agreements with us.
We take the technical and organisational measures described in Annex 2 (Article 32 GDPR).
We may adapt these measures to technical progress, provided the level of protection does not fall. Annex 2 also lists the gaps we know of, so that the customer can assess the risk for its own use.
The customer gives us general written authorisation to engage subprocessors. The current subprocessors are listed at /legal/subprocessors (Annex 3).
We tell the customer by email at least 30 days before we add or replace a subprocessor. Within that period, the customer may object on reasonable grounds relating to data protection. If we cannot resolve the objection, the customer may terminate the contract before the change takes effect.
We impose the same data protection obligations as in this agreement on every subprocessor (Article 28(4) GDPR). We remain liable to the customer for our subprocessors.
We help the customer answer requests from data subjects with appropriate technical and organisational measures. The customer can itself:
- delete individual messages in the dashboard, with their content, attachments, events and Postal copies;
- shorten the retention period of a project (from 1 to 90 days); a shorter period also applies to messages already stored;
- retrieve messages through the API and view them in the dashboard;
- remove addresses from the suppression list.
If a data subject contacts us directly, we pass the request on to the customer without undue delay and do not answer it ourselves unless the customer instructs us to.
We notify the customer of a personal data breach without undue delay after becoming aware of it, and where feasible within 48 hours (Article 33(2) GDPR). The notification contains the information required by Article 33(3) GDPR, as far as it is available; we provide the rest as soon as we have it.
Taking into account the nature of the processing and the information available to us, we help the customer with its obligations under Articles 32 to 36 GDPR, including data protection impact assessments and prior consultation of the supervisory authority.
When the processing ends, we delete the customer’s personal data or, at the customer’s choice, return it first as described in the switching and data export clause of the terms, unless Union or Member State law requires us to store it.
Deletion works as follows:
- deleting live data removes it from the application and the matching copies from Postal;
- backups keep the last 7 daily recovery points, so deleted data disappears from them about a week after deletion, or later if nightly backups fail;
- the recovery copy of held by the operator (Annex 2) contains the data of that day, including data deleted since, until it is deleted or replaced; [For legal review: the date by which the recovery copy is deleted or replaced]
- the restore history of the database provider Neon: the restore window configured for our Neon project;
- content-free fingerprints of received messages remain, so that deleted mail cannot be replayed into the system. They contain no message content.
We confirm the deletion in text form on request.
We make available to the customer the information needed to demonstrate compliance with Article 28 GDPR. We do so first through documentation: this agreement, its annexes, and the answers to the customer’s questions in text form.
If the documentation is not sufficient, the customer or an auditor bound to confidentiality may carry out an audit, including an inspection, with reasonable notice, during business hours and without disrupting operations. Each party bears its own costs, unless the audit reveals a material breach by us. [For legal review: notice period, frequency and cost rules]
For our providers’ data centres, we rely on the audit reports and documentation those providers make available.
We use customer personal data for our own purposes only where this is necessary to keep the service secure and prevent abuse, to keep suppression lists intact, or to comply with a legal obligation. For these purposes, we are an independent controller, and our privacy policy applies.
[For legal review: whether suppression lists, abuse handling, and the user accounts and audit records of the customer’s staff are processor or controller activities (EDPB Guidelines 07/2020; Article 28(10) GDPR)]
We host the service in the European Union. EU hosting does not mean EU-only access.
Our application database is operated by Neon (Databricks, Inc., the parent company of Neon, LLC), part of Databricks, Inc., USA, on Amazon Web Services in eu-central-1 (Frankfurt). Neon, Databricks and Amazon Web Services are US groups. Access from outside the EU, for example for support and operations, and requests from US authorities cannot be ruled out. For these transfers we rely on the EU-US Data Privacy Framework and on the Standard Contractual Clauses in Neon’s data processing agreement. [To verify: the transfer mechanism in Neon’s current data processing agreement; the outcome of the appeal against the Data Privacy Framework (C-703/25 P)]
As an additional safeguard, message bodies and attachments are encrypted with keys held on our OVH server, not by the database provider. Addresses, subjects and events are not encrypted in the database (Annex 2).
When the customer sends a message to a recipient whose mail server is outside the EU, the message necessarily goes there. This is the customer’s instruction, not a transfer we choose.
Liability under this agreement follows the liability clause of the terms. Article 82 GDPR is not affected.
If this agreement and the terms conflict on the protection of personal data, this agreement prevails.
This agreement ends when the terms end, but its obligations continue for as long as we process personal data for the customer. Changes follow the clause on changes to the terms.
If a provision of this agreement is invalid, the other provisions remain in effect.
- Data subjects
- Recipients of messages (to, cc and bcc); reply-to addresses; people who write to addresses on the customer’s domains that Letterpier receives for; people named in message content; the customer’s staff who use Letterpier.
- Personal data
- Envelope and header addresses; subjects; message bodies; attachments; raw MIME messages; IP addresses and host names of connecting mail servers; delivery events and bounce reasons; webhook payloads; suppression entries; domains and DNS data; user accounts of the customer’s staff (name and email address) and audit records of their actions (who, what, when). Signing in itself (sign-in codes and sessions) is our own processing under the privacy policy.
- Special categories
- Not intended. Processed only if the customer sends them (see the customer’s obligations in the terms).
- Nature and purpose
- Sending, receiving, storing and logging transactional email; webhook delivery; DNS verification; retention and deletion as set by the customer.
- Retention
- Message content, attachments and events: 1 to 90 days per project, as set by the customer (30 days by default). Postal: raw messages 7 days, metadata 30 days, unless deleted earlier. Backups: 7 daily recovery points; the recovery copy of until it is deleted or replaced (Annex 2).
- Locations
- OVH, Limburg, Germany (EU); Neon on Amazon Web Services, eu-central-1 (Frankfurt, Germany); the operator’s own computer, for the encrypted recovery copy of the backups (Annex 2).
The measures below describe the installation as verified on . The “Known gaps” column lists the gaps we know of; they are part of this annex.
| Area | Measures | Known gaps |
|---|---|---|
| Physical and host security |
|
|
| Access control |
| None identified. |
| Authentication |
|
|
| Encryption |
|
|
| Integrity |
| None identified. |
| Data minimisation |
|
|
| Availability and recovery |
|
|
| Deletion |
|
|
| Testing and review |
|
|
Technical and organisational measures (Article 32 GDPR)
Physical and host security
- Measures
- A server at OVH in an EU data centre (Limburg, Germany).
- Administrative SSH access restricted by host controls.
- Postal administration reachable only through an SSH tunnel.
- Postal’s MariaDB database only on a private Docker network.
- The application and Postal’s web interface bound to loopback, behind nginx.
- Public ports: 25 (SMTP), 80 (certificate challenges and redirect to HTTPS) and 443.
- Known gaps
- A single host, shared with unrelated media workloads.
- Where provider staff access the host from has not been independently audited.
Access control
- Measures
- Organisations and projects are isolated; every message, domain, key, webhook and suppression belongs to one project.
- Each project has its own Postal server and its own encrypted Postal credential.
- Role-based memberships (owner, admin, member) and per-project grants.
- API keys are long random values from a cryptographically secure generator, stored only as SHA-256 hashes, shown once, and split into sandbox or live and sending or full access. They can be revoked at any time.
- Today, only the operator has access to the server and the provider accounts.
- Known gaps
- None identified.
Authentication
- Measures
- Single-use sign-in codes of 6 letters, sent by email: valid for 10 minutes, at most 5 attempts, used up atomically. They are stored as a keyed hash (HMAC-SHA256); an encrypted copy is kept only until the sign-in email has been sent.
- Code requests and code checks are rate-limited per address, and repeat requests within a minute are ignored.
- Sessions in an encrypted cookie for 7 days, checked against the user’s disabled state and authentication version whenever the session is read.
- Origin checks against cross-site request forgery on every change made in the dashboard.
- Known gaps
- No multi-factor authentication and no account recovery yet.
- Sign-in depends on the security of the user’s own mailbox.
Encryption
- Measures
- AES-256-GCM with context binding for message bodies, original
.emlfiles, attachments, DKIM private keys, webhook signing secrets and Postal credentials. - The keys are held by the application on the OVH server, not by the database provider.
- TLS 1.2 and 1.3 with HSTS for the website, dashboard and API.
- SMTP submission requires STARTTLS before authentication.
- This is encryption at rest with keys the application manages. It is not end-to-end encryption.
- AES-256-GCM with context binding for message bodies, original
- Known gaps
- Addresses, subjects and events are stored unencrypted in PostgreSQL, so they can be searched.
- Postal keeps raw messages and DKIM private keys unencrypted in its private database (raw messages for 7 days, metadata for 30 days).
- TLS between mail servers is opportunistic: a receiving server may not offer it.
Integrity
- Measures
- Callbacks from Postal are verified with RSA-SHA256 over the original bytes.
- Outgoing webhooks are signed with HMAC-SHA256 in the Svix format.
- Bounded, validated input; a Content Security Policy that loads scripts, styles, images and fonts only from our own origin (inline scripts are still allowed).
- Deduplication of receipts and idempotency keys against duplicate processing.
- Known gaps
- None identified.
Data minimisation
- Measures
- The host for the API and the dashboard (app.letterpier.com) keeps no access logs, because request paths can contain short-lived download signatures.
- Download links for received messages and attachments expire after 15 minutes.
- HTML previews run in a sandbox without scripts, forms or remote content.
- Webhooks go only to public HTTPS addresses on port 443: the addresses are checked and pinned for the connection, redirects are not followed, and responses are not stored.
- Known gaps
- Plain-HTTP requests (certificate challenges and redirects) and the mail server’s host names are recorded in the web server’s default access log: IP address, time, request line, status, response size, referring page and browser user agent. [To verify: the web server’s log_format]
- Retention of these access logs and of error and application logs, which can contain IP addresses: up to 14 days (web server logs rotate daily; container logs are capped at 3 × 10 MB per service and overwritten as they fill). [To verify: nginx access and error logs (logrotate), application, Docker and Postal logs]
Availability and recovery
- Measures
- Nightly encrypted backups with Restic, keeping the last 7 daily recovery points.
- A restore check in isolated containers, last passed on .
- A health check of the database connection and the worker.
- An emergency stop for all live sending.
- Known gaps
- The backup repository is on the same server as the data, and so is its key. Replication to another server is pending.
- One encrypted copy of the backup repository, made on , is held on the operator’s computer, currently together with its password. It does not expire automatically. [To verify: password moved to a password manager; copy deleted or replaced]
- No independent alerting yet.
Deletion
- Measures
- A retention job, running every minute, deletes expired messages with their content, attachments and events, and purges the matching Postal copies.
- Deleting a message in the dashboard does the same at once.
- Expired sign-in codes, idempotency records and rate-limit entries are deleted automatically.
- Known gaps
- Suppression lists: until the project allows the address again, or until the project is deleted.
- Audit logs: 12 months, then deleted automatically.
- No API endpoint for deleting a single message yet; the dashboard has one.
Testing and review
- Measures
- Automated unit, integration and browser tests.
- A dependency audit (npm audit) on found no known vulnerabilities; it doesn’t run automatically yet.
- Known gaps
- Dependency audits don’t run automatically yet.
- No independent security audit or penetration test.
- No antivirus scanning of received attachments.
Further limits of the service (100 API requests per minute per project and environment; an initial 1,000 live messages per hour per project) protect the shared infrastructure; they are described in the terms.
The subprocessors are listed at /legal/subprocessors. The list that is current when the customer accepts this agreement is archived under its date and forms part of it.
Today these are:
- OVH (OVH GmbH (OVHcloud), Cologne, Germany): server hosting in the EU; data processing agreement: www.ovhcloud.com/de/terms-and-conditions/contracts;
- Neon (Databricks, Inc., the parent company of Neon, LLC): the application database; data processing agreement: www.databricks.com/legal/dpa;
- Amazon Web Services, as Neon’s infrastructure provider.
Questions about this agreement: mail@michael-ketzer.com.
Version history
| Date | Version | Changes |
|---|---|---|
| Version 0.1 (draft) (this version) | First draft for legal review. |