Przejdź do treści
juz-ide.pl blog
Wróć

PII jako wartość, nie jako string

Paweł G.
3 min czytania
PII jako wartość, nie jako string
Temat Technologia gdpr-saga

Email to dla większości programistów kawałek tekstu — przechowujesz go jak numer telefonu, nazwę ulicy, dowolny inny napis. To działa. I jest dokładnie tak bezpieczne, jak trzymanie dokumentów tożsamości mieszkańców Starachowic w niezamkniętej szufladzie.

Kontekst: buduję coś o prawdziwych ludziach

juz-ide.pl to nie abstrakcyjna platforma. To aplikacja o mieszkańcach konkretnych dzielnic Starachowic — z adresami zamieszkania, numerami telefonów, historiami weryfikacji. Te dane są wrażliwe, i RODO mówi: musisz wiedzieć, gdzie one są i co z nimi robisz.

Na początku podchodziłem do tego jak do checklist: szyfruj, anonimizuj, loguj dostęp. Zrobiłem to i miałem poczucie, że „jestem zgodny”.

Sierpień 2025 zmienił to podejście. Zamiast traktować RODO jako wymaganie bezpieczeństwa na zewnątrz kodu, zacząłem je wbudowywać w strukturę kodu.

Dane osobowe jako typy domenowe

Zamiast email: stringemail: Email. Zamiast phone: stringphone: Phone. Zamiast address: stringaddress: ResidenceAddress.

Te obiekty wartości (z biblioteki vytches-ddd) wiedzą, że są danymi osobowymi:

  • Walidacja jest wbudowana — nie można stworzyć Email z nieprawidłowym adresem.
  • Można je zamaskować do logów automatycznie (jan.k***@gmail.com).
  • Zdarzenia domenowe segregują dane osobowe — zdarzenia systemowe nie zawierają PII, zdarzenia RODO-specyficzne są wyraźnie oznaczone.

Konkretna korzyść: kiedy infrastruktura logów dostaje obiekt wartości PII, wie, że go maskuje. Nie muszę pamiętać o tym w każdym miejscu.

Zdarzenia domenowe i RODO

Przy rejestrowaniu zdarzeń domenowych (co się stało w systemie) pojawia się problem: jak dużo danych osobowych zapisujesz w zdarzeniu?

W sierpniu 2025 wdrożyłem podejście: zdarzenia systemowe mają dwa poziomy. Pierwsza warstwa zawiera minimum — identyfikatory, nie dane osobowe. Zdarzenia RODO-specyficzne (logi audytu, historia weryfikacji adresu) są oddzielne, z wyraźnym przeznaczeniem i innym cyklem życia.

Kiedy kiedyś przyjdzie żądanie „usuń moje dane” (RODO Art. 17), te dwa poziomy będą kluczowe. Dane osobowe wiadomo gdzie są — bo architektura je oddziela.

RODO jako projektant

Normalnie RODO kojarzy się z wymaganiami „do spełnienia”. Tu odkryłem coś odwrotnego: gdy zacząłem traktować RODO jako ograniczenie projektowe („gdzie te dane być NIE powinny?”), kod stał się lepszy.

Pytanie „czy ta dana może tu dotrzeć?” zamiast „czy ta dana jest bezpieczna” — to zmiana perspektywy. Jedno pyta o bezpieczeństwo po fakcie, drugie o architekturę przed faktem.

Budując system dla mieszkańców małego polskiego miasta — i wiedząc, że za rok może to obsługiwać prawdziwe dane adresowe — wybrałem drugą perspektywę. Nawet jeśli na dziś jedynym użytkownikiem jestem ja sam w trybie testowym.

PII Value Objects — podejście techniczne

Obiekty wartości z danymi osobowymi rozszerzają BaseValueObject<T> z biblioteki vytches-ddd — tak jak każdy inny obiekt wartości w systemie. Nie ma osobnej hierarchii klas dla PII. Różnica jest gdzie indziej: tam, gdzie maskowanie ma sens w logach (np. numer telefonu), VO implementuje metodę maskującą wprost. Nie dziedziczoną — świadomą decyzję na poziomie tego konkretnego typu.

Segregacja zdarzeń: zdarzenia systemowe nie zawierają PII w payload’zie — tylko identyfikatory. Zdarzenia RODO-specyficzne (ślady audytu, historia weryfikacji adresu) żyją osobno, z innym cyklem życia i odrębną kolejką.



Poprzedni wpis
Siedemdziesiąt procent kodu do wyrzucenia
Następny wpis
Autoryzacja, która nie pyta o rolę