Data-Processor Posture
The consent-certificate product (epic docs#19) captures personal data on behalf of publishers: a
witnessed form-submission opt-in. AdPriva therefore acts as a data processor on the client’s
documented instructions (GDPR Art. 28), with strict minimization. Compliance buyers audit this
posture first — this page is the reviewed checklist they are pointed to.
1. Roles
| Party | Role | Basis |
|---|---|---|
| Publisher / lead-gen partner | Controller | Determines purpose (proving consent for their own marketing) |
| AdPriva | Processor | Acts only on the controller’s documented instructions (Art. 28) |
| zkVerify, Horizen, DigitalOcean | Sub-processors | Engaged under Art. 28(4) with equivalent terms |
The certifiable consent event is the atomic unit we process: we seal it, anchor a hash, and serve a retrievable certificate. We do not determine the purpose of the underlying marketing.
2. Data Processing Agreement (DPA)
A processor DPA is offered to every partner before production traffic. Required clauses:
- Subject matter & duration — consent-evidence sealing + retention for the agreed period.
- Nature & purpose — tamper-evident proof of opt-in; no profiling, no resale.
- Categories of data —
form_url,sha256(consent wording), checkbox state, pseudonymoussubject_ref, field labels (never values), behavioural aggregates (never raw input). - Art. 28(3) obligations — process only on instructions; confidentiality; security (Art. 32); sub-processor flow-down; assist with Art. 15–22 requests; delete/return on termination; audit.
- Sub-processor authorisation — general authorisation with the list in §3 and 30-day change notice.
3. Sub-processors
| Sub-processor | Purpose | Data exposed | Location |
|---|---|---|---|
| DigitalOcean | Application + database hosting (App Platform, managed MySQL) | All processed fields at rest | EU region |
| zkVerify | ZK proof verification of the batch Merkle root | Hash only (Merkle root) — no PII | Decentralised |
| Horizen | On-chain anchoring of the verified root (Anchor.sol) | Hash only (Merkle root) — no PII | Public chain |
| Cloudflare | Static site + WAF for adpriva.com | None (public certificate reads) | EU/global edge |
Only hashes ever reach the chain. The anchoring path is the evidentiary edge, not a data flow: no personal data is published on-chain.
4. Retention
- Each consent certificate carries
retention_until. The public lookup serves 410 Gone once it passes (api/internal/app/public_certificates_handler.go) — the record is retired, not silently served. - Default retention is set per the controller’s instruction in the DPA (the consent product is sold on long-term, audit-grade retention; the controller picks the window).
- On termination, certificates are deleted or returned per the DPA. Raw operational logs follow the data-minimization policy in §5.
5. Data minimization (current state + gap)
Already minimized: consent wording is hashed (never stored raw); field labels only (never
values); behavioural signals are aggregates (no raw coordinates/keystrokes — tag/src/behavior.ts);
the public certificate is PII-free by construction (PII columns are never SELECTed).
Gap (filed as follow-up code issues): raw IP + User-Agent are still stored on the proofs model
(*/internal/model/proof.go). For consent certificates these must be pseudonymized or dropped:
- IP → daily-salted hash (the
DAILY_SALT_SECRETsalt already exists for rate-limiting) or dropped. - UA → coarse client class (browser family + bot flag), raw string dropped.
Tracked as follow-up code issues:
server#136(proof-model IP/UA minimization) andapi#222(consent subject-access endpoint, §6) — spun off from this posture doc per thedocs#20acceptance criteria.
6. Subject access (Art. 15) for consent certificates
A data subject (or the controller on their behalf) can retrieve every certificate tied to their
pseudonymous subject_ref — the tag never sends raw PII as the subject reference. Design:
subject_refis an APSID or a hashed handle, supplied by the controller’s form integration.- Subject-access is controller-mediated: the controller authenticates the subject, then queries by
subject_ref. AdPriva exposes the listing to authenticated controllers, not to the open internet (a publicsubject_reflisting would itself be a data leak). - For the mobile/consumer consent path, the existing
GET /mobile/v1/consent(api#96) already serves Art. 15 access for the authenticated user.
7. Cross-border transfers (Ch. V) & breach notification
- Transfers: hosting is pinned to an EU region; sub-processors that may process outside the EEA are covered by SCCs referenced in the DPA. On-chain anchoring transfers no personal data (hash only), so it is out of Ch. V scope.
- Breach notification: on a confirmed personal-data breach, AdPriva notifies the affected
controller without undue delay and within 72 hours of becoming aware, with the Art. 33(3) details
(nature, categories, likely consequences, measures). Controllers notify their supervisory authority.
Procedure lives in
operations-and-upgrades/incident-response-and-transparency.
Compliance checklist
- Processor role documented (Art. 28) with controller/processor split
- DPA clause set defined (§2)
- Sub-processor list published with data exposed + location (§3)
- Retention tied to
retention_until+ 410-Gone enforcement (§4) - Minimization stance documented; IP/UA gap filed as code follow-ups (§5)
- Art. 15 subject-access design (pseudonymous
subject_ref) (§6) - Ch. V transfer safeguards + 72-hour breach procedure (§7)
- IP/UA minimization code change merged (follow-up issues,
server/api) - DPA + SCCs counter-signed with the first France design partner