Data Processing Agreement
1. Parties and scope
1.1 This Data Processing Agreement (DPA) is made between:
- the Customer, as defined in our Terms of Service (the Terms), as the controller, and
- Christoph Emunds, trading as Vellumine, c/o COCENTER, Koppoldstr. 1, 86551 Aichach, Germany (Vellumine), as the processor.
1.2 Terms defined in clause 2 of the Terms, such as Service, Collection, Customer Content, and Reader, have the same meaning in this DPA. "GDPR" means Regulation (EU) 2016/679.
1.3 This DPA applies to all personal data that Vellumine processes on behalf of the Customer when providing the Service (Customer Personal Data). It does not apply to the Customer's own account data, such as the Customer's name, email address, and billing information. For that data, Vellumine is the controller, and our Privacy Policy applies. This DPA also does not apply to blogs that a Vellumine partner, for example a hosting provider, has set up for blog owners who have no Vellumine account of their own. For those blogs, the partner's agreement with Vellumine governs the processing, and instructions about export or deletion of their data reach Vellumine through the partner.
1.4 This DPA forms part of the Terms (clause 8.1 of the Terms). It applies automatically to every contract under the Terms, without a separate signature. It is concluded in electronic form, which Art. 28(9) GDPR permits. If the Customer needs a signed copy, Vellumine provides this DPA as a signed PDF on request to chris@vellumine.com. This DPA also applies, from its effective date, to Customers whose contract with Vellumine is still governed by previous terms.
1.5 If this DPA and the Terms conflict on the protection of personal data, this DPA takes precedence.
1.6 Changes to this DPA follow clause 11 of the Terms, with two exceptions. Vellumine may update Annex 1 under section 6.2 without the Customer's acceptance, as long as the update does not reduce the level of protection. Changes to the list of subprocessors in Annex 2 follow section 7 of this DPA.
2. Subject matter, duration, nature and purpose
2.1 Subject matter. Vellumine provides search and search analytics for the Customer's Ghost blog, as described in clause 4 of the Terms.
2.2 Duration. This DPA applies for the term of the contract under the Terms. After the contract ends, it continues to apply for as long as Vellumine still processes Customer Personal Data, until that data is deleted under section 10.
2.3 Nature of the processing. Vellumine processes Customer Personal Data as follows:
- Indexing: syncing published posts, pages, tags, and author profiles from the Customer's Ghost blog, storing them in a search index, and, for Collections with semantic search, computing text embeddings of post content.
- Search: receiving search requests from Readers and returning results from the search index.
- Analytics aggregation: receiving search and click events from Readers' browsers, deriving the data listed in section 3.1, and aggregating it into daily statistics.
- Reporting: showing the statistics to the Customer in the app and through the partner API (section 4.5), and sending them in weekly digest emails if the Customer turns these on.
- Search suggestions: if the Customer turns on dynamic suggestions, publishing the most popular redacted search queries in the Collection's public search configuration.
- Deletion: deleting data when its retention period ends, when the Customer deletes a Collection, or when the contract ends.
2.4 Purpose. The only purpose of the processing is to provide the Service to the Customer under the Terms.
3. Categories of data and data subjects
3.1 Readers. For Readers who use the search on the Customer's blog, Vellumine processes:
- search queries. They are converted to lowercase, and email addresses and phone numbers are redacted before storage. Phone numbers are recognised in international format (starting with + or 00), in national formats with a leading 0, and 10-digit North American numbers written without separators or with dashes or dots (555-123-4567). Redaction is best effort: other numbers, such as national numbers without a leading 0 or +, or North American numbers written with spaces or brackets, and other personal data that a Reader types into a query are not removed and are stored as typed.
- clicked results and their position in the result list,
- the number of results of a search,
- country, taken from a request header added by Cloudflare,
- device type and browser, derived from the user agent,
- IP address and user agent. For the search analytics, they are processed only transiently, to derive the country, device type, browser, and the daily session identifier. They are not stored in the search analytics.
- request logs. To keep the Service secure and stable (Art. 32 GDPR), Cloudflare may log the IP address, user agent, time, and requested URL of requests from Readers' browsers that pass through its network, and keeps these logs for 30 days. The reverse proxy and the search servers do not write access logs; if Vellumine turns them on temporarily, they are kept for at most 30 days (Annex 1, section 6). Readers' own search requests carry the search query only in the request body, never in the URL, so these logs do not contain the queries that Readers type. Request URLs of the Customer's analytics views in the app can contain redacted search queries (Annex 2, Cloudflare).
- a daily session identifier, computed from the IP address and user agent as described in Annex 1, section 5,
- browser storage used by the search script on the Reader's device, as described in Part B of our Privacy Policy: a session storage cache of filter options for 10 minutes, and a local storage flag that excludes the Customer's own searches from the analytics. The search script sets no cookies.
3.2 Blog authors. For authors of the Customer's blog who have published posts, Vellumine processes their name, slug, bio, profile image URL, and author page URL. Vellumine does not sync staff email addresses or any data about the members of the Customer's Ghost blog.
3.3 Personal data in Customer Content. Posts and pages that Vellumine syncs may themselves contain personal data, for example names of authors or of other people mentioned in a post. Vellumine processes this data only as part of the Customer Content, for the purposes in section 2.
3.4 Special categories. Vellumine does not intend to process special categories of personal data (Art. 9 GDPR). Because search queries are free text, they may contain such data if a Reader types it. The Customer should not ask Readers to enter personal data in the search.
3.5 Data subjects. The data subjects are:
- the Readers of the Customer's blog,
- the authors and staff of the Customer's blog, and
- other people whose personal data is contained in the Customer Content.
4. Instructions
4.1 Vellumine processes Customer Personal Data only on documented instructions from the Customer, including with regard to transfers to a third country, unless Union or Member State law requires Vellumine to process it. In that case, Vellumine informs the Customer of that legal requirement before the processing, unless the law prohibits this on important grounds of public interest.
4.2 The Customer's instructions are set out in:
- the Terms,
- this DPA, and
- the configuration that the Customer chooses in the app, for example the Collections it creates, the content it syncs, the features it turns on such as dynamic suggestions or the weekly digest, and the Collections it deletes.
4.3 The Customer can give further instructions in text form, for example by email. If an instruction goes beyond the functions of the Service, Vellumine tells the Customer whether and how it can follow it.
4.4 Vellumine informs the Customer without undue delay if it believes that an instruction infringes the GDPR or other data protection law. Vellumine may suspend following that instruction until the Customer confirms or changes it.
4.5 Some Collections are managed through a Vellumine partner, for example a hosting provider, that acts for the Customer. If the Customer authorises a partner to manage a Collection, the Customer instructs Vellumine to make that Collection, its configuration, and its search analytics available to the partner through Vellumine's partner API. The partner acts on the Customer's side. It is not a subprocessor of Vellumine.
4.6 Vellumine does not use Customer Personal Data for its own purposes, and does not sell it or disclose it to third parties except as set out in this DPA or required by law.
5. Confidentiality
5.1 Vellumine ensures that every person it authorises to process Customer Personal Data has committed to confidentiality or is under an appropriate statutory obligation of confidentiality (Art. 28(3)(b) GDPR). This obligation continues after their work for Vellumine ends.
5.2 These persons process Customer Personal Data only on the Customer's instructions (Art. 29 GDPR). At the time of this version, Vellumine is run by its owner alone, and no other person has access to Customer Personal Data.
6. Security
6.1 Vellumine takes the technical and organisational measures required under Art. 32 GDPR. Annex 1 describes these measures.
6.2 Vellumine may change these measures as technology and the Service develop, as long as the level of protection is not reduced. Vellumine documents material changes in a new version of Annex 1.
7. Subprocessors
7.1 The Customer gives Vellumine general written authorisation to engage subprocessors (Art. 28(2) GDPR). The subprocessors listed in Annex 2 are approved when this DPA takes effect.
7.2 Vellumine informs the Customer by email at least 30 days before it adds or replaces a subprocessor. The notice names the subprocessor, its purpose, and its location. The new list is also published as a new version of this DPA in the version history.
7.3 The Customer can object to the change for reasons of data protection within the 30-day notice period, in text form. Vellumine and the Customer then try to find a solution in good faith. If they do not find one, the Customer can terminate the contract free of charge with effect before the change takes effect.
7.4 Vellumine imposes the same data protection obligations as in this DPA on every subprocessor by contract, in particular sufficient guarantees for appropriate technical and organisational measures (Art. 28(4) GDPR). Vellumine remains liable to the Customer for the performance of the subprocessor's obligations.
7.5 Vellumine transfers Customer Personal Data to a country outside the European Economic Area only if the requirements of Art. 44–49 GDPR are met. Annex 2 names the transfer mechanism for each subprocessor.
8. Assistance
8.1 Data subject requests. Vellumine assists the Customer, through appropriate technical and organisational measures and within reason, in answering requests from data subjects under Art. 12–22 GDPR. If a data subject contacts Vellumine directly, Vellumine forwards the request to the Customer without undue delay, where the Customer can be identified, and does not answer it itself except to refer the data subject to the Customer.
8.2 Vellumine stores Reader data only in aggregated daily statistics and with a daily session identifier that can no longer be linked back to a Reader once the daily salt has been deleted (Annex 1, section 5). Redacted search queries also appear in application logs (Annex 1, section 6). For this reason, Vellumine will usually not be able to identify the data of an individual Reader (Art. 11 GDPR). On the Customer's instruction, Vellumine deletes specific stored search queries, for example if a Reader asks for a query to be removed that contains their personal data.
8.3 Other obligations. Within reason and taking into account the information available to it, Vellumine assists the Customer in meeting its obligations under Art. 32–36 GDPR: the security of processing, notifying personal data breaches, data protection impact assessments, and prior consultation with a supervisory authority.
9. Personal data breaches
9.1 Vellumine notifies the Customer without undue delay after becoming aware of a personal data breach affecting Customer Personal Data. Vellumine aims to notify the Customer within 48 hours. The notification is sent to the email address of the Customer's account.
9.2 As far as the information is available, the notification describes:
- the nature of the breach, including the categories and approximate number of data subjects and records concerned,
- the likely consequences of the breach,
- the measures taken or proposed to address the breach and to mitigate its possible adverse effects, and
- a contact point for further information.
If not all information is available at once, Vellumine provides it in phases without undue further delay.
9.3 Vellumine takes the measures needed to contain the breach and to mitigate its possible adverse effects, and informs the Customer about them. Notifying the supervisory authority and the data subjects is the Customer's responsibility as controller. Vellumine supports the Customer under section 8.3.
10. Deletion and return
10.1 Before the contract ends, the Customer can export its data on the Profile page in the app at any time, as one machine-readable file (JSON). For each Collection, including Collections deleted in the last 30 days, the export contains its configuration (without API keys or other secrets), its sync history, its weekly digest settings and send log, the list of synced posts and pages with their tags, and its search analytics: the daily statistics of search queries (in redacted form), clicks, tags, and sessions by country, device type, and browser, without session identifiers. The export also contains the Customer's account data. It does not contain the search index, including the synced author profiles, because the search index is a copy of the Customer's Ghost content, which remains in the Customer's Ghost blog. Vellumine recommends exporting any data the Customer wants to keep before deleting its account or before the contract ends.
10.2 When the contract ends, Vellumine deletes all Customer Personal Data within 30 days, unless Union or Member State law requires Vellumine to keep it.
10.3 During the contract, Customer Personal Data is deleted:
- when its retention period ends, as described in Annex 1, section 8,
- when the Customer deletes a post in Ghost or excludes it from the search. The post is removed from the search index when Vellumine receives the change from Ghost and at the latest at the next sync, and from the list of synced posts 30 days later,
- when the Customer deletes a Collection. Vellumine then deletes the search index, the public search configuration, and the Ghost webhooks immediately, and all other Collection data, including analytics, 30 days later. Ghost webhooks of older Collections are removed the next time Ghost sends them (Annex 1, section 8).
10.4 Logs and backups are kept for no longer than 30 days (Annex 1, sections 6 and 7). Customer Personal Data in application logs, server access logs, and backups is deleted when that period ends, even if this is later than the 30 days in section 10.2. Backups are used only to restore the Service after a failure or data loss and are not restored for any other purpose.
10.5 On request, Vellumine confirms the deletion to the Customer in text form.
11. Audits
11.1 Vellumine provides the Customer with all information necessary to demonstrate compliance with Art. 28 GDPR and this DPA. In the first instance, Vellumine does this by providing documentation, such as this DPA and its annexes, and by answering the Customer's written questions within a reasonable period.
11.2 If this information is not sufficient to demonstrate compliance, Vellumine allows for and contributes to audits, including inspections, by the Customer or by an auditor mandated by the Customer. For an on-site inspection:
- the Customer gives reasonable notice in advance,
- the inspection takes place during normal business hours and without unreasonable disruption of Vellumine's operations,
- the auditor is bound to confidentiality and is not a competitor of Vellumine, and
- the Customer bears its own costs and the costs of the auditor.
11.3 The servers that process Customer Personal Data are operated by the subprocessors in Annex 2. For their premises, Vellumine provides the reports and certifications that the subprocessors make available.
11.4 The rights of the supervisory authorities remain unaffected.
12. Liability
12.1 The liability of the parties to each other under this DPA follows clause 9 of the Terms.
12.2 The liability of the parties towards data subjects under Art. 82 GDPR remains unaffected.
Annex 1: Technical and organisational measures
This annex describes the technical and organisational measures that Vellumine takes under Art. 32 GDPR. It describes only measures that are in place.
1. Encryption in transit
- Readers' browsers connect to Vellumine's search servers, to the app, and to the content delivery network over HTTPS (TLS).
- Vellumine's servers connect to the APIs of its subprocessors and to the Customer's Ghost blog over HTTPS.
- The connection from Vellumine's servers to the Supabase database requires TLS (
sslmode=require).
2. Encryption of stored credentials
- The Customer's Ghost Admin API key, the secret used to verify webhooks from the Customer's Ghost blog, and the recipient address in the log of sent digest emails are encrypted in the database with AES-256-GCM, with a random initialisation vector for each value and an authentication tag that detects tampering.
- The encryption key is kept outside the database, in the server's environment.
- API keys of Vellumine partners are stored only as SHA-256 hashes and are compared in constant time.
3. Access control
- Customer accounts. Customers sign in with a password or with GitHub or Google. Passwords are stored only as hashes, by Supabase.
- Role-based access. Access to a Collection and its analytics is checked on every request against the user's workspace membership and role (owner, admin, editor, or viewer). Only owners, admins, and editors can change or delete a Collection.
- Partner access. Partner API keys carry scopes, for example read-only access to analytics. A partner can only access Collections that it manages.
- Scoped search keys. The search script on the Customer's blog uses a search-only key for each Collection. It can only search that Collection's index and only returns fields needed for search results. The full text of members-only and paid posts is never returned to Readers.
- Administrative access. Only Vellumine's owner has administrative access to the servers, the database, and the subprocessors' consoles.
4. Server security
Vellumine's servers at Ionos are configured according to an internal hardening runbook, which has been applied on all servers.
- A firewall at Ionos allows only SSH, web traffic (HTTP and HTTPS), and specific administration ports from the internet. Internal service ports, such as the direct ports of the search engine, the reverse-proxy dashboard, monitoring, and the deployment platform, are blocked from outside.
- A host firewall on each server adds a second layer, with rules that also cover ports published by Docker.
- SSH login is possible with keys only. Password login is disabled, and the number of login attempts per connection is limited.
- Security updates are installed automatically (unattended-upgrades). AppArmor is enabled.
- Repeated failed SSH login attempts are blocked automatically (Fail2ban).
5. Pseudonymisation and data minimisation
- Daily session identifier. The session identifier of a Reader is an HMAC-SHA256 hash of the Collection ID, the IP address, and the user agent, keyed with a random value (salt) for each day (UTC). Salts older than the previous day are permanently deleted, at the latest by a daily job at 02:00 UTC, so each salt exists for at most about 50 hours. Once the salt is deleted, nobody, including Vellumine, can compute the identifier from an IP address and user agent again, or link a Reader's searches across days or across blogs.
- No storage of IP address or user agent. The search analytics store neither the IP address nor the user agent of a Reader. City and region are not collected.
- Query redaction. Search queries are converted to lowercase, and email addresses and phone numbers are replaced with placeholders before they are stored in the analytics or written to application logs. Phone numbers are recognised in international format (starting with + or 00), in national formats with a leading 0, and 10-digit North American numbers written without separators or with dashes or dots (555-123-4567). Redaction is best effort: other numbers, such as national numbers without a leading 0 or +, or North American numbers written with spaces or brackets, and other personal data in a query are not removed.
- No Reader search queries in URLs. The search script sends Readers' search queries only in the body of
POSTrequests, never in the URL, so request logs of proxies and the content delivery network do not contain the queries that Readers type. The Customer's analytics views in the app request details of a stored, redacted query with the query in the URL. - Aggregation. Reader events are stored only as daily aggregated statistics per Collection.
- No processing without an entitlement. Analytics events for Collections without an active subscription, trial, or partner entitlement are discarded.
- No Reader cookies. The search script sets no cookies on the Reader's device.
6. Logging
- Application logs are written in a structured format. Values with names that indicate secrets, such as API keys, passwords, tokens, cookies, and authorisation headers, are replaced with
[REDACTED]before a log entry is written. - Application logs do not contain IP addresses. Logs of Reader events contain neither the IP address nor the user agent, and contain search queries only in redacted form.
- Application logs record request paths without query parameters. Server access logs are separate and are described below.
- Application and container logs are stored in Axiom's EU region and kept for at most 30 days. Container logs on the servers are rotated within the same period.
- Sign-in logs of Customers' accounts are kept by Supabase for 7 days.
- Server access logs. The reverse proxy and the search servers do not write access logs or search logs. If Vellumine turns them on temporarily to investigate a problem, they can contain the IP address, user agent, time, and requested URL of requests, including requests from Readers' browsers, and they are kept for at most 30 days. They are used only to keep the Service secure and stable, as a security measure on the Customer's behalf.
- Cloudflare. Cloudflare keeps request logs of the requests that pass through its network for 30 days.
7. Availability and backups
- The search engine runs on three servers. If one server is unavailable, the search script sends requests to another one.
- The database is operated by Supabase. Supabase creates daily backups of the database, encrypts them at rest, and keeps them for 7 days. They are used only to restore the Service after a failure or data loss.
- Vellumine keeps no standing copies of the database of its own. One-off manual exports, for example before moving to another database, are deleted within 7 days. There are no snapshots of the search servers.
8. Deletion
- Analytics retention. Reader analytics are deleted when the retention period of the Customer's plan ends, as shown on the pricing page. For Collections without an active subscription, the retention period is 90 days. A scheduled job runs daily, marks expired statistics as deleted, and permanently deletes them 30 days later.
- Digest email logs are marked as deleted after 90 days and permanently deleted 30 days later, so they are kept for at most 120 days.
- Session salts are permanently deleted after at most about 50 hours, as described in section 5.
- Synced content. When a post is deleted in Ghost or excluded from the search, it is removed from the search index when Vellumine receives the change from Ghost and at the latest at the next sync. Its entry in the list of synced posts is permanently deleted 30 days later.
- Collection deletion. When the Customer deletes a Collection, its search index, search keys, public search configuration, and queued jobs are deleted immediately, and the Ghost webhooks that Vellumine created are removed. For Collections created before this removal was available, and if the Customer's Ghost blog cannot be reached, Ghost removes each webhook the next time it sends it. All other data of the Collection, including its analytics, sync history, synced post list, and digest email logs, is permanently deleted 30 days later.
- Account deletion. When the Customer deletes its account, all its Collections, including deleted Collections, are permanently deleted immediately, together with their search indexes, public search configuration, and analytics. The Ghost webhooks are removed as for a Collection deletion. If a step fails, for example because a subprocessor is unavailable, it is retried hourly, and the deletion is completed within 30 days at the latest. A deletion record with the Customer's user ID, timestamps, and the status of each step is kept for 30 days after completion.
- Logs and backups. Copies in logs and backups are deleted when their retention period in sections 6 and 7 ends, at the latest 30 days after the deletion.
- End of contract. All Customer Personal Data is deleted as described in section 10 of this DPA.
Annex 2: Subprocessors
The Customer authorises the following subprocessors. They process Reader data or Customer Content on Vellumine's behalf.
| Subprocessor | Purpose | Data | Region | Transfer mechanism |
|---|---|---|---|---|
| IONOS SE, Germany | Hosting of the app servers and the search servers (Typesense) | All data in section 3: the search index with synced content and author profiles; Reader search requests and events, including IP address and user agent in transit | Germany (Berlin) | Not needed for a data centre in the EU/EEA |
| Supabase Pte. Ltd., Singapore | Database | Aggregated search analytics; titles, URLs, and tags of synced posts; Collection configuration | EU (Frankfurt, Germany) | Standard Contractual Clauses |
| Cloudflare, Inc., USA | DNS, content delivery network, reverse proxy, storage of the search configuration (R2) | Reader IP address, user agent, and requests in transit and in request logs; redacted search queries in request URLs of the Customer's analytics views (request logs, 30 days); public search configuration, including popular redacted queries if dynamic suggestions are on | Global network; company in the USA | EU–US Data Privacy Framework |
| Modal Labs, Inc., USA | Text embeddings of post content for Collections with semantic search | Title, excerpt, and plain text of posts. Reader search queries are never sent to Modal | EU | Standard Contractual Clauses |
| Plus Five Five, Inc. (Resend), USA | Delivery of weekly digest emails | Aggregated redacted search queries and statistics in the digest | EU (Ireland) | EU–US Data Privacy Framework |
| Axiom, Inc., USA | Storage of application logs | Redacted search queries and Collection IDs in logs | EU (Frankfurt, Germany) | Standard Contractual Clauses |
The EU–US Data Privacy Framework is based on the European Commission's adequacy decision of 10 July 2023. Standard Contractual Clauses are the clauses adopted by the European Commission in Decision (EU) 2021/914.
Vellumine partners that manage a Collection for the Customer (section 4.5) are not subprocessors and are not listed here.
Vellumine uses PostHog for product analytics of its own website and app, as a controller. In the app, views that show Reader search queries are masked in PostHog's session recordings and excluded from its automatic event capture, input fields are masked, and recorded network requests are stripped of query strings and bodies. PostHog therefore does not receive Customer Personal Data and is not a subprocessor.