Per-tenant extracts available on request via dpo@preferium.com. Customer-portal export planned R176+.
GDPR Article 30 — Records of Processing Activities
Document status: Template for Preferium AS as Processor on behalf of Customers (Controllers). Required by Regulation (EU) 2016/679 Article 30(2). Last updated 2026-05-21 (R174 — preferium-edge).
Owner: Robert Andre Johansen (Acting DPO until R174+ outsource decision — see dpo-designation.md).
Review cadence: Quarterly + on any change to processing scope, sub-processors, retention, or transfer mechanism.
A. Controller / Processor identity
| Field | Value |
|---|---|
| Name | Preferium AS |
| Org. nr. | Robert to fill — to be added before first Enterprise customer signs DPA |
| Registered address | Robert to fill — to be added before first Enterprise customer signs DPA |
| Establishment within EU/EEA | Norway (member of EEA, fully subject to GDPR via EEA-EFTA acquis) |
| Data Protection Officer | _Pending R174 decision per dpo-designation.md — Option A (Robert) vs Option B (outsource) |
| DPO contact email | dpo@preferium.com (alias resolves to current DPO mailbox per dpo-designation.md §6) |
| Lead Supervisory Authority | Datatilsynet (Norwegian Data Protection Authority — datatilsynet.no) |
| Representative inside the EU | Not required — Preferium AS is established in EEA |
B. Processing activities (one row per distinct purpose)
| # | Purpose of processing | Categories of data subjects | Categories of personal data | Retention | Lawful basis (Art. 6) | Source |
|---|---|---|---|---|---|---|
| 1 | Serve optimized HTML to AI crawlers on behalf of the Controller | Visitors (AI agents + humans) to Customer’s site | IP address (truncated to /24), User-Agent, request path, optimized HTML payload | 14 days (CF edge logs) / 90 days (ai_crawler_visits) | Art. 6(1)(f) Legitimate interest (operate the Service) | HTTP requests proxied through CF Worker |
| 2 | Crawl Customer’s site to populate pages table | Page authors named in byline/author tags | Names, social handles, biographies if present in <meta> / JSON-LD authored by Customer | Until Customer deletes the page row OR account closure | Art. 6(1)(b) Contract (Customer instructs us to crawl) | Customer’s own published HTML |
| 3 | Generate AI optimizations + store in Postgres | Same as #2 | Same as #2 (we don’t add identifying data; we reword existing copy) | Until Customer deletes the page row OR account closure | Art. 6(1)(b) Contract | AI Gateway → Claude Sonnet 4.6 |
| 4 | Track Customer brand visibility in 4 LLMs (Phase 13) | Customer’s brand mentions in LLM responses | LLM-generated text, citations, sentiment scores. No human data subjects | 2 years (rolling) | Art. 6(1)(b) Contract | OpenAI/Anthropic/Perplexity/Gemini APIs |
| 5 | Tenant sign-up, billing, subscription management | Account owners + invited members | Email, name, password (hashed via Supabase Auth), Stripe customer ID, plan tier, login timestamps | Account lifetime + 5 years (billing — Bokføringsloven) | Art. 6(1)(b) Contract | Dashboard sign-up / Supabase Auth |
| 6 | Operational logging (audit trail of every privileged action) | Tenant users (owner/admin/member) | User ID, action type, IP, User-Agent, request body summary | 24 months (most); 5 years (billing actions) | Art. 6(1)(c) Legal obligation (Bokføringsloven for billing) | API workers — audit_logs |
| 7 | Customer support email correspondence | Tenant users + their nominees | Email, name, content of message | 3 years from last interaction | Art. 6(1)(b) Contract + Art. 6(1)(f) for analytics | post@preferium.com |
| 8 | Outbound webhook delivery + retry log | Tenant users (subjects of audit events) | User ID embedded in webhook payload (mirrors audit_logs.user_id); webhook URL + response codes | 90 days | Art. 6(1)(b) Contract | webhook_deliveries |
| 9 | OAuth token storage (Google Search Console + Analytics) | Tenant user who connected the account | Encrypted (AES-GCM) refresh + access tokens, OAuth scopes, Google email | Until Customer revokes OR account closure | Art. 6(1)(a) Consent (explicit per Google OAuth flow) | oauth_tokens |
| 10 | DSAR (export/delete/rectify) request fulfillment | Data subjects exercising Art. 15-22 rights | Email of requester, request type, response artifact (export ZIP, deletion log) | 3 years from completion | Art. 6(1)(c) Legal obligation | audit_logs (gdpr.export/gdpr.erasure events) |
| 11 | Cost-tracking telemetry (cents-precision per API call) | None (no human data subjects) | Provider name, token counts, cost — no user IDs attached | 13 months rolling | Not personal data — no Art. 6 basis required | AI Gateway analytics + per-route middleware |
| 12 | Consent log (proves opt-in to telemetry / marketing) | Tenant users | User ID, consent type, given/revoked timestamp | 5 years from revocation | Art. 6(1)(c) Legal obligation (proof of consent) | consent_log |
Activities #1, #4, #11 typically don’t process personal data, but the records are kept anyway because lines blur (e.g., IP-derived patterns, brand mentions referencing named individuals).
C. Recipients (sub-processors)
Public list maintained at docs/legal/sub-processors.md and (post-R174 deploy) at trust.preferium.com/sub-processors. Summary:
| Recipient | Service | Hosting region | Transfer mechanism |
|---|---|---|---|
| Cloudflare, Inc. | Workers compute, KV cache, R2 object storage, DNS, AI Gateway | US/EU (data-resident) | EU SCCs + UK IDTA + DPF (where US) |
| Supabase, Inc. | Managed Postgres + Auth (project eu-west-1) | EU (Frankfurt) | No transfer — EU intra-region |
| Anthropic PBC | AI generation (Claude Sonnet 4.6) via AI Gateway | US | EU SCCs (via Cloudflare AI Gateway DPA) |
| OpenAI, LLC | LLM citation tracking (ChatGPT) | US | EU SCCs (direct DPA, see vendor agreements) |
| Google LLC | OAuth + Search Console + Analytics + KG + PageSpeed Insights | US | DPF + EU SCCs (Google Workspace DPA) |
| Perplexity AI, Inc. | LLM citation tracking | US | EU SCCs |
| Stripe Payments Europe Ltd. | Billing + payment processing | EU (Dublin) | No transfer — EU intra-region |
| Resend, Inc. | Transactional + marketing email | US (with EU pop) | EU SCCs |
| DataForSEO LLC | SEO data (keywords, backlinks, SERP) | EU (Vilnius) | No transfer — EU intra-region |
| Better Stack Inc. | Status page + heartbeats | US (with EU pop) | EU SCCs |
| Sentry, Inc. | Application monitoring | US/EU (data-resident) | EU SCCs (EU pop available; enabled per Sentry DPA) |
Sub-processor changes notified per DPA.md §5 — 30 days advance notice + objection-right within 14 days.
D. Transfers to third countries
| Country | Mechanism | Adequacy decision? |
|---|---|---|
| USA | DPF + EU SCCs (Module 2 + Module 3) | Yes — EU-US DPF (2023) |
| UK | UK IDTA + UK addendum to EU SCCs | Yes — UK adequacy (2021) |
International transfers ALL covered by either an EU Commission adequacy decision OR EU/UK standard contractual clauses. Robert reviews adequacy status at each quarterly Art. 30 review.
E. Technical and organizational measures (Art. 32)
Summary — full implementation status in enterprise-readiness.md:
- Encryption in transit: TLS 1.3 minimum (Cloudflare, Supabase, Stripe webhooks all enforce). HSTS preload (R168).
- Encryption at rest: Supabase Postgres AES-256 (Supabase platform default). OAuth tokens AES-GCM-encrypted in Worker memory (key never reaches Postgres — P7/P18).
- Pseudonymization: Tenant data partitioned by tenant_id + RLS isolation. Edge IP truncated to /24 before storage (R157 audit-log spec).
- Access control: Supabase Auth + RLS (multi-tenant
is_member_of()). Role-based: owner/admin/member/sub_user. saas_admin gated separately (R169 MFA scaffold; full enforcement R175+). - Multi-factor authentication: TOTP scaffold shipped R171 (
requireMfamiddleware +MFA_ENFORCEMENT_MODEenv-gated; full enforcement for privileged roles after staging soak). - Single Sign-On: SSO/SAML scaffold shipped R173 (
tenant_sso_configstable + 503 route stubs; samlify wire-up R175+ for Enterprise tier). - Audit logging: Tamper-evident hash chain (P39) — R170 library + R171 wire-up + R172 verification cron + R173 NOT-NULL flip + R174 chain-only write trigger (warn mode default; block flip after staging soak).
- Backups: Supabase Daily Backups (managed) + R2 daily backup (managed) + 7-year Object Lock COMPLIANCE-mode archive of
audit_logs(R166). - DR drill: Runbook shipped R171 (first execution scheduled 2026-08-21 per quarterly cadence).
- Vulnerability scanning: GitHub Advanced Security CodeQL + Dependabot + secret scanning + Dependency Review action (R159/R166).
- Penetration testing: First external pen-test scheduled R174 ($8-15k engagement). Annual cadence thereafter.
- Coordinated vulnerability disclosure: RFC 9116
security.txtpublished R168 +VDP-policy.mddocumented R157. - Incident response: RUNBOOK.md §2 covers prod-incident runbooks. GDPR Art. 33-34 breach-notification process: discovery → 72h DPA-notification + concurrent customer notification per DPA.md §8.
- Data minimization: Edge IP truncation, no raw IPs in
audit_logs, no marketing-tracking analytics on dashboard (CF Web Analytics only — no cookies set). - Right to erasure (Art. 17): DPO-fulfilled on written request (no self-service deletion tab exists). The audit trail is ANONYMIZED, never deleted (the P39 hash chain + the 5-yr legal-retention carve-out require it) — chain-safe re-hashing core
audit/anonymize.ts(R691/R693), exposed atPOST /admin/dsar/users/:userId/anonymize(saas-admin + MFA, behindGDPR_ANONYMIZE_ENABLED). Account/tenant PII is removed via the operator runbookRUNBOOK.md §8.2(DELETE FROM tenants→ the FK cascade in migration 0101 purgesdomain_users/notification_preferences/tenant_members/… ; KV sweep; Stripe cancel; delete theauth.usersrow). ThePOST /admin/dsar/users/:id/anonymizeendpoint now performs the COMPLETE erasure (R926): it anonymizes the audit chain THEN deletes theauth.usersrow, so the migration-0101 FK cascades purge the subject’s account PII (memberships, notification prefs, import jobs, usage logs). DISARMED behindGDPR_ANONYMIZE_ENABLEDuntil the operator validates the destructive path against a Supabase branch. - Right to portability (Art. 20): Dashboard
GET /domains/:id/exports/csv+ JSON export endpoints. DSAR export ZIP for cross-tenant requests. - Right to access (Art. 15): SaaS-admin-fulfilled via
GET /admin/dsar/users/:userId/export(R685, MFA-gated, downloadable JSON bundle). No self-service “My data” tab exists yet.
F. Children’s data (Art. 8)
The Service is B2B; no part of the product is targeted at children under 16. No age-gate at sign-up because account creation is restricted to natural persons acting on behalf of a business. If a Customer publishes children’s data in their HTML, Preferium processes it as instructed by the Customer — the Customer is the data controller and bears Art. 8 responsibilities.
G. High-risk processing flags (Art. 35)
| Risk category | Triggers Art. 35 DPIA? | Notes |
|---|---|---|
| Large-scale processing of special categories | No | We don’t process Art. 9 special categories (health, biometric, etc.) |
| Systematic monitoring of public areas | No | We crawl Customer’s site (not public areas in the GDPR sense — Customer is the controller) |
| Innovative use of new tech (AI generation) | Yes — DPIA done | DPIA on AI optimization pipeline scheduled R175+ (template in docs/legal/dpia-ai-pipeline.md — placeholder, to be drafted) |
H. Change log
| Date | Round | Change |
|---|---|---|
| 2026-05-21 | R174 | Template created. Sub-processor list pulled from docs/legal/sub-processors.md (created same round). DPIA placeholder added. |
| 2026-05-19 | R157 | DPA.md drafted with §9 sub-processor change notification mechanism. This Art. 30 template was the natural follow-up. |
I. Operator notes
Per docs/legal/dpo-designation.md, R174 records the final DPO Option (A: Robert as DPO; B: external service ~€500-2000/mo; C: hybrid). This Art. 30 template assumes Option A as the placeholder — flip the “Data Protection Officer” row in §A once R174 decision lands.
Where this lives in production (R174+):
- Primary canonical:
docs/legal/gdpr-article-30-records.md(this file, version-controlled). - Per-tenant copy: each Customer can request their own Art. 30 record extract — generated from this template + their specific use of the Service (sub-processors they’ve consented to, plan tier, custom integrations).
- Customer-portal section: planned R175+ “Compliance” tab in the dashboard lets a tenant owner download their own Art. 30 PDF + DPA + DPIA + sub-processor list.
When this template is updated, the change MUST be reflected in:
docs/MASTERPLAN.md§13 Enterprise Readiness (cross-cutting)enterprise-readiness.md§C (skill file)dpa-redlines.md(tracker)- This file’s §H change log