Data processing agreement — template
Draft, not reviewed by counsel. Written by an agent from
docs/ARCHITECTURE.md§10 and the database schema. It is not legal advice and it has not been read by a lawyer. Do not sign this. Take it to one first. Notes addressed to that lawyer are marked [For counsel].
1. Parties
| Processor | HallinCreations, Sweden, operating HonestFetch. A name, not a registered entity: the legal form is pending, see docs/adr/0006-business-setup.md. |
| Controller | The customer named in the order form. |
2. Roles
HonestFetch is your processor for what you send it, and its own controller for what it keeps. ADR-0018 records the decision and the reasoning. The short form:
| Data | Role | Why |
|---|---|---|
| The URL and question you send, and the page fetched for them | Processor | They arrive as your instruction, for your purpose, and are never kept |
| Account and key records | Controller | HonestFetch keeps these for its own purpose |
| Usage records, including host and customer id | Controller | Kept for abuse tracing and metering, which are HonestFetch's own duties, not your instruction |
This agreement covers the first row. For the other two, HonestFetch is an independent
controller and PRIVACY.md §11 states the legal basis for each.
[For counsel] Confirm the classification. It is the one assumption everything below rests on: were HonestFetch the controller for the URL, this would be a controller-to-controller arrangement and §§4–11 would change shape. ADR-0018 sets out why the split is the position, and what would reopen it.
3. Subject matter, duration, nature and purpose
| Subject matter | Fetching one web page named by the Controller and returning an extract of its text |
| Duration | For as long as the Controller holds an active account |
| Nature and purpose | Retrieval, on the Controller's instruction, of text at a URL the Controller supplies |
| Type of personal data | Any personal data contained in a URL the Controller sends, and any contained in the page at that URL |
| Categories of data subjects | Any person a requested URL or page relates to. The Controller chooses the URLs and therefore the subjects |
The Controller decides what personal data reaches HonestFetch, by choosing which URLs to send. HonestFetch has no way to know in advance whose data is on a page.
4. Documented instructions (Art. 28(3)(a))
The Processor processes personal data only on the Controller's documented instructions. A request to the API is an instruction. The Terms of Service and this agreement are the standing instructions.
The Processor tells the Controller if an instruction appears to infringe the GDPR.
One exception, and it is not negotiable. The Processor refuses a request when a site's
own rules refuse it: robots.txt, Content Signals, a licence the Processor cannot meet, or
the Processor's own exclusion list. A refusal is an answer. The Controller cannot instruct
the Processor around it.
5. Confidentiality (Art. 28(3)(b))
Everyone authorised to process personal data is bound to confidentiality. Today that is one person, the operator.
6. Security (Art. 28(3)(c), Art. 32)
The measures in force, and each is a fact about the running system rather than an intention:
| Measure | What it is |
|---|---|
| No content at rest | Page content is never written anywhere. The schema has no column that could hold it, and a test asks the database and fails the build if one appears |
| No URL at rest | usage_events stores a host and at most a truncated path prefix. No query string |
| Keys are hashed | Only a SHA-256 of an API key is stored, never the key |
| Contacts are hashed with a secret | A site owner's address is stored as a keyed HMAC-SHA256, never as an address |
| Encryption in transit | TLS on every inbound and outbound connection |
| Encrypted backups | Database dumps are encrypted before they touch disk, with the key held off the server |
| Logs hold no credential and no URL | Authorization, Proxy-Authorization and Cookie headers are deleted from the access log; the application log serialises no headers at all and writes only allow-listed fields |
| Network | A cloud firewall allows three ports; a host firewall repeats it; SSH accepts keys only |
| Least privilege | The database and the cache listen on loopback only |
| Request isolation | A guard blocks requests to internal addresses, on every request and on every redirect |
7. Sub-processors (Art. 28(3)(d))
The Controller gives general authorisation for the sub-processors below. The Processor gives notice before adding or replacing one, and the Controller may object.
| Sub-processor | Purpose | Location |
|---|---|---|
| Hetzner Online GmbH | Hosting and encrypted backups | Helsinki, Finland |
| Cloudflare, Inc. | DNS, and mail forwarding for the operator's contact address | Global |
[For counsel] A payment provider joins this list before the first paid customer. Cloudflare is listed because it routes the operator's mail; it does not sit in front of the API, which runs DNS-only, so it never sees a customer request.
8. Data subject rights (Art. 28(3)(e))
The Processor assists the Controller in answering a data subject.
In practice this is a short conversation, because of what is not kept: no page content, no full URL, and a request's data is gone when the request ends. What can be produced is the usage record for a customer, which is hosts and counts, for 30 days in detail and 13 months in daily totals.
9. Assistance (Art. 28(3)(f))
The Processor assists the Controller with security, breach notification, impact assessments and prior consultation, taking into account the nature of the processing and what is available to it.
The Processor notifies the Controller without undue delay after becoming aware of a personal data breach.
10. Deletion and return (Art. 28(3)(g))
There is almost nothing to return. Content and URLs are never retained, so at the end of the contract what exists is the account record and the usage record.
On termination the Processor deletes them, subject to the retention periods below and any legal obligation to keep records.
| Data | Kept for |
|---|---|
| Raw usage events | 30 days |
| Daily aggregates | 13 months |
| Page content | Not kept at all |
11. Audit (Art. 28(3)(h))
The Processor makes available the information needed to show compliance, and allows audits by the Controller or an auditor it mandates, on reasonable notice and no more than once a year unless an incident warrants it.
Two things stand in place of a certification the Processor does not have: the source of these claims is the running code, and the tests that hold it to them are named in §6.
12. International transfers
None. Processing takes place on a server in Finland. The Processor does not transfer personal data outside the European Union.
[For counsel] Cloudflare is a US company and mail forwarding touches its network. Whether that is a transfer, and which mechanism covers it, needs your view. The API itself runs DNS-only, so no customer request passes through Cloudflare.
13. Liability, term, and law
The liability cap, the term and the governing law are those of the Terms of Service §§11–13, and this agreement ends when those terms end. §10 survives, because deletion is a duty that begins when the contract stops.
Annex: the plain-language version
If somebody asks what HonestFetch does with their data, this is the answer.
- You tell it a page to read.
- It reads that page once, and tells you what it says.
- It does not keep the page. It does not keep the address you gave it.
- It keeps a note that you read something at that website, so that if the website complains, there is an honest answer. That note lasts 30 days, then becomes a daily count that lasts 13 months.
- All of it sits on one machine in Finland.