Data Processing Agreement
Draft wording — not yet reviewed by a solicitor. This page is published so you can see how we intend to work while a solicitor reviews it. Anything in [square brackets] is still to be decided. It is not final legal wording and should not be relied on as such. Version recorded: draft-2026-11-03.
Parties
This agreement is between:
- The Customer named in the Order (the "Controller"). The Controller is the agency that uses AquaCRM.
- Edward Hallam, a sole trader in England and Wales, trading as AquaCRM, of the address given on request at [email protected] ("AquaCRM", the "Processor").
It forms part of the AquaCRM Terms of Service (the "Terms") and takes effect on [EFFECTIVE DATE].
1. Definitions
1.1 UK GDPR, controller, processor, data subject, personal data, processing and personal data breach have the meanings given in the UK GDPR, as defined in section 3(10) of the Data Protection Act 2018 ("DPA 2018"). Data Protection Law means the UK GDPR, the DPA 2018 and the Privacy and Electronic Communications Regulations 2003.
1.2 Customer Personal Data means personal data that AquaCRM processes for the Controller in providing the Service.
1.3 Sub-processor means a third party that AquaCRM engages to process Customer Personal Data.
1.4 Connected Service has the meaning in the Terms. It is a service that the Controller connects to the Service using its own account and credentials.
1.5 Restricted Transfer means a transfer of Customer Personal Data to a country outside the UK that is not covered by UK adequacy regulations.
1.6 Other capitalised terms have the meanings given in the Terms.
2. Roles
2.1 For Customer Personal Data, the Controller is the controller and AquaCRM is the processor.
2.2 Where the Controller itself processes some of the Customer Personal Data as a processor for its own clients, the following applies. The Controller warrants that it has its clients' authority to appoint AquaCRM as a sub-processor on these terms. In relation to those clients' data, AquaCRM's obligations run to the Controller. [Solicitor: see open question S2.]
2.3 AquaCRM is a controller, not a processor, of the personal data it processes for its own purposes. That covers Authorised Users' account, sign-in and security records, and the Controller's billing contacts. That processing is described in AquaCRM's product privacy notice and is not governed by this agreement. [Solicitor: see open question S3.]
3. Details of the processing
The subject matter, duration, nature and purpose of the processing, and the types of personal data and categories of data subject, are set out in Annex 1.
4. Instructions
4.1 AquaCRM will process Customer Personal Data only on the Controller's documented instructions, unless UK law requires otherwise. If it does, AquaCRM will tell the Controller before processing, unless that law forbids it.
4.2 The Controller's documented instructions are:
(a) the Terms and this agreement; and
(b) the Controller's own use and configuration of the Service by its Authorised Users. Examples are creating records, connecting Connected Services, sending messages, publishing websites, using the AI assistant, setting retention periods and erasing clients.
4.3 AquaCRM will tell the Controller promptly if, in its opinion, an instruction infringes Data Protection Law.
5. Confidentiality
5.1 AquaCRM will make sure that everyone it authorises to process Customer Personal Data is bound by a duty of confidentiality, whether contractual or statutory.
5.2 Access to Customer Personal Data outside the Service's own screens, for example directly in the database, is limited to [NAMED PERSONS — today, Edward Hallam only]. It is used only for support the Controller has asked for, for security, incident response and maintenance, or where the law requires.
6. Security
6.1 AquaCRM will implement the technical and organisational measures in Annex 2. They are designed to give a level of security appropriate to the risk, as Article 32 UK GDPR requires.
6.2 AquaCRM may change those measures, provided the change does not materially reduce the overall level of protection.
6.3 Some security depends on the Controller. This includes the roles and permissions it grants, whether its users turn on two-factor sign-in, the Connected Services it chooses, and the security of its own devices. The Controller is responsible for those choices.
7. Sub-processors
7.1 The Controller gives AquaCRM general written authorisation to engage the
Sub-processors listed in Annex 3 (sub-processors.md).
7.2 AquaCRM will tell the Controller at least [30] days before adding or replacing a Sub-processor, by [email to the Workspace owner / a notice in the Service]. The Controller may object on reasonable data protection grounds within that period. The parties will then discuss it in good faith. If they cannot resolve the objection, the Controller may end the Terms for the affected part of the Service without penalty.
7.3 AquaCRM will impose on each Sub-processor, by written contract, data protection obligations that give at least the same protection as this agreement. AquaCRM remains liable to the Controller for each Sub-processor's performance of those obligations.
7.4 Connected Services are not Sub-processors. The Controller engages a Connected Service directly, under its own agreement with that provider and using its own credentials. AquaCRM transmits Customer Personal Data to and from it on the Controller's instruction. [Solicitor: see open question S4. This is not yet true for every Connected Service. Reviewer note B7 records the code paths that use AquaCRM's own account with Resend, GitHub and Vercel for any customer, and Annex 3 lists those three as Sub-processors for those uses.]
8. International transfers
8.1 AquaCRM hosts the Service's application server, database and file storage in the regions shown for them in Annex 3. Annex 3 also marks whether each region has been verified.
8.2 AquaCRM will not make a Restricted Transfer of Customer Personal Data unless one of the following covers it: UK adequacy regulations (including the UK Extension to the EU-US Data Privacy Framework, for a certified recipient), the International Data Transfer Agreement, or the UK Addendum to the EU Standard Contractual Clauses. Annex 3 names the mechanism proposed for each Sub-processor. [Every mechanism there is marked "to confirm". None is recorded as in place.]
8.3 Transfers to a Connected Service are made on the Controller's instruction, under the Controller's own agreement with that provider.
9. Helping with data subject rights
9.1 The Service gives the Controller's owners and managers these tools for responding to data subjects:
(a) erasure of a client workspace. This is available to an owner only, who must type the client's name to confirm. Each category of data is deleted, anonymised or kept according to a fixed policy, and retained recovery copies inside the database are scrubbed. If any step fails, the erasure stops and can be retried rather than reporting success;
(b) a preview of what an erasure would remove, before anything is removed;
(c) a subject access export that prepares a structured copy of the records held about one person. A review and a delivery step are recorded against the exact file produced;
(d) retention settings for the activity log, closed subject requests and enquiry notices. Nothing is deleted until the owner switches enforcement on;
(e) a subject-request register showing each request's one-month deadline.
[See reviewer note B6: the register in (e) has no way to add a request from inside the Service today. Because (c) works only on a request already in the register, (c) cannot be used through the Service yet. Do not sign 9.1(c) or (e) as written until that is fixed.]
9.2 If AquaCRM receives a request from a data subject about Customer Personal Data, it will pass the request to the Controller within [5] business days. It will not respond to the data subject itself, other than to say that it has passed the request on, unless the Controller instructs it to.
9.3 Where the tools in 9.1 do not reach the data a request concerns, AquaCRM will help the Controller on request, so far as it reasonably can. Examples are data outside the records the export reads, or data held in a Connected Service. [Charges, if any.]
10. Other help
Taking into account the nature of the processing and the information available to it, AquaCRM will give the Controller reasonable help with the Controller's obligations under Articles 32 to 36 UK GDPR. Those cover security, breach notification, data protection impact assessments and prior consultation with the Information Commissioner.
11. Personal data breaches
11.1 AquaCRM will notify the Controller without undue delay, and in any event within [24 / 48] hours, after becoming aware of a personal data breach affecting Customer Personal Data.
11.2 The notice will include, as far as AquaCRM then knows them: the nature of the breach; the categories and approximate number of data subjects and records concerned; the likely consequences; what AquaCRM has done and proposes to do; and a contact for further information. Where AquaCRM does not have all of this yet, it will send what it has and follow up as it learns more. It will not hold back the first notice in order to complete it.
11.3 AquaCRM will not notify the Information Commissioner or any data subject about a breach of Customer Personal Data on the Controller's behalf unless the Controller asks it to, or the law requires it to.
11.4 AquaCRM will keep its own record of every breach affecting Customer Personal Data. It will help the Controller meet its 72-hour notification duty.
12. Deletion or return at the end
12.1 After the Terms end, the Controller may export Customer Personal Data during the Exit Period stated in the Terms. AquaCRM will help as the Terms describe.
12.2 Within [30] days after the Exit Period ends, AquaCRM will delete Customer Personal Data from the Service. Any copy that UK law requires AquaCRM to keep is excepted.
12.3 Copies of Customer Personal Data in backups will be deleted when those backups expire under their retention schedule. Until then they will be kept secure and not used. [Today the only recovery copies the Service makes itself are the in-database copies described in Annex 2, item 21. They are replaced as later changes are made. The repository does not record whether any copy exists outside the database; reviewer note B1 asks Ed.]
12.4 On request, AquaCRM will confirm in writing that deletion is complete.
[See reviewer note B5: there is no single function today that deletes an entire agency Workspace. Deletion at the end would be a manual operation, and that is the process this clause commits to.]
13. Audits and information
13.1 AquaCRM will make available to the Controller the information reasonably needed to show that it meets Article 28 UK GDPR. That includes answering reasonable security questionnaires.
13.2 The Controller, or an independent auditor bound by confidentiality, may audit AquaCRM's compliance with this agreement. The Controller must give at least [30] days' written notice, may audit no more than once in any 12 months (except after a personal data breach or where a regulator requires it), and must arrange the audit to avoid unreasonable disruption. [Costs: each party bears its own / the Controller pays.]
14. Liability
Each party's liability under this agreement is subject to the limits and exclusions in the Terms. [Solicitor: see the Terms clause 17.4 and open question S5.]
15. General
15.1 This agreement lasts for as long as AquaCRM processes Customer Personal Data for the Controller.
15.2 If this agreement conflicts with the Terms on a data protection matter, this agreement prevails.
15.3 This agreement is governed by the law of England and Wales. The courts of England and Wales have exclusive jurisdiction.
Annex 1 — Details of the processing
Subject matter. Hosting and operating the AquaCRM Service for the Controller.
Duration. The term of the Terms, plus the Exit Period and the deletion period in clause 12.
Nature of the processing. Collecting (through forms, connected inboxes and connected sources), recording, organising, storing, retrieving, displaying, editing, analysing, transmitting (sending email, SMS and messages on the Controller's instruction), restricting, and erasing.
Purpose. Providing the Service to the Controller under the Terms.
Categories of data subject. Those the Controller chooses to keep in the Service. Typically:
- the Controller's own owners, managers, staff and freelancers;
- the Controller's clients, and their staff who are given client-portal access;
- its clients' customers (portal users, buyers, members, affiliates);
- prospects and enquirers, including people who contact the Controller's or its clients' websites, and businesses found through prospecting;
- people who correspond with the Controller through connected inboxes (email, Facebook and Instagram messages, SMS, WhatsApp and calls);
- meeting attendees from connected calendars;
- job applicants and employees, where the Controller uses the People module;
- visitors to websites that carry the Aqua Tag, as consent-limited telemetry only.
Types of personal data.
- identity and contact details: name, email, phone, company, job title, business address, social-profile identity of a messaging sender;
- communications: message bodies and attachments, email content, and notes of meetings and calls;
- audio: calls recorded from the inbox, and voice notes. Both are recorded from the user's microphone in the browser and stored in the Service. Before a call is recorded, the user must confirm that everyone on the call has agreed to it;
- commercial and financial records: proposals, invoices, orders, subscriptions, affiliate earnings, and payment references (not card numbers — card payments are taken on the payment provider's own checkout);
- account and access data for Authorised Users: role, workspace membership, sign-in records;
- HR records, if the People module is used: applications, CVs, employment records, leave, shifts, training and feedback;
- working-time and activity records about the Controller's staff, where they clock in to the Service: clock-in and clock-out times; the time spent on each screen of the Service; when they last interacted with it and whether the page was visible; idle time; check-ins, breaks and declared work outside the Service; day and week plans and reviews; per-day counts of their actions; bids for tasks; internal chat messages; and personal alert settings;
- website telemetry, if the Aqua Tag is used: page, performance, error and conversion events, with a pseudonymous visitor id and page title. Events are sent only for the cookie categories the visitor has allowed. The record of the visitor's choice itself is always sent. Page and referrer addresses are reduced to origin and path. Form field values are not read;
- anything else the Controller's users type into free-text fields or upload.
Special category data. One kind is processed by design. If the Controller uses the People module, staff leave is recorded by type, and one of the types is sick leave, which is health data about the Controller's staff. Beyond that, special category data is not intended, and the Terms prohibit it without prior written agreement. Free-text fields, messages and uploaded CVs can contain it anyway, and the Controller is responsible for that content.
Frequency. Continuous, for the term.
Annex 2 — Technical and organisational measures
These are the measures in the Service at the version this draft was checked against. Each is backed by a reviewer note.
Hosting and location
- The application server runs on Railway in its EU West region. The database,
authentication and file storage run on Supabase in
eu-west-1(Ireland). [One exception: files stored before the move to Supabase may still be held in Vercel Blob storage, which the Service still reads. Its region is not verified. See Annex 3.]
Encryption in transit
- Browser traffic is served over HTTPS. Every response carries an HSTS header for two years, including subdomains, with preload.
- In production, direct database connections use TLS with the certificate verified,
unless the connection string itself says otherwise. What the connection string says
takes precedence over the Service's own TLS setting. Of the settings that were
checked:
sslmode=disable,ssl=0, or alocalhostor127.0.0.1address with nosslmode, turns TLS off;ssl=no-verify,sslmode=no-verify, oruselibpqcompat=truewithsslmode=prefer, or withsslmode=requireand nosslrootcert, keeps TLS but turns the certificate check off;uselibpqcompat=truewithsslmode=requireorverify-caand ansslrootcertfile checks the certificate against that file but does not check that it was issued for the server's host name; and the other TLS settings checked keep the full check but replace the Service's own certificate-authority setting. These are the settings that were checked, not every one a connection string can carry. Connections to a mailbox (IMAP) also verify the certificate. [What the live connection string says is not recorded in the repository. See reviewer note A3.]
Encryption of credentials at rest
- Credentials the Controller stores for Connected Services through the Service's
integration, calendar and inbox connections are encrypted with AES-256-GCM before
storage. These include API keys, tokens, SMTP and IMAP passwords, calendar tokens
and messaging secrets. So are the secret fields on a module's settings page, such
as Stripe keys, and, from [the date the Email sender change is deployed], the
four credentials entered on the Email sender module's own Settings page: its
Postmark server and account tokens, its SMTP password and its Postmark webhook
signing secret. The key is held outside the database. In production the Service
cannot encrypt or decrypt without the key, so a save that would store one of these
credentials is refused rather than written in plain text.
[A secret entered anywhere else is not covered. These keep it in plain text in
the workspace data: the headers of an automation's webhook action, where the
editor suggests an
Authorizationheader; and the signing secret and headers of a website-editor webhook target. Until the Email sender change is deployed, every Email sender credential is stored in plain text as well. After it, one stored before it stays in plain text until the module's settings are saved, a send succeeds, or a send fails with an authentication-type error, whichever comes first. Nothing re-encrypts it in the background, and a backup taken before then still holds it in plain text. In production without the key, a save that would store a credential is refused and a send cannot encrypt one, so a plain-text credential stays as it is until the key is set. The Email sender also keeps unencrypted, on its settings record, the last four characters of each credential longer than 8 characters; the activity entry for a save repeats that tail for the server token or SMTP password only. Until a credential stored before the change is re-encrypted, the record keeps the tail worked out under the old rule: the whole credential when it is four characters or fewer, otherwise its last four, which for a credential of up to eight characters is most of it. The Business Radar records view and its download show that tail. Activity entries and error text written before the change are not rewritten, and an activity entry for saving a server token or SMTP password of four characters or fewer holds it whole. Before the change, the Service also showed a stored Email sender credential in full to some users; reviewer note A4 says who. These were found by reading the code; not every field was audited. See reviewer notes A4 and B17.] [Encryption at rest of the database and file storage as a whole is a feature of the hosting provider and is not claimed here until confirmed. See reviewer note B8.]
Authentication and sessions
- Users' passwords are not stored in plain text. Sign-in is verified by Supabase
Auth, and the application's own user record holds only a salted scrypt hash. New
passwords must be at least 8 characters, and very common ones are refused. [One
exception: the operator's own founder account is created from a password that
production requires as a plain-text setting in the hosting configuration
(
FOUNDER_PASSWORD). See reviewer note A5.] - Two-factor sign-in with an authenticator app is available. Once a user has enrolled, sign-in is refused without the code. Recovery codes are stored only as hashes, and each code is deleted when used.
- The Service's own session cookie is HTTP-only and SameSite=Lax, and is marked Secure in production. By default it lasts 7 days. (The embedded client-account view sets the same cookie with SameSite=None in production, so that it works inside a frame.) Every authenticated request checks again that the user still exists, still holds the same role, is still a member of the workspace, and has not been suspended or had their sessions revoked. [Signing in also sets the authentication provider's own session cookies, and later requests rewrite them when their token is refreshed. They are not hardened in the same way. See reviewer note B15.]
- Before a password is checked in production, sign-in, sign-up, password reset, magic-link requests and the public enquiry forms require a bot challenge (Cloudflare Turnstile). If the challenge is not configured, these requests are refused rather than let through. [Two public intake routes have rate limits but no bot challenge: form capture from websites, and the demo-interest form, which answers only when the demo is switched on. See reviewer note A8.]
- Sign-in and public endpoints have rate limits that are kept in the database, so they survive restarts, and that refuse requests if the limit cannot be checked. For sign-in, they allow 10 attempts per IP address per minute, and 10 attempts, successful or not, for the same email address from the same IP address in 5 minutes. In addition, each server process blocks an email address and IP address pair for 5 minutes after 10 failed sign-ins; that faster lockout is held in memory and is lost on a restart. The durable counters store a keyed hash of the IP address or account identifier, not the raw value.
Access control
- Every server action that needs a signed-in user checks that user's role and workspace. The Service has fixed roles for agency, client and customer users, and finer per-person permissions (hidden, view, use, manage) scoped to a workspace, client or project, with optional expiry.
- The database roles a browser can use hold only a short reviewed list of read permissions, under row-level security. Workspace data is read and written by the server, and so are private files.
Application security
-
State-changing requests from a browser to the signed-in API (the paths under
/api/portal/,/api/auth/,/api/tenants/and/api/internal/) are refused unless they come from the Service's own origin. The check uses the exact Origin header and Fetch Metadata. Public intake forms, provider webhooks, the token-authenticated API and telemetry are outside the check by design, because they do not rely on the sign-in cookie. [One signed-in route is also outside it: the in-app assistant at/api/assistant, which has a weaker origin check of its own. See reviewer note A12.] -
Responses carry a Content Security Policy,
X-Content-Type-Options: nosniff, a Referrer-Policy and a Permissions-Policy that switches off camera, microphone and location. [The Permissions-Policy also covers the features that need the microphone and camera. See reviewer note B16.] -
Files uploaded to private storage are checked by their content as well as by their declared type, and a SHA-256 digest of each one is recorded. Executables, disguised active content and files whose content does not match their declared type are refused. Where a malware scanner is configured, the file is sent to it, and a file the scanner could not read in full is never treated as cleared. In production, an upload that the scanner does not clear is refused, not stored. With no scanner, high-risk types (PDF, ZIP and Office files) are refused in production, and other types get the content check only. Public media uploads get the content and type check only. [Not every upload path in the code is claimed to go through this check. See reviewer note A14.]
-
Four pieces of code check a server-side request's address before it is made, with one shared address rule. The address must be public: private, loopback, link-local (which includes the cloud-metadata address), carrier-grade NAT, multicast and reserved addresses are refused, a name that resolves to any such address is refused as a whole, and the connection goes to the address that was checked. The requests that go through them are these:
- the egress broker, for HTTP requests such as automation webhooks, connection tests (except the Search Console token request below), reads from a client's own database or shop, and one of the two malware-scanner paths. It also re-checks every redirect, strips credentials when a redirect changes origin, and allows only ports 80, 443, 8080 and 8443;
- the website fetcher, for site capture, site audits, set-up checks and Aqua Tag detection, which re-checks every redirect;
- Radar's website probes, which do the same;
- the malware scanner's own transport, for the other scanner path, which also requires HTTPS in production, accepts only its configured origin, and refuses redirects.
Connections to mail servers (SMTP and IMAP) use the broker's check and pin for raw connections; the Email sender module's do so from [the date the Email sender change is deployed]. From that date, for the Email sender module's SMTP option, production refuses any connection that is not TLS or STARTTLS before the host is looked up, and the server's certificate is checked against the host name the customer entered. IMAP accepts only port 993, with TLS. [Until the Email sender change is deployed, that module connects to the host the customer typed with no address check, and honours a saved choice of no transport security in production too. Two requests whose address comes from customer input do not go through any of the four, so their address is not checked: a Google Search Console connection sends its token request to the token address named in the service-account file the customer pastes in, and a website-editor form that submits to a webhook block posts to that block's address. Either can be pointed at a private address, including the cloud-metadata address. The SMTP path behind an SMTP Connected Service uses TLS on port 465, and on other ports upgrades to TLS only when the server offers it. The address rule does not refuse every special-purpose range. Not every outbound request in the code was audited. See reviewer notes A15 and B18.]
-
In production, the application will not start without a strong session secret and the other required security settings.
Logging and monitoring
- An activity log records who did what, and when. It holds the most recent 50,000 entries across the Service.
- Where error monitoring is switched on, the Service attaches only an allowlisted context to an error report: a correlation id, the error class, the route pattern (never the actual address or query string), the method, and internal workspace, client, plugin and user ids. The Service does not add request bodies, headers or cookies. The line that the error-capture code writes to the production server log carries the same allowlisted fields, without the user id. [That holds for the error-capture line only. Around seventy other places in the server code write their own error lines to the production server log at Railway, and most of those print the raw error, with its message and stack trace; one prints a user's email address. So the server log can contain personal data. The exception's own message and stack trace are also sent to the error monitor and can contain personal data. What the error-monitoring SDK collects by default, on its own, has not been audited. See reviewer note A18.]
Incident containment
- A workspace owner can lock the workspace, sign every session in it out, or revoke one person's sessions. In the application, each of these needs the password entered again, a typed confirmation word specific to the action, and a written reason. Platform-wide switches are reserved to a designated operator: suspend a person everywhere, cancel every session a person has anywhere, sign out every session on the whole Service, put the whole Service into read-only, and switch off AI features. The application's security screen does not offer them, so they run from an operator console on the server. Every containment action is recorded. All writes can also be frozen from the hosting configuration.
Erasure and retention
- A client workspace can be erased as described in clause 9.1(a). The surviving record of the erasure does not name the client.
- Retention, as it actually runs:
- the activity log keeps its most recent 50,000 entries;
- per-person activity counters are kept for 400 days;
- the database keeps the 20 most recent full copies of each stored state row, for recovery, and an erasure scrubs the erased client from them;
- write receipts are pruned after 30 days;
- the Controller can set retention periods for the activity log, closed subject requests and enquiry notices. By default no period is set, which means records are kept until deleted. Enforcement runs only after an owner switches it on and the server's scheduled maintenance task is configured.
AI
- Records are sent to an AI provider only when someone uses an AI feature. They go to the Controller's own connected provider account. The in-app assistant returns text and suggestions and does not change records itself.
People and process
- [Personnel: who has access, confidentiality undertakings, training.]
- [Incident response: the procedure for handling a personal data breach, including telling a controller early when its data is affected.]
Annex 3 — Sub-processors
See sub-processors.md in this folder.