Szkielet modelu wielodostępności ipIII: jak dane wielu banków, partnerów i urzędów miałyby być odseparowane na jednej instancji. Dziś ipIII działa w trybie single-org (LIVE MVP) — jedna organizacja, brak izolacji wielodostępnej. Pełny multi-tenant z Row-Level Security to ROADMAP P1: wymaga migracji schematu DB i ACK operatora. Zgodnie z doktryną claim ≤ proof — poniżej spec, nie deklaracja gotowej funkcji.
Izolacja danych między klientami to warunek wejścia dla banku SIFI, partnera SaaS i urzędu. ipIII ma dziś działającą warstwę evidence (import → incydent → evidence-package → retest → close, z JWT/RBAC/audit na żywej PostgreSQL) — ale w jednym kontekście organizacyjnym. Model poniżej opisuje, jak dołożyć czterowarstwową hierarchię najmu i wymusić scoping w każdym zapytaniu, tak aby żaden tenant nie mógł zobaczyć danych innego.
Czterowarstwowa struktura scopingu. Każdy rekord danych jest kotwiczony do tenant_id; niższe poziomy zawężają widoczność wewnątrz tenanta. Cała tabela = spec docelowa (ROADMAP).
| Poziom | Encja | Rola w izolacji | Przykład | Status |
|---|---|---|---|---|
| 1 — Tenant | tenant |
Najwyższa granica izolacji. Twarda separacja danych między klientami; brak jakiegokolwiek przecieku między tenantami. Klucz scopingu dla RLS. | Bank A · Partner B · Urząd C | ROADMAP P1 |
| 2 — Org | org |
Jednostka organizacyjna wewnątrz tenanta (departament, spółka zależna). Zawęża widoczność, ale nie przekracza granicy tenanta. | Bank A / Pion Cyber · Bank A / Compliance | ROADMAP P1 |
| 3 — Project | project |
Kontener pracy w ramach org (system, aplikacja, obszar audytu). Grupuje engagementy i evidence. | Bankowość internetowa · Aplikacja mobilna | ROADMAP P1 |
| 4 — Engagement | engagement |
Pojedyncze zaangażowanie (pilot, PoC, cykl retestu) w granicach RoE. Najniższy scope, do którego wiążą się findings, incydenty i evidence-package. | PoC purple-team Q3 · Retest po remediacji | ROADMAP P1 |
tenant_id
(a niżej org_id / project_id / engagement_id). Scope pochodzi z tokenu
sesji, nie z parametru żądania sterowanego przez klienta — to eliminuje klasę podatności, w której użytkownik
podstawia cudzy identyfikator, żeby sięgnąć po nieswoje dane. Dziś (single-org) scopingu tenantowego nie ma,
bo istnieje jeden kontekst.
RLS to warstwa obrony w samej bazie: nawet gdy warstwa aplikacyjna pominie filtr, baza nie zwróci wierszy spoza aktywnego tenanta. Poniższy szkielet jest ilustracją docelowej polityki (ROADMAP), nie fragmentem wdrożonego kodu.
-- SPEC / ROADMAP (nie wdrożone) — szkic polityki RLS per tenant
ALTER TABLE evidence ENABLE ROW LEVEL SECURITY;
ALTER TABLE incidents ENABLE ROW LEVEL SECURITY;
ALTER TABLE findings ENABLE ROW LEVEL SECURITY;
-- scope pochodzi z sesji (SET app.tenant_id = ... przy uwierzytelnieniu),
-- nie z parametru sterowanego przez klienta
CREATE POLICY tenant_isolation ON evidence
USING (tenant_id = current_setting('app.tenant_id')::uuid);
CREATE POLICY tenant_isolation ON incidents
USING (tenant_id = current_setting('app.tenant_id')::uuid);
-- FORCE RLS = polityka obowiązuje także właściciela tabeli
ALTER TABLE evidence FORCE ROW LEVEL SECURITY;
ALTER TABLE incidents FORCE ROW LEVEL SECURITY;
tenant_id do istniejących tabel,
backfillu danych, przepięcia ścieżki uwierzytelnienia na ustawianie app.tenant_id oraz zestawu
testów regresji. To migracja schematu produkcyjnej bazy — nie zmiana kosmetyczna. Uruchamiana wyłącznie
po ACK operatora i na planie z rollbackiem.
Sama polityka nie wystarczy — trzeba udowodnić, że działa, także w scenariuszach nadużycia. Zestaw testów (spec) obejmuje przypadki pozytywne (tenant widzi swoje) i negatywne (tenant NIE widzi cudzego). Cały zestaw = ROADMAP.
Tenant A odczytuje wyłącznie własne evidence/incydenty. Scope z sesji zwraca komplet swoich rekordów, żaden nie ginie.
ROADMAP
Tenant A podstawia identyfikator rekordu należącego do Tenanta B (bezpośrednie odwołanie do obiektu). Oczekiwany wynik: brak dostępu (404/403), zero wierszy z RLS.
ROADMAP
Autoryzowany użytkownik Tenanta A próbuje operacji na obiekcie poza swoim scope (broken object-level authorization). Oczekiwany wynik: odmowa na poziomie polityki, nie tylko UI.
ROADMAP
Użytkownik org/project próbuje sięgnąć do engagementu spoza swojego poddrzewa w tym samym tenancie. Oczekiwany wynik: zawężenie respektowane.
ROADMAP
Dziś audit-log jest wspólny (single-org). Docelowo (ROADMAP) każdy wpis audytu jest kotwiczony do tenant_id, a dostęp do logów jest scope'owany tak samo jak dane — administrator Tenanta A nie widzi zdarzeń Tenanta B.
Każde zdarzenie (kto, co, kiedy, na jakim rekordzie) nosi tenant_id. Log jest niereużywalny między tenantami.
ROADMAP
Widok audytu respektuje tę samą politykę RLS co dane. Brak globalnego „superwidoku" bez wyraźnej roli platformy i śladu.
ROADMAP
Wpisy audytu tylko dopisywane, z chain-of-custody. Zachowanie integralności śladu (dziś: hash + chain w DB, LIVE MVP).
LIVE MVP / ROADMAP (per-tenant)
Cykl życia danych klienta zgodny z umową powierzenia (DPA) i zasadami RODO (minimalizacja, ograniczenie przechowywania, prawo do usunięcia/przenoszenia). Spec docelowa; realizacja per tenant = ROADMAP.
| Faza | Co obejmuje | Odniesienie | Status |
|---|---|---|---|
| Retencja | Okres przechowywania danych engagementu ustalany per tenant w DPA; po jego upływie dane kwalifikują się do usunięcia. Zasada ograniczenia przechowywania. | RODO art. 5(1)(e); zapisy DPA | ROADMAP P1 |
| Purge | Trwałe usunięcie danych tenanta na żądanie lub po terminie retencji, wraz z evidence i kopiami roboczymi; potwierdzenie usunięcia w audycie (scoped do tenanta). | RODO art. 17 (prawo do usunięcia) | ROADMAP P1 |
| Eksport | Przenoszalny pakiet danych tenanta (evidence-package, incydenty, audit) w formacie strukturalnym; do migracji, offboardingu lub realizacji prawa do przenoszenia. | RODO art. 20 (przenoszalność) | ROADMAP P1 |
Powiązane: rejestr granic dojrzałości → /known-limitations · przetwarzanie danych → /data-processing · gotowość enterprise → /enterprise-readiness.