* docs(privacy): state the two local values PostHog actually stores
Verified in production after Support went live: PostHog's conversations
module writes ph_conv_<token> = {"widgetSessionId": uuid} to
localStorage at PAGE LOAD, before the user contacts support at all, and
it bypasses persistence: 'memory' exactly like surveys' seenSurvey_
flags do.
The privacy page claimed enkäter were the only thing stored locally.
That became wrong the moment Support was enabled, so it now names both
values and what they are for.
The substance is unchanged: both are functional UI state with no
personuppgifter (do-not-ask-again, and find-my-own-ticket in this
browser), no cookies are set, and no analytics data is stored on the
device, so the no-consent-banner position still holds. Only the claim
needed to match reality.
Lesson recorded in DECISIONS.md: enabling any new PostHog product can
silently add device storage, so check localStorage in prod after each
one rather than trusting the persistence setting.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(compliance): inventory the client-side storage keys
Closes the ISO 27001 A.5.9 finding from the compliance swarm on #1242:
the two device-side keys were described in prose but were not enumerated
anywhere that a future change would be checked against.
Lists both application keys and both PostHog keys, what each contains,
why neither PostHog key is personal data (which is what makes the
strictly-necessary assessment hold), and why purge-legacy-storage
deliberately leaves them alone.
Adds the review trigger that would have caught this earlier: enabling a
new PostHog product can silently add storage, because the products write
to localStorage directly rather than through the SDK persistence setting.
The Support product was found in prod, not in review.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
608 lines
24 KiB
YAML
608 lines
24 KiB
YAML
# Record of Processing Activities (GDPR Art. 30)
|
|
#
|
|
# Each entry documents one processing activity. Field shape follows EDPB
|
|
# Guidelines 9/2022 §3 (controller-side RoPA): purposes, lawful basis,
|
|
# data subject + data category, recipients, transfer mechanism, retention,
|
|
# security measures. Add an entry whenever a new flow ships that touches
|
|
# personal data: onboarding, integrations, support, or regulator filings.
|
|
|
|
processing_activities:
|
|
|
|
- id: invoices.delivery_history
|
|
name: Leveranshistorik för kundfakturor
|
|
purpose: >-
|
|
Dokumentera att en kundfaktura skickades, när leveransförsöket skedde,
|
|
vilken mottagardomän som användes och vilken exakt PDF som skickades.
|
|
Dashboardens listvy visar endast maskerade mottagardomäner och
|
|
driftmetadata. Fullständigt meddelandeinnehåll stannar på serversidan.
|
|
lawful_basis: art_6_1_b_and_c
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: supabase_and_resend
|
|
data_subjects:
|
|
- customer_contact
|
|
- company_member
|
|
data_categories:
|
|
- user.contact.email
|
|
- user.communication_content
|
|
- user.activity_timestamp
|
|
- user.document
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
- name: Resend
|
|
country: US
|
|
role: processor
|
|
international_transfers:
|
|
applicable: true
|
|
mechanism: scc_2021_c2p
|
|
note: Resend processes the outbound delivery under SCC Module 2.
|
|
retention:
|
|
duration: through_seventh_calendar_year_after_fiscal_year_end
|
|
basis: bfl_7_kap_and_gdpr_storage_limitation
|
|
stored_in:
|
|
- invoice_deliveries
|
|
- document_attachments
|
|
security_measures:
|
|
- active_company_route_context
|
|
- rls_company_scoped
|
|
- masked_recipient_domains_in_list_api
|
|
- no_message_content_in_browser_list_api
|
|
- exact_sent_pdf_worm_protection
|
|
- metadata_only_immutable_audit_log
|
|
- daily_post_retention_pii_redaction
|
|
- signed_provider_delivery_webhook_only
|
|
- masked_recipient_addresses_in_provider_reason_text
|
|
|
|
- id: customer.private_identity
|
|
name: Personnummer för privatkund
|
|
purpose: >-
|
|
Identifiera en privatkund när företagets avtal, fakturering eller
|
|
kundadministration kräver en entydig identitet. Personnumret får endast
|
|
sparas på kundtypen privatkund och exponeras endast maskerat i API och UI.
|
|
lawful_basis: art_6_1_b
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: supabase
|
|
data_subjects:
|
|
- customer
|
|
data_categories:
|
|
- user.government_id
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor.
|
|
retention:
|
|
duration: customer_relationship_or_7y_if_accounting_record
|
|
basis: contract_and_bfl_7_kap
|
|
stored_in:
|
|
- customers.personal_number
|
|
- retained_invoice_documents_when_required
|
|
security_measures:
|
|
- aes_256_gcm_field_encryption
|
|
- masked_api_and_ui_output_last4_only
|
|
- write_role_required
|
|
- rls_company_scoped
|
|
- no_full_value_read_endpoint
|
|
|
|
- id: agi.submit
|
|
name: AGI inlämning till Skatteverket
|
|
purpose: >-
|
|
Lämna in lagstadgad arbetsgivardeklaration på individnivå (AGI) till
|
|
Skatteverket varje månad (Skatteförfarandelagen 26 kap.). Innefattar
|
|
huvuduppgift (HU) och individuppgifter (IU) per anställd. Skatteverkets
|
|
kvittens sparas i response_data inklusive signeradAv: personnummer för
|
|
den som BankID-signerade inlämningen. Ändamålet är bevis för vem som
|
|
juridiskt undertecknade deklarationen samt behandlingshistorik; BFL
|
|
5 kap. 6 § och BFNAR 2013:2 kap. 8 kräver att räkenskapsinformationen
|
|
bevarar den faktiska ingivaren, medan själva inlämningen styrs av SFL.
|
|
lawful_basis: art_6_1_c # legal obligation
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na # software supplier; Skatteverket is recipient, not processor
|
|
data_subjects:
|
|
- employee
|
|
- company_signatory # firmatecknare/deklarationsombud (BankID-signerare av kvittensen)
|
|
data_categories:
|
|
- user.government_id # personnummer (anställda i IU; signerarens i response_data.signeradAv)
|
|
- user.name
|
|
- user.financial.employment # gross salary, tax withheld, benefits
|
|
- user.financial.tax # avgifter, sjuklönekostnad
|
|
recipients:
|
|
- name: Skatteverket
|
|
country: SE
|
|
role: legal_recipient
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: >-
|
|
Sweden-to-Sweden processor-to-public-authority flow. Adequacy decision
|
|
not applicable; no third-country transfer.
|
|
retention:
|
|
duration: 7y
|
|
basis: bfl_7_kap # BFL 7 kap. 2 §: räkenskapsinformation
|
|
stored_in:
|
|
- agi_declarations.xml_content
|
|
- agi_declarations.individuppgifter
|
|
- agi_declarations.response_data # SKV kvittens incl. signeradAv (signerarens pnr); access via company-membership RLS
|
|
- skatteverket_api_audit_log
|
|
security_measures:
|
|
- encryption_at_rest_supabase
|
|
- rls_company_scoped
|
|
- tls_1_3_to_skatteverket
|
|
- bankid_signing_required_for_filing
|
|
- immutable_audit_log
|
|
- personnummer_at_rest_encryption
|
|
|
|
- id: agi.kontrollera.preflight
|
|
name: AGI pre-flight kontrollera (HU/IU)
|
|
purpose: >-
|
|
Skicka enskild HU eller IU som JSON till Skatteverkets kontrollera-
|
|
ändpunkt (v1.7 §7/§8) för dry-run-validering av felmeddelanden och
|
|
STOPP-/AVVISANDE-status innan ett fullständigt underlag laddas upp.
|
|
Skatteverket lagrar inget från denna kontroll; svaret driver vår UI
|
|
som låter användaren rätta felaktigheter i lönekörningen lokalt.
|
|
lawful_basis: art_6_1_c # legal obligation (ancillary to AGI filing)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na
|
|
data_subjects:
|
|
- employee
|
|
data_categories:
|
|
- user.government_id # personnummer (BetalningsmottagarId)
|
|
- user.financial.employment # gross salary, tax withheld, benefits
|
|
recipients:
|
|
- name: Skatteverket
|
|
country: SE
|
|
role: legal_recipient
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: Sweden-to-Sweden flow; no third-country transfer.
|
|
retention:
|
|
# Skatteverket retains nothing for kontrollera calls. Our outbound
|
|
# audit row in skatteverket_api_audit_log records who-called-what-when
|
|
# but NOT the payload body, minimising at-rest footprint.
|
|
duration: 7y
|
|
basis: bfl_7_kap
|
|
stored_in:
|
|
- skatteverket_api_audit_log
|
|
security_measures:
|
|
- strict_zod_allow_list_input_validation
|
|
- request_size_cap_64kb
|
|
- rbac_company_member_role_check
|
|
- rls_company_scoped
|
|
- tls_1_3_to_skatteverket
|
|
- immutable_audit_log
|
|
- no_payload_body_persisted
|
|
|
|
- id: moms.declaration
|
|
name: Momsdeklaration till Skatteverket
|
|
purpose: >-
|
|
Lämna in lagstadgad momsdeklaration (utkast, lås och signering) till
|
|
Skatteverkets momsdeklaration-API (Mervärdesskattelagen 17 kap. 24 §).
|
|
lawful_basis: art_6_1_c
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na
|
|
data_subjects:
|
|
- business_owner
|
|
data_categories:
|
|
- user.government_id # orgnummer (juridiska personer) eller pnr
|
|
- user.financial.tax # rutor 05-62
|
|
recipients:
|
|
- name: Skatteverket
|
|
country: SE
|
|
role: legal_recipient
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: Sweden-to-Sweden flow; no third-country transfer.
|
|
retention:
|
|
duration: 7y
|
|
basis: bfl_7_kap
|
|
stored_in:
|
|
- extension_data (utkast metadata)
|
|
- skatteverket_api_audit_log
|
|
security_measures:
|
|
- rls_company_scoped
|
|
- tls_1_3_to_skatteverket
|
|
- bankid_signing_required_for_filing
|
|
- immutable_audit_log
|
|
|
|
- id: psd2.cash_account_mirror
|
|
name: PSD2-konton speglas till cash_accounts
|
|
purpose: >-
|
|
När en bank-anslutning via Enable Banking returnerar kontolista efter
|
|
lyckad PSD2-consent kopieras kontometadata (IBAN, valuta, kontonamn,
|
|
external_uid) till cash_accounts så att avstämning, motkontoresolver
|
|
och __PRIMARY_SEK__-sentinel kan rutta verifikat utan att läsa JSONB
|
|
från bank_connections.accounts_data vid varje fråga.
|
|
lawful_basis: art_6_1_b # contract (PSD2 consent + bookkeeping service)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na
|
|
data_subjects:
|
|
- business_owner
|
|
data_categories:
|
|
- user.financial.bank_account # IBAN
|
|
- user.contact # account name (kontotitel)
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor; no third-country transfer.
|
|
retention:
|
|
duration: consent_lifetime
|
|
basis: psd2_consent
|
|
stored_in:
|
|
- cash_accounts
|
|
- bank_connections.accounts_data
|
|
security_measures:
|
|
- rls_company_scoped
|
|
- data_minimization_no_balance_on_callback
|
|
- failure_emitted_to_event_log
|
|
|
|
- id: transactions.counterparty_iban
|
|
name: Motpartens IBAN på transaktioner
|
|
purpose: >-
|
|
Spara motpartens IBAN på transaktionsraden så att own-account-detector
|
|
kan identifiera överföringar mellan företagets egna konton (1930 → 1932
|
|
etc.) och bokföra båda benen automatiskt istället för att felbokföra
|
|
utflödet som extern kostnad. Krävs även för payment-matchning mot
|
|
leverantörsfakturor.
|
|
lawful_basis: art_6_1_b # contract (bookkeeping service)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na
|
|
data_subjects:
|
|
- business_owner
|
|
- counterparty
|
|
data_categories:
|
|
- user.financial.bank_account # counterparty IBAN
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor.
|
|
retention:
|
|
duration: 7y
|
|
basis: bfl_7_kap
|
|
stored_in:
|
|
- transactions.counterparty_iban
|
|
security_measures:
|
|
- rls_company_scoped
|
|
- immutable_after_post
|
|
|
|
- id: skattekonto.drift_alert
|
|
name: Skattekonto-drift via e-post
|
|
purpose: >-
|
|
Underrätta företagets kontaktadress när det cachade Skatteverket-saldot
|
|
avviker från GL 1630 utöver konfigurerad tolerans (> 1 SEK), så
|
|
bokföraren kan granska skattekonto-raderna. E-postmeddelandet
|
|
innehåller ingen finansiell siffra utan en länk till autentiserad
|
|
dashboard; mottagaren valideras mot company_members innan utskick.
|
|
lawful_basis: art_6_1_f # legitimate interest (bookkeeping accuracy)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: resend
|
|
data_subjects:
|
|
- business_owner
|
|
- company_member
|
|
data_categories:
|
|
- user.contact.email
|
|
recipients:
|
|
- name: Resend
|
|
country: US
|
|
role: processor
|
|
international_transfers:
|
|
applicable: true
|
|
mechanism: scc_2021_c2p
|
|
note: >-
|
|
Resend (US): SCC Module 2 (controller-to-processor). Outbound
|
|
payload limited to ett notifieringsmail utan finansiella belopp;
|
|
TIA dokumenterad i .compliance/tia/resend.md.
|
|
retention:
|
|
duration: 30d
|
|
basis: event_log_ttl
|
|
stored_in:
|
|
- event_log
|
|
security_measures:
|
|
- recipient_membership_check_before_send
|
|
- no_financial_figures_in_body
|
|
- tls_to_resend
|
|
- rls_company_scoped
|
|
|
|
- id: ai.inference
|
|
name: AI-inferens (kategorisering + dokumenttolkning) via Amazon Bedrock
|
|
purpose: >-
|
|
Föreslå bokföringskategori för banktransaktioner och tolka/extrahera
|
|
uppladdade underlag (kvitton, leverantörsfakturor) med Anthropic
|
|
Claude-modeller körda i Amazon Bedrock. Endast aktiv när tenanten
|
|
uttryckligen aktiverat AI-funktioner: kärntjänsten (bokföring, fakturor,
|
|
moms, rapporter) fungerar fullt ut utan AI.
|
|
lawful_basis: art_6_1_a # consent: opt-in, AI features off by default
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: aws-bedrock
|
|
data_subjects:
|
|
- business_owner
|
|
- counterparty # namn/belopp på uppladdade underlag
|
|
data_categories:
|
|
- user.financial # transaktionsdata skickad för kategorisering
|
|
- user.document # uppladdade kvitton/fakturor för OCR/extraktion
|
|
recipients:
|
|
- name: Amazon Web Services (Amazon Bedrock)
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: >-
|
|
Inferens körs i AWS-regionen eu-north-1 (Stockholm): ingen överföring
|
|
till tredje land. AWS DPA + SCC + DPF-certifiering finns som
|
|
skyddsmekanism. Prompter lagras ej hos Bedrock efter anropet och används
|
|
ej till modellträning.
|
|
retention:
|
|
duration: none_at_processor
|
|
basis: no_retention_bedrock # prompt not persisted by Bedrock post-inference
|
|
stored_in:
|
|
- ai_usage_tracking # usage metadata only (tokens/cost), no payload body
|
|
security_measures:
|
|
- opt_in_consent_required
|
|
- eu_region_inference_eu_north_1
|
|
- prompts_not_retained_after_inference
|
|
- not_used_for_model_training
|
|
- rls_company_scoped
|
|
- tls_to_bedrock
|
|
|
|
- id: mcp.telemetry
|
|
name: MCP/agent-telemetri i event_log
|
|
purpose: >-
|
|
Varje MCP-verktygsanrop loggar metadata (verktygsnamn, felkod,
|
|
felmeddelande max 500 tecken, latens, aktör, session, frivillig
|
|
distributionskanal-markör, t.ex. 'openclaw' via X-Gnubok-Client-header
|
|
eller ?client=-parameter, sanerad mot allow-list och aldrig använd för
|
|
auktorisation) och varje skill-laddning loggar slug/tier till event_log.
|
|
Syftet är tillförlitlighetsanalys av agentgränssnittet: felfrekvens per
|
|
verktyg, adoption per distributionskanal, korrelation mellan laddade
|
|
skills och efterföljande fel, samt agenters egenrapporterade feedback
|
|
(agent.feedback). Inga verktygsargument eller verktygsresultat
|
|
persisteras.
|
|
lawful_basis: art_6_1_f # legitimate interest (service reliability/improvement)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: supabase
|
|
data_subjects:
|
|
- business_owner
|
|
data_categories:
|
|
- user.unique_id # userId, actorId (API-nyckel-id), sessionId
|
|
- user.contact # actorLabel (användarvald API-nyckeletikett)
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor; no third-country transfer.
|
|
retention:
|
|
# Differentiated TTL via /api/events/cleanup/cron: mcp.*/agent.*-rader
|
|
# behålls 180 dagar (felfrekvens-trender kräver mer än leveransfönstret);
|
|
# övriga event_log-rader (leveranshändelser) 30 dagar.
|
|
duration: 180d
|
|
basis: legitimate_interest_reliability
|
|
stored_in:
|
|
- event_log
|
|
security_measures:
|
|
- rls_user_scoped_select # event_log SELECT: auth.uid() = user_id
|
|
- service_role_only_writes
|
|
- error_message_truncated_500_chars
|
|
- no_tool_args_or_results_persisted
|
|
|
|
- id: mcp.company_customer_tools
|
|
name: MCP-verktyg för företagsinställningar och kunder
|
|
purpose: >-
|
|
Låta en uttryckligen behörig användare läsa nödvändiga företags- och
|
|
kunduppgifter samt förbereda ändringar för användarens godkännande.
|
|
Verktygssökningen gnubok_search_tools returnerar endast verktygsmetadata
|
|
och JSON-schema, aldrig företags- eller kundposter. Läsresultat begränsas
|
|
till det aktiva företaget och till verktygets dokumenterade fält.
|
|
lawful_basis: art_6_1_b
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: supabase
|
|
data_subjects:
|
|
- business_owner
|
|
- company_member
|
|
- customer
|
|
data_categories:
|
|
- user.name
|
|
- user.contact
|
|
- user.financial.bank_account
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor.
|
|
retention:
|
|
duration: pending_operation_lifecycle
|
|
basis: contract_and_user_approval
|
|
stored_in:
|
|
- pending_operations
|
|
security_measures:
|
|
- api_key_scope_companies_read_or_write
|
|
- api_key_scope_customers_read_or_write
|
|
- active_company_filter_on_every_query
|
|
- rls_company_scoped
|
|
- search_returns_tool_metadata_only
|
|
- writes_staged_for_explicit_user_approval
|
|
- plaintext_personnummer_blocked_from_staging
|
|
|
|
- id: arsredovisning.signature_evidence
|
|
name: Underskriftsbevis för årsredovisning
|
|
purpose: >-
|
|
Bevara vem som undertecknade en låst årsredovisningsversion, i vilken
|
|
roll, med vilken metod och på vilket datum. Bevisreferensen är endast en
|
|
ogenomskinlig identifierare med prefix archive:, document: eller receipt:.
|
|
Den får inte innehålla namn, e-post, personnummer eller fritext.
|
|
lawful_basis: art_6_1_c
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: supabase
|
|
data_subjects:
|
|
- company_signatory
|
|
data_categories:
|
|
- user.name
|
|
- user.professional_role
|
|
- user.activity_timestamp
|
|
recipients:
|
|
- name: Supabase
|
|
country: EU
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: EU-only processor.
|
|
retention:
|
|
duration: 7y
|
|
basis: bfl_7_kap_and_arl_signing_evidence
|
|
stored_in:
|
|
- arsredovisning_signature_requests
|
|
- annual_report_versions
|
|
security_measures:
|
|
- rls_company_scoped
|
|
- service_role_only_signature_transitions
|
|
- version_company_period_and_state_validation
|
|
- signed_rows_immutable
|
|
- structured_opaque_evidence_reference
|
|
- future_and_pre_finalization_dates_rejected
|
|
|
|
- id: arsredovisning.bolagsverket.submit
|
|
name: Digital inlämning av årsredovisning till Bolagsverket
|
|
purpose: >-
|
|
Lämna in årsredovisningen (iXBRL) digitalt till Bolagsverkets eget
|
|
utrymme (ÅRL 8 kap.). Avsändarens och undertecknarens personnummer
|
|
krävs av Bolagsverkets API (skapa-inlamningtoken, lamna-in) och
|
|
används endast transient i anropen. Varken personnummer eller hash av
|
|
personnummer sparas i inlämningsposten. Fastställelseintyget signeras
|
|
med e-legitimation hos Bolagsverket, aldrig i appen.
|
|
lawful_basis: art_6_1_c # legal obligation (ÅRL filing duty)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: anthropic-na # software supplier; Bolagsverket is recipient, not processor
|
|
data_subjects:
|
|
- business_owner # avsändare/undertecknare (styrelseledamot, VD)
|
|
data_categories:
|
|
- user.government_id # personnummer, endast transient till Bolagsverket
|
|
- user.name # undertecknarens namn
|
|
- user.contact # undertecknarens/kvittens e-post
|
|
- user.financial # årsredovisningens finansiella innehåll
|
|
recipients:
|
|
- name: Bolagsverket
|
|
country: SE
|
|
role: legal_recipient
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: Sweden-to-Sweden flow to a public authority; no third-country transfer.
|
|
retention:
|
|
duration: 7y
|
|
basis: bfl_7_kap # filed .xhtml archived as räkenskapsinformation
|
|
stored_in:
|
|
- arsredovisning_submissions # status, idnummer and checksums, no PNR values or hashes
|
|
- document_attachments # the exact filed iXBRL bytes (WORM)
|
|
security_measures:
|
|
- mtls_client_certificate_to_bolagsverket
|
|
- mtls_key_env_only_injected_from_secret_manager # never in settings/DB; see .env.example custody note
|
|
- pinned_endpoint_allowlist_per_environment # HOSTS map in client.ts; not env-configurable
|
|
- personnummer_and_hash_never_persisted
|
|
- personnummer_never_logged
|
|
- webhook_secret_constant_time_validation
|
|
- rls_company_scoped
|
|
- immutable_status_machine_trigger
|
|
|
|
- id: product.analytics
|
|
name: Produktanalys, sessionsinspelning, felrapportering, enkäter och supportärenden (PostHog)
|
|
purpose: >-
|
|
Förstå hur tjänsten faktiskt används (var användare fastnar i
|
|
onboarding, vilka flöden som avbryts), fånga klientfel och serverfel så
|
|
de kan åtgärdas, och ställa riktade produktfrågor. Endast hostad drift:
|
|
self-hosted-installationer laddar aldrig PostHog (isAnalyticsEnabled()
|
|
kortsluter på NEXT_PUBLIC_SELF_HOSTED, och ingen token bakas in i
|
|
Docker-imagen). Sandbox-/demoföretag identifieras aldrig.
|
|
lawful_basis: art_6_1_f # legitimate interest (produktförbättring och felsökning)
|
|
special_category_basis: null
|
|
controller: gnubok-tenant
|
|
processor: posthog-eu
|
|
data_subjects:
|
|
- business_owner
|
|
- company_member
|
|
data_categories:
|
|
- user.contact.email # person property via identify(), aldrig i event-properties
|
|
- user.name # profiles.full_name
|
|
- user.behavior # sidvisningar, klick, händelser, sessionsinspelning
|
|
- user.device # user agent, skärmstorlek, IP (trunkeras av PostHog)
|
|
# Supportärenden: fritext som användaren SJÄLV skriver till supporten via
|
|
# in-app-dialogen (components/ui/support-link.tsx). Till skillnad från
|
|
# analysdata bär ärendet meddelandetexten, eftersom det är hela poängen
|
|
# med att skriva till supporten. Kan i praktiken innehålla bokförings-
|
|
# detaljer som användaren väljer att beskriva. Widgeten är avstängd:
|
|
# endast vår egen dialog kan öppna ärenden.
|
|
- user.content.support # fritext i supportmeddelanden, användarinitierat
|
|
# EJ organisationsnummer: för enskild firma ÄR orgnr innehavarens
|
|
# personnummer. buildGroupProperties() vägrar skicka det och ett
|
|
# enhetstest låser fast beteendet.
|
|
recipients:
|
|
- name: PostHog
|
|
country: DE
|
|
role: processor
|
|
international_transfers:
|
|
applicable: false
|
|
mechanism: null
|
|
note: >-
|
|
PostHog Cloud EU (Frankfurt). EU-baserat biträde; ingen
|
|
tredjelandsöverföring. DPA tecknat; SCCs gäller för eventuella
|
|
underbiträden utanför EES.
|
|
retention:
|
|
duration: posthog_project_retention
|
|
basis: processor_configured # sätts i PostHog-projektet, ej i denna kodbas
|
|
stored_in:
|
|
- posthog_eu # externt hos biträdet; inget lagras i vår databas
|
|
security_measures:
|
|
- session_replay_masks_all_text # maskTextSelector '*' utöver maskAllInputs
|
|
- session_replay_masks_all_inputs
|
|
- org_number_never_transmitted # låst av test i lib/analytics/__tests__
|
|
- no_pii_in_event_properties # PII endast som person properties via identify()
|
|
# persistence: 'memory' -> ingen analysdata och inga kakor på enheten.
|
|
# TVÅ undantag, båda funktionell UI-state utan personuppgifter, båda
|
|
# skrivna direkt till localStorage av PostHogs egna moduler förbi
|
|
# persistence-inställningen: seenSurvey_<id> ("visa inte igen") och
|
|
# ph_conv_<token> = {"widgetSessionId": uuid} (hitta tillbaka till sitt
|
|
# eget ärende i samma webbläsare). ph_conv skapas vid sidladdning, alltså
|
|
# innan användaren faktiskt kontaktar supporten. Verifierat i prod.
|
|
- no_analytics_data_or_cookies_on_device
|
|
- only_functional_ui_state_persisted # seenSurvey_*, ph_conv_* (uuid, ingen PII)
|
|
- same_origin_reverse_proxy # /rl-rewrite; ingen tredjepartsvärd i CSP
|
|
- sandbox_companies_never_identified
|
|
- disabled_entirely_when_self_hosted
|
|
- server_side_payloads_redacted_before_send # lib/observability/redact.ts
|
|
- support_widget_disabled # endast egen UI via conversations-API
|
|
- 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
|