feat(whatsapp-inbox): GDPR retention cron and RoPA entry (#1341)
PR5b, the final code piece of the WhatsApp intake track. A daily cron (04:15) enforces the channel's retention table; the receipt itself stays 7-year WORM under BFL and is never touched. Retention actions (lib/retention.ts, each isolated and idempotent): - whatsapp_messages transcripts past 90 days: body_text + raw_payload cleared in id batches under a wall-clock budget; the row skeleton (wamid, direction, timestamps, status, inbox_item_id) survives for audit. Only rows still carrying content match. - Rows with phone_link_id IS NULL (unknown senders, orphans) past 30 days: deleted. - Link codes expired more than 24h ago: deleted, used or not. - Sender rate counters idle 2+ days: deleted (minute/day window keys are dead weight after that). - Links revoked 90+ days ago: phone_enc crypto-shredded to '' (column is NOT NULL), one-shot via neq guard; phone_hash and phone_masked kept for uniqueness history and audit display. Route mirrors the sweep cron exactly: withCronContext + registry gate (503 EXTENSION_DISABLED when the extension is off). vercel.json gets the schedule and both Docker crontabs are regenerated. Compliance: new whatsapp.receipt_intake activity in .compliance/ropa.yaml covering purpose, Art 6(1)(b)/(c)/(f) bases with the Art 14(5)(b) note for third-party attendee names, Meta Platforms Ireland as processor (Cloud API, EU SCC addendum, Local Storage region DE), the differentiated retention table, and security measures. Co-authored-by: Jakob Wennberg <jakob.wennberg@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Jakob Wennberg
Claude Fable 5
parent
629069e281
commit
bf5ca2c615
@@ -662,3 +662,93 @@ processing_activities:
|
||||
- support_ticket_identity_hmac_signed # POSTHOG_SECRET_API_KEY, serverside
|
||||
- support_message_body_never_in_event_properties # breadcrumb bär endast subject
|
||||
- email_remains_the_delivery_guarantee # ärendet är ett komplement, ej leveransväg
|
||||
|
||||
- id: whatsapp.receipt_intake
|
||||
name: Kvittoinlämning och klargörande dialog via WhatsApp
|
||||
purpose: >-
|
||||
Ta emot kvitton som foto eller PDF skickade till Accounteds delade
|
||||
WhatsApp-nummer och landa dem i dokumentinkorgen (Underlag) som
|
||||
räkenskapsinformation, samt föra en kort klargörande dialog i samma
|
||||
chatt: bekräfta mottagning, fråga vilket företag underlaget tillhör och
|
||||
samla in de representationsuppgifter Skatteverket kräver (deltagarnas
|
||||
namn och företag samt syfte). Avsändare är enbart befintliga
|
||||
Accounted-användare som själva knutit sitt nummer med en engångskod;
|
||||
okända nummer får ett enda begränsat standardsvar och behandlas aldrig
|
||||
vidare (ingen AI, ingen mediahämtning, inget innehåll sparas).
|
||||
Deltagarnamn i representationssvar är tredjepartsuppgifter som samlas
|
||||
in från användaren, inte från de registrerade själva; individuell
|
||||
information till varje deltagare vore oproportionerlig i förhållande
|
||||
till den lagstadgade dokumentationsplikten och undantaget i art.
|
||||
14.5 b tillämpas (uppgifterna framgår av verifikationen, som bevaras
|
||||
enligt BFL).
|
||||
# art 6.1 b: tjänsten (mottagning, dialog, inkorgsleverans).
|
||||
# art 6.1 c: BFL 7 kap: kvittot bevaras 7 år som räkenskapsinformation.
|
||||
# art 6.1 f: tredjeparts deltagarnamn i representationssvar (med
|
||||
# art 14.5 b-undantaget dokumenterat i purpose ovan).
|
||||
lawful_basis: art_6_1_b_c_and_f
|
||||
special_category_basis: null
|
||||
controller: gnubok-tenant
|
||||
processor: supabase_and_meta
|
||||
data_subjects:
|
||||
- business_owner
|
||||
- company_member
|
||||
- representation_attendee # tredjepart: namn + företag i representationssvar
|
||||
data_categories:
|
||||
- user.contact.phone_number # HMAC-hash med peppar + AES-256-GCM + mask; aldrig i klartext i DB
|
||||
- user.communication_content # chattext och rå webhook-payload, 90 dagars retention
|
||||
- user.document # kvittofiler, 7 år WORM enligt BFL 7 kap
|
||||
- user.name # deltagarnamn i representationssvar (tredjepart)
|
||||
- user.activity_timestamp
|
||||
recipients:
|
||||
- name: Meta Platforms Ireland Ltd (WhatsApp Business Platform, Cloud API)
|
||||
country: IE
|
||||
role: processor
|
||||
- name: Supabase
|
||||
country: EU
|
||||
role: processor
|
||||
# AI-tolkningen av kvittobilder och fritextsvar sker via Amazon Bedrock
|
||||
# och täcks av den befintliga aktiviteten ai.inference ovan.
|
||||
international_transfers:
|
||||
applicable: true
|
||||
mechanism: scc_2021_c2p
|
||||
note: >-
|
||||
Meta Platforms Ireland behandlar meddelandena under WhatsApp Business
|
||||
dataskyddsvillkor med EU SCC-addendum (Module 2) för vidareöverföring
|
||||
till Meta Platforms Inc. (US). Cloud API Local Storage är aktiverat
|
||||
med region DE, så meddelandeinnehåll lagras i vila inom EU hos Meta.
|
||||
retention:
|
||||
# Differentierad per datakategori; verkställs dagligen av
|
||||
# /api/extensions/whatsapp-inbox/retention/cron:
|
||||
# chattranskript (body_text, raw_payload) 90 dagar, sedan rensas
|
||||
# innehållet men radskelettet (wamid, riktning, tidsstämplar,
|
||||
# status, inbox-koppling) bevaras som behandlingsspår
|
||||
# okända avsändares rader 30 dagar, sedan radering
|
||||
# engångskoder 24 h efter utgång, radering
|
||||
# telefonkoppling (phone_enc) tills användaren återkallar,
|
||||
# därefter kryptoshredning 90 dagar efter revokering (phone_hash och
|
||||
# phone_masked bevaras för unikhetshistorik respektive visning)
|
||||
# kvittofilen 7 år, WORM (BFL 7 kap),
|
||||
# hanteras av dokumentarkivet, ej av denna cron
|
||||
duration: differentiated_per_data_category
|
||||
basis: gdpr_storage_limitation_and_bfl_7_kap
|
||||
stored_in:
|
||||
- whatsapp_messages
|
||||
- whatsapp_phone_links
|
||||
- whatsapp_link_codes
|
||||
- whatsapp_sender_rate_counters
|
||||
- whatsapp_conversations
|
||||
- invoice_inbox_items.channel_context
|
||||
- document_attachments # kvittofilen, WORM
|
||||
security_measures:
|
||||
- phone_number_hmac_peppered_hash_lookup_only
|
||||
- phone_number_aes_256_gcm_at_rest
|
||||
- phone_number_masked_in_ui
|
||||
- dedicated_whatsapp_key_material_not_bankid_keys
|
||||
- webhook_signature_verified_over_raw_body
|
||||
- service_role_only_tables_rls_no_policies
|
||||
- unknown_senders_no_content_persistence_no_llm
|
||||
- pre_binding_sender_rate_limits
|
||||
- daily_retention_cron_with_crypto_shred
|
||||
- llm_reads_answers_as_untrusted_data_no_tools
|
||||
- receipt_files_worm_protected_bfl
|
||||
- opt_out_stop_keyword_honored
|
||||
|
||||
Reference in New Issue
Block a user