Skip to content

DPIA — Chat Attachments (ADR-0043 Phase 1)

  • Status: Accepted (DPO sign-off recorded 2026-05-09)
  • Date: 2026-05-09
  • Reviewer: DPO + external counsel (sign-off lodged with legal-document store)
  • Sign-off required before: ADR-0043 phase 1 GA — closed
  • Regulatory frame: GDPR Art 35 (DPIA) + PDPA TH §39 (Records of Processing Activities)
  • Scope: visitor-uploaded images via the chat widget — NOT admin avatar uploads (covered separately under brand-asset processing)
  • Next review: 2027-05-09 (annual cadence per §6) or sooner on any §6 trigger

DPO to confirm before sign-off. Below is the engineering-supplied factual baseline; legal counsel adjusts language for regulator-facing precision.

  • Visitors of tenant sites embed our widget. From a chat composer they may attach an image (PNG / JPEG / WebP / HEIC), up to 5 MB, max 4 per turn.
  • Image bytes are uploaded over TLS 1.3 to a Cloudflare Worker that validates type via magic-byte sniff, runs an edge-side sensitive-data classifier, and stores them in Cloudflare R2 under a tenant + visitor prefix.
  • Where tenant policy permits and the image is not flagged sensitive, the bytes are also forwarded to Anthropic Claude Haiku 4.5 (vision) for inference. Inference output (text reply) is persisted; the input image is not retained by Anthropic under the Zero Data Retention contract.
  • Tenant agents may view attachments through the admin inbox. Visitors retain the right to view and delete their own uploads from the widget.
  • Geographies: Thailand (primary tenants today), with potential EU + ASEAN visitors. PDPA TH governs all tenant relationships; GDPR governs EU-resident data subjects.
  • Volumes (estimated): engineering to fill in once phase 1 has 30 days of data; baseline guess 10k MAU × 50 KB avg × 50% turn-attachment rate = ~25 GB / month per 10k MAU.
  • Retention: aligned with conversation retention. Default 90 days idle; configurable to plan-defined ceilings (max 7 years for finance retention).
  • Identifiable personal data: visitor cookie ID (pseudonymous), source IP at upload time, image bytes potentially containing names / addresses / faces, filename hash.
  • Special-category data (GDPR Art 9 / PDPA §26): biometric (faces, ID-card photos), health (medical screenshots), occasionally racial/ethnic, religious — all plausibly present given the eKYC and customer-support use cases. We do not solicit it; we cannot prevent visitors from uploading it.
  • Anonymous and identified visitors of tenant websites.
  • Tenant agents (their access events are also processed but covered under their employment / contractor agreement).

See docs/compliance/dpa-template.md for the canonical list. Reproduced here for DPIA self-containment.

Processor Purpose Data Region
Cloudflare R2 object storage image bytes + metadata Singapore (APAC)
Cloudflare Workers AI sensitive-data classifier image bytes (transient) global edge
Anthropic vision inference image bytes + text US-WEST (EU optional)
Cohere text reranker text only US
Sentry error monitoring metadata only (URL + bytes scrubbed via beforeSend) EU + US
  • PDPA §24(1) consent — explicit, recorded per visitor, surfaced as a modal on first attachment. Stored in consents.attachment_upload.
  • PDPA §26 sensitive-category data — we do not rely on consent alone. The sensitive-data classifier triggers either warning (visitor accepts the risk) or hard block (tenant policy block). Where blocked, no processing occurs; where warned and accepted, processing proceeds on §24(1) consent + §26 implicit acknowledgement via the same modal.
  • GDPR Art 6(1)(a) consent — same modal serves the EU baseline.
  • GDPR Art 9(2)(a) explicit consent — special-category data; same modal (text in modal explicitly mentions sensitive data risk).
  • GDPR Art 6(1)(b) contract performance — for tenant-agent reads of attachments to fulfil the support contract.
  • Without attachments, support flows requiring visual context (eKYC errors, payment screenshots, error captures) require out-of-band channels that fragment audit trail and increase total PII surface.
  • AI vision specifically: removes the descriptive round-trip (“can you describe what you see”), reducing total processing time and visitor cognitive load.
  • Smallest viable per-turn cap (4 images, 5 MB) chosen to minimise stored bytes.
  • Tenant-side opt-out for AI vision keeps the in-flight processing minimal where sensitivity is high.
  • Sensitive-data classifier runs at the edge before any third-party processing — ensures the proportionality test fails closed.
# Risk Likelihood Impact Mitigation Residual
R1 Visitor uploads ID card; bytes leak via Anthropic-side abuse-monitoring retention Low (ZDR addendum signed 2026-05-09 — Anthropic does not retain input bytes beyond inference) High (sensitive PII) (a) ZDR contract removes the 30-day default retention on Anthropic side. (b) Sensitive-data classifier still routes ID-card images agent-only, bypassing vision entirely — defence in depth. Low
R2 Cross-tenant access via guessed URL Low High Visitor-cookie auth gate on /uploads/[...path] for attachments/ prefix; cross-visitor Playwright test Low
R3 Sub-processor breach (R2 / Anthropic) leaks visitor uploads Low Critical Encryption at rest, contracted breach SLA, 72-hour notification process; offline runbook in docs/security/runbooks/attachment-breach.md Low
R4 Filename PII leak (e.g., passport_2026.jpg → audit logs / Sentry) Medium without mitigation / Low with Medium Filename hashed before D1 write, sanitised display name shown to agent, audit logs hold only the hash Low
R5 Model inversion attack on vision answer reveals input image content Low (Haiku 4.5 vision is short-context, not memorising) Medium ZDR contract; no fine-tune on customer data; vision input not persisted by Anthropic Low
R6 Account takeover (ATO) of agent → bulk attachment download Low High MFA enforced for agent accounts (ADR pending — TODO); rate-limit on /uploads/ reads per agent session; anomaly alerts Open — depends on MFA ADR
R7 Adversarial visitor bypasses sensitive-data classifier Medium Medium Defence-in-depth: per-tenant block mode is the ultimate gate; agent inbox review for warn mode; tenant SLA on agent review surface Medium-Low
R8 Right-to-erasure incomplete (residual bytes in CDN / Anthropic / backups) Medium without process / Low with High Cascading erasure documented in ADR-0043; CDN cache TTL 5 min for attachments; Anthropic ZDR means no Anthropic-side residue; CF R2 versioning disabled to prevent shadow copies Low
R9 Cross-border data transfer challenged under PDPA §28 Low (with SCCs) Medium DPA includes SCCs; Singapore (R2 APAC) and US (Anthropic) covered; per-tenant residency hint disclosed in admin UI Low
R10 Visitor consent invalid (coerced / unaware / minor) Low Medium Modal text plain-language TH/EN, requires explicit click, recorded with timestamp + IP + UA; ages: out of scope (we do not target minors but cannot verify); tenant must declare audience age in DPA Medium
  • Engineering: ADR-0043 author (this file accompanies it)
  • Security: review completed; pen-test scope updated to include attachment endpoint (next quarterly cycle)
  • DPO: sign-off recorded 2026-05-09 — addendum + this DPIA filed in legal-document store
  • Counsel: review completed 2026-05-09 — R10 (minors) explicitly addressed in DPA template §7 Controller responsibilities; SCC clauses confirmed in §12

ADR-0043 phase 1 is cleared for GA. Residual risk profile signed off:

  • Low: R1 (ZDR signed 2026-05-09 closes the Anthropic-side retention residual; classifier still routes sensitive uploads agent-only), R2 (cross-tenant URL guess), R3 (sub-processor breach — incident response runbook in place), R4 (filename PII — hashing + tombstone redaction), R5 (model inversion), R8 (right-to-erasure cascade), R9 (cross-border SCCs).
  • Medium-Low: R7 (adversarial classifier bypass — defence in depth via block policy mode + agent inbox review).
  • Open residuals — accepted with mitigations:
    • R6 (agent ATO leading to bulk download). MFA enforcement is the gate; tracked as a separate ADR (TBC). Until landed, mitigated by per-agent rate-limit on /uploads/ reads (30 req/10min) and anomaly alerts on unusual access patterns.
    • R10 (consent validity — minors / coerced consent). Inherent limit of any user-input system. Mitigated by plain-language consent modal (TH/EN), recorded with timestamp + IP + UA, and the controller’s contractual warranty in DPA §7 that they’ve declared their audience age band.

Conditions of acceptance:

  1. Quarterly review of audit logs for R7-style bypass patterns (DPO + security).
  2. R6 follow-up ADR scheduled within 90 days; until shipped, the per-agent rate-limit is non-removable.
  3. Annual DPIA review (next: 2027-05-09) or sooner on any §6 trigger.
  • Initial review at GA, then every 12 months.
  • Triggered review on: change in sub-processor, change in lawful basis, change in scope (e.g., phase 2 documents), change in retention.

Addendum B — Voice notes on channels (ADR-0207, 2026-09-18)

Section titled “Addendum B — Voice notes on channels (ADR-0207, 2026-09-18)”
  • Status: Proposed — DPO review requested; a §6 scope trigger (“change in scope”). The feature ships behind a tenant switch (attachments.aiVoice, default on) so a tenant whose DPO has not reviewed it can turn it off in Settings before any voice note is processed.

Visitors on LINE, Messenger, Instagram, WhatsApp and Telegram send voice messages (≤ 60 s, ≤ 5 MB). The audio is fetched from the platform, transcribed by Cloudflare Workers AI (@cf/openai/whisper-large-v3-turbo, in-network — no new sub-processor), stored under the same attachments/{tenant}/{workspace}/{visitor}/ prefix as images, and the transcript is answered exactly as a typed message. Not in scope: the web widget (no microphone yet), video.

A voice recording is identifiable by nature (voiceprint) and may contain anything the visitor says — names, addresses, health details. Treated as at least as sensitive as an image (PDPA §26 biometric adjacency): stored encrypted at rest, served only to the visitor (header-gated) and tenant members, never sent to Anthropic (only the transcript text enters the LLM turn, under the existing text rules — hashed in query_log, retained per plan).

Consent is implicit in the act of sending a voice message on a channel the tenant operates (same basis as text). The assistant quotes what it heard (🎤 "…") at the top of its reply so the visitor can spot a mis-transcription; the inbox shows the player and the transcript to agents.

Identical to images: visitor_attachments index → per-visitor erasure (ADR-0056) and tenant erasure (ADR-0055) delete the object; retention cron applies. Region: R2 APAC; Workers AI inference is transient at the edge and retains nothing.

# Risk Likelihood Impact Mitigation Residual
R11 Mis-transcription answers the wrong question or captures wrong contact data Medium Low–Medium Echo line; contact capture still confirms with the visitor; agents see audio + transcript Low
R12 Transcript smuggles prompt injection Low Medium Transcript is untrusted user input — sanitizer + injection patterns run as for text Low
R13 Runaway Workers AI spend from bulk voice Low Low Per-visitor turn rate limit + per-tenant daily minutes budget (default 300 min) Low
R14 Voice of a minor / third party recorded without their knowledge Low Medium Same posture as R10; tenant audience declaration in DPA Medium
  • DPIA: Data Protection Impact Assessment (GDPR Art 35)
  • RoPA: Records of Processing Activities (PDPA §39, GDPR Art 30)
  • ZDR: Zero Data Retention — Anthropic contract addendum disabling default 30-day input retention
  • SCC: Standard Contractual Clauses — EU mechanism for cross-border data transfers; PDPA §28 accepts equivalent contractual safeguards