Przejdź do treści głównej

RODO + program poleceń — 7 rzeczy, które musisz mieć w consent log (2026)

UODO opublikował Plan Kontroli Sektorowych — programy lojalnościowe i e-commerce w centrum uwagi. Yotpo loguje user_id i email. ReferralCandy: data flow opisany niejasno. UODO oczekuje audit trail, nie checkboxa. Siedem pól, gotowy SQL schema i co konkretnie weryfikuje inspektor.

MK
Maciej KowalskiFounder, VibeReferral
22 min czytania15 maj 2026
TL;DR
  • UODO wymaga audit trail — sam checkbox z timestampem nie wystarcza
  • Raw IP w consent log = przetwarzanie danych osobowych bez podstawy (Breyer C-582/14)
  • Granular consent scope jako JSON — jeden bool flag nie spełnia art. 7 ust. 2
  • Consent text versioning — bez tego nie wykażesz, na co dokładnie się zgodził klient
  • Retention 5+ lat — zachodnie SaaSy logują 12-24 mc, za krótko dla PL praktyki

Listopad 2024. UODO publikuje Plan Sektorowych Kontroli na rok 2025 — corocznie aktualizowany dokument wyznaczający priorytety inspekcji. W obszarze szczególnego nadzoru — e-commerce, programy lojalnościowe, profilowanie marketingowe oraz przetwarzanie danych w celu kierowania komunikacji handlowej. Plan na 2026 kontynuuje większość tych obszarów, dokładając kontrole post-PKE compliance.

Marta — właścicielka 8-osobowego DTC z marżą 12% — czyta ten plan w niedzielę wieczór. Kary RODO sięgają do 4% globalnego obrotu rocznego lub 20 milionów EUR. Dla sklepu robiącego 3 miliony PLN obrotu rocznie teoretyczna kara to 120 000 PLN — równowartość sześciu miesięcy operacyjnego runwayu, znikających w jednym piśmie z UODO.

Marta otwiera swój stack. Yotpo — domyślny consent log loguje user_id i email z timestampem, ale nie wersjonuje treści klauzuli, którą użytkownik widział. Klaviyo — hosting w Wirginii, audit trail trzy miesiące. ReferralCandy — data flow opisany w DPA niejasno. Wszystkie obiecują "GDPR-ready" na landing page'u. W drobnym druku — minimum, które może nie wytrzymać kontroli UODO.

Większość zachodnich SaaSów loguje consent w sposób minimalny — wystarczająco, żeby nie naruszyć GDPR formalnie, ale niewystarczająco, żeby przetrwać kontrolę UODO bez paniki.

RODO art. 7 ust. 1 (warunki wyrażenia zgody) brzmi — "Jeżeli przetwarzanie odbywa się na podstawie zgody, administrator musi być w stanie wykazać, że osoba, której dane dotyczą, wyraziła zgodę."

Słowo klucz — wykazać. Nie zebrać. Nie udokumentować ogólnie. Wykazać — to znaczy przedstawić dowód, który wytrzyma weryfikację UODO podczas kontroli. Sam checkbox z timestampem to zebranie. Pełen audit trail z wersją klauzuli, kontekstem zbierania i mechanizmem wycofania to wykazanie.

Recital 32 precyzuje — zgoda musi być dobrowolna, świadoma, konkretna, jednoznaczna. Każdy wymóg ma konsekwencje dla tego, co loguj:

  • Dobrowolna — loguj kontekst zbierania (czy nie była wymuszona np. wymogiem zaakceptowania przed checkout)
  • Świadoma — loguj wersję klauzuli (co dokładnie użytkownik widział)
  • Konkretna — loguj scope (jakie konkretne cele przetwarzania zostały wskazane)
  • Jednoznaczna — loguj mechanizm (active opt-in, nie pre-checked checkbox)

Recital 42 dokłada wymóg wycofywalności — "wycofanie zgody musi być tak proste jak jej wyrażenie". To znaczy że w consent log musisz logować nie tylko moment zgody, ale i moment wycofania.

Te siedem pól to minimalny zestaw, który pozwoli przetrwać kontrolę UODO bez paniki. Nie idealny. Nie premium. Minimalny, który jest wystarczający w oparciu o praktykę 2025-2026.

2.1 User identifier (pseudonimizowany)

Co loguj: unikalny identyfikator osoby. Nie raw email, nie raw IP, nie imię i nazwisko. UUID lub pseudonimowany hash.

Dlaczego: Trybunał Sprawiedliwości UE w sprawie C-582/14 Breyer potwierdził, że dynamiczny adres IP jest danymi osobowymi. Logging surowego IP w consent log = przetwarzanie danych osobowych bez jednoznacznej, oddzielnej podstawy.

Standard polskiej praktyki: SHA-256 hash IP plus daily salt. Hash jest deterministyczny w obrębie dnia, ale nie da się go odwrócić po 24 godzinach.

texthashed_ip = SHA256(raw_ip + daily_salt)

2.2 Timestamp (ISO 8601, z retention policy)

Format ISO 8601 UTC z dokładnością do sekundy. Przykład — 2026-04-14T16:23:47Z. UODO oczekuje udokumentowania kiedy zgoda została wyrażona w sposób, który pozwala odtworzyć kontekst.

Retention policy:

  • Aktywni użytkownicy — okres aktywnego przetwarzania plus okres przedawnienia roszczeń, który ustalasz ze swoim prawnikiem (dla roszczeń związanych z działalnością gospodarczą to zwykle 3 lata, art. 118 KC)
  • Po wycofaniu zgody — dowód zgody trzymasz tak długo, jak długo możesz musieć wykazać jej udzielenie
  • Po deletion request (RODO art. 17) — zachowujemy fakt usunięcia z metadanymi, ale nie samą treść danych

2.3 Consent type (granularnie, jako JSON)

Dokładny zakres zgody jako strukturalny JSON, nie jeden bool flag:

json{  "marketing_email": true,  "marketing_sms": false,  "profiling_behavioral": true,  "profiling_predictive": false,  "referral_program_participation": true,  "third_party_sharing": false}

RODO art. 7 ust. 2 wymaga, żeby zgoda była konkretna. Jeden checkbox "zgadzam się na marketing" nie spełnia wymogu — to "zgoda zbiorcza" odrzucona w wielu interpretacjach UODO.

2.4 Consent text version (history versioning)

Wersja konkretnej treści klauzuli, którą użytkownik widział. Nie reference do "regulaminu" jako abstrakcyjnego dokumentu — referencyjne ID konkretnej wersji.

json{  "consent_version": "consent_v3_2026_01_15",  "consent_url_at_time_of_acceptance": "https://example.pl/regulamin?v=3"}

Po roku użytkownik może wycofać zgodę i zażądać udokumentowania, na co dokładnie się zgodził w styczniu. Jeśli logujesz tylko consent: true, a regulamin zmieniłeś trzy razy — nie masz dowodu, której wersji dotyczyła ta zgoda.

2.5 Source / UI context

json{  "collection_source": "checkout_step_2",  "collection_url": "https://example.pl/checkout?step=consent",  "ui_component": "checkout_consent_modal_v2",  "referrer": "https://example.pl/cart"}

UODO sprawdza czy zgoda była dobrowolna. Zgoda zebrana na checkout (gdzie użytkownik musi zaznaczyć żeby kupić) jest mniej dobrowolna niż w niezależnym pop-upie. Logging source pozwala udokumentować kontekst.

2.6 Withdrawal mechanism (logowane przy wycofaniu)

Recital 42 — wycofanie musi być tak łatwe jak wyrażenie. W praktyce:

  • Jeśli zgoda została wyrażona przez kliknięcie checkboxa w 30 sekund, wycofanie nie może wymagać emaila do supportu
  • Wycofanie powinno być dostępne w panelu użytkownika, jednym klikiem
  • Po wycofaniu natychmiast zatrzymujemy przetwarzanie objęte tą zgodą
json{  "event_type": "consent_withdrawn",  "user_id": "uuid_xxx",  "withdrawn_at": "2026-04-14T16:23:47Z",  "consent_type_withdrawn": "marketing_email",  "withdrawal_method": "user_panel_self_service",  "withdrawal_url": "https://example.pl/panel/preferences",  "previous_consent_id": "uuid_yyy"}

2.7 Audit trail (append-only, immutable)

Każda operacja na consent — append-only. Nigdy nie nadpisuj istniejącego entry. Tabela z UPDATE/DELETE permission to nie audit trail — to log z możliwością manipulacji.

  • INSERT only permission dla aplikacji
  • Hard delete tylko jako reakcja na żądanie usunięcia (RODO art. 17), z osobnym entry dokumentującym operację
  • created_at immutable timestamp od strony bazy (PostgreSQL DEFAULT NOW())
  • Idealnie — cryptographic hash chain (każdy wpis zawiera hash poprzedniego)

Konkretny przykład consent log — SQL schema

sqlCREATE TABLE consent_log (  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),  user_id UUID NOT NULL REFERENCES users(id),  hashed_ip TEXT NOT NULL,  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),  consent_scope JSONB NOT NULL,  consent_version_id UUID NOT NULL REFERENCES consent_versions(id),  collection_source TEXT NOT NULL,  collection_url TEXT NOT NULL,  ui_component TEXT,  referrer TEXT,  event_type TEXT NOT NULL DEFAULT 'consent_granted',  withdrawal_method TEXT,  previous_consent_id UUID REFERENCES consent_log(id));-- Audit trail append-only — brak UPDATE/DELETE policyREVOKE UPDATE, DELETE ON consent_log FROM authenticated;

Co UODO sprawdza w kontroli sektorowej 2026

Pięć konkretnych obszarów w trakcie inspekcji:

  1. 01Rejestr czynności RODO art. 30 — dokumentacja przetwarzania
  2. 02Przykładowy consent log entry — czy zawiera 7 wymaganych pól
  3. 03Klauzula z dnia X — czy potrafisz pokazać dokładnie tę wersję klauzuli, którą widział konkretny użytkownik miesiące temu
  4. 04Procedura withdrawal — self-service vs email do supportu
  5. 05DPA z sub-processorami (Stripe, mailer, hosting) — gdzie dane fizycznie trafiają

Jak sprawdzić to u swojego dostawcy

Zamiast rankingu, który i tak zestarzeje się przy najbliższym release dowolnego narzędzia: weź listę siedmiu pól z tego tekstu i poproś swojego dostawcę o eksport jednego rekordu zgody. To zajmuje jeden mail, a odpowiedź mówi więcej niż każda tabela porównawcza — łącznie z naszą.

U nas rejestr zgód ma te pola od początku: zakres zgody osobno dla każdej kategorii, wersjonowanie treści zgody, zapis wyłącznie przez dopisanie (bez edycji historii), IP jako hash SHA-256 z solą dobową. Dane trzymamy w Unii, w regionie AWS eu-west-1 (Irlandia) — lokalizacja i lista podprocesorów są w umowie powierzenia.

Compliance checklist na koniec

  1. 01Pseudonimowany user_id (UUID, nie raw email)
  2. 02SHA-256 hash IP plus daily salt
  3. 03ISO 8601 UTC timestamp z retention 5+ lat
  4. 04Granular consent scope jako JSONB
  5. 05consent_version_id z linkiem do tabeli consent_versions
  6. 06Source, URL, UI component, referrer
  7. 07Withdrawal event log z previous_consent_id
  8. 08INSERT-only permission na tabeli
  9. 09DPA z każdym sub-processorem
  10. 10Hosting w UE — sprawdź w umowie powierzenia, w którym regionie faktycznie leżą dane

Źródła

Twój następny kanał wzrostu.
Gotowy w 5 minut.

Narzędzie wzrostu zbudowane dla SMB. Bez kodu. Jedna rozmowa z AI.

Zacznij od 14 dni Growth →Umów demo