W systemie wielodostępnym izolacja klientów nie jest właściwością tabeli z kolumną tenant_id. Jest niezmiennikiem całej ścieżki: od ustalenia tożsamości, przez decyzję o dostępie, aż po cache, wyszukiwarkę, eksport i zadania asynchroniczne.

Przykład fikcyjny. API poprawnie filtruje bazę po identyfikatorze klienta, lecz wspólny cache zapisuje raport pod kluczem złożonym wyłącznie z lokalnego numeru raportu. Dwaj klienci mogą mieć raport numer 42. Pierwsze wywołanie wypełnia cache; drugie dostaje cudzy wynik. Baza nie zawiodła. Granica izolacji skończyła się przed cache.

Najpierw ustal kontekst

Tożsamość użytkownika i tożsamość organizacji to dwie różne rzeczy. Użytkownik może należeć do kilku organizacji, a rola „administrator” zwykle ma sens dopiero w obrębie konkretnego klienta. Kontekst klienta powinien pochodzić z zaufanego mechanizmu i być związany z żądaniem lub zadaniem. Parametr przesłany przez przeglądarkę nie staje się prawdą tylko dlatego, że ma poprawny format.

Przenieś granicę przez całą ścieżkę

  1. Autoryzacja: sprawdzaj prawo do konkretnej operacji i zasobu, nie tylko poprawność tokenu na bramie. Domyślną odpowiedzią dla nieznanej kombinacji klient–zasób powinno być „nie”.
  2. Dane: każda ścieżka zapisu i odczytu musi stosować ten sam zakres klienta. Ochrona w repozytorium danych, widoku albo polityce wierszy może być drugą barierą, ale nie usprawiedliwia braku kontroli w aplikacji.
  3. Cache i wyszukiwanie: identyfikator klienta należy do przestrzeni klucza, indeksu lub filtra. Trzeba również zaplanować unieważnianie po zmianie uprawnień.
  4. Asynchroniczność: komunikat i zadanie eksportu muszą nieść jawny, zweryfikowany kontekst. Worker nie powinien go zgadywać z nazwy pliku czy ostatnio obsłużonego żądania.
  5. Obserwowalność: loguj decyzję i identyfikatory techniczne w sposób umożliwiający audyt, ale bez kopiowania danych klienta do wspólnego logu.

Jak to sprawdzić

Zbuduj testy z co najmniej dwoma klientami mającymi takie same lokalne identyfikatory. Uruchom odczyt po rozgrzaniu cache, eksport, wyszukiwanie, zmianę roli i przetworzenie wiadomości po opóźnieniu. Test pozytywny mówi, że klient A widzi swoje dane. Ważniejszy test negatywny dowodzi, że A nie potrafi odczytać, zmienić ani pośrednio wywnioskować danych B.

Osobna baza dla każdego klienta daje mocniejszą granicę, lecz zwiększa koszt operacji, migracji i raportowania. Wspólny magazyn może być rozsądną decyzją, jeśli kontrola zakresu jest centralna, wymuszana i stale testowana. „Programiści będą pamiętać” nie jest mechanizmem izolacji. Jest prośbą skierowaną do przyszłego incydentu.

Pytanie do projektu: gdzie dokładnie powstaje zaufany kontekst klienta i w których elementach ścieżki można go dziś zgubić albo zastąpić?

Materiały uzupełniające: AWS Well-Architected SaaS Lens: Tenant isolation; OWASP Authorization Cheat Sheet. Przykład jest fikcyjny; zalecenia są syntezą praktyk projektowych.