Bezpieczeństwo i RBAC

RBAC i uprawnienia

Autoryzacja na platformie DataFlow AI jest regulowana przez hierarchiczny model kontroli dostępu opartej na rolach (RBAC). Haczyk: istnieją trzy różne słowniki ról — role realmu Keycloak, hierarchia backendowa DataFlowRole oraz persony frontendu — które muszą być pogodzone przez zakodowane na sztywno tabele mapowania. Ta strona dokumentuje wszystkie trzy, pełne macierze uprawnień, sposób działania egzekwowania oraz znane luki.


Trzy słowniki ról

Pojedynczy człowiek-użytkownik jest opisywany trzema różnymi nazwami ról w zależności od tego, na którą warstwę patrzysz. Zrozumienie mapowania między nimi jest niezbędne do rozumowania o dostępie.

WarstwaSłownikŹródło
Dostawca tożsamościRole realmu Keycloakrealm-export.json
Usługi backendoweHierarchia DataFlowRoleRBACService.kt (moduł common)
SPA frontenduPersony (PersonaId)frontend/src/types/permissions.ts

1. Role realmu Keycloak

Realm dataflow dostarcza sześć ról realmu: org_admin, workspace_admin, developer, analyst, operator oraz viewer. org_admin jest rolą złożoną, która obejmuje pozostałych pięć.

2. Hierarchia backendowa DataFlowRole

RBACService.DataFlowRole definiuje pięć uporządkowanych ról, każdą z numerycznym poziomem:

ADMIN(100) > ENGINEER(75) > ANALYST(50) > STEWARD(40) > VIEWER(25)

Rola przyznaje każde uprawnienie, którego requiredRole.level jest mniejszy lub równy poziomowi roli użytkownika (RBACService.hasPermission).

3. Persony frontendu

SPA modeluje cztery persony (PersonaId): admin, engineer, analyst oraz steward. Każda persona mapuje się na stały zestaw uprawnień oraz listę dozwolonych prefiksów tras.

Słowniki nie pasują do siebie

Keycloak dostarcza developer, operator oraz org_adminnie ma roli realmu STEWARD ani roli realmu ENGINEER. Backend i frontend natomiast oczekują engineer oraz steward. „Steward" w Keycloak może pojawić się tylko poprzez grupę AD (PLK-BI-Stewards) lub nazwę roli data_steward, z których żadna nie znajduje się w dostarczonym eksporcie realmu. Zaszczepiony przykładowy użytkownik „Tomasz Zielinski / Data Steward" faktycznie nosi rolę realmu viewer.


Tabele mapowania

Grupy Keycloak → role realmu

Eksport realmu mapuje cztery grupy w stylu korporacyjnym na role realmu:

GrupaPrzyznawana rola realmu
/PLK-BI-Adminsorg_admin
/PLK-BI-Engineersdeveloper
/PLK-BI-Analystsanalyst
/PLK-BI-Operationsoperator

KeycloakJwtConverter oraz RBACService dodatkowo wiedzą o PLK-BI-Stewards i PLK-BI-Viewers, ale te grupy nie występują w dostarczonym eksporcie realmu.

Zaszczepieni użytkownicy

Nazwa użytkownikaRola realmuGrupaAtrybut stanowiska
anna.kowalska@polkomtel.pldeveloperPLK-BI-EngineersData Engineer
marek.nowak@polkomtel.planalystPLK-BI-AnalystsBusiness Analyst
katarzyna.wisniewski@polkomtel.plorg_adminPLK-BI-AdminsPlatform Admin
tomasz.zielinski@polkomtel.plviewer(brak)Data Steward

Wszyscy czterej zaszczepieni użytkownicy mają puste credentials oraz requiredActions: [UPDATE_PASSWORD].

Dowolna surowa rola → DataFlowRole

Brama mapuje każdy surowy ciąg roli, który zobaczy — role realmu, role klienta, nazwy grup oraz ścieżki grup — na pojedynczy DataFlowRole (RBACService.mapSingleRole / KeycloakJwtConverter). Wygrywa najwyższa zmapowana rola; wartością domyślną jest VIEWER.

Surowa rola / grupaRozwiązany DataFlowRole
PLK-BI-Admins, /PLK-BI-AdminsADMIN
admin, dataflow-admin, org_admin, workspace_admin, platform_adminADMIN
PLK-BI-EngineersENGINEER
engineer, dataflow-engineer, data_engineer, developer, operatorENGINEER
PLK-BI-AnalystsANALYST
analyst, dataflow-analyst, business_analystANALYST
PLK-BI-StewardsSTEWARD
steward, dataflow-steward, data_stewardSTEWARD
PLK-BI-ViewersVIEWER
viewer, dataflow-viewerVIEWER
Nazwy z prefiksem ROLE_*To samo mapowanie po usunięciu prefiksu
Nierozpoznana rolaPomijana — brak niejawnego przyznania (FR-020)

KeycloakJwtConverter.extractAuthorities konwertuje rozwiązaną rolę na uprawnienia Spring ROLE_*. Jeśli JWT nie ma żadnych mapowalnych ról, zestaw uprawnień jest pusty, a żądanie jest odrzucane przez @PreAuthorize — to celowy wybór przeciwdziałający eskalacji uprawnień. Mapowania org_admin / developer / operator zostały dodane późno, aby naprawić sytuację użytkowników, którzy w przeciwnym razie byliby po cichu degradowani do ANALYST lub VIEWER.

Dlaczego wartości domyślne mapowania mają znaczenie

Reguły „najwyższa wygrywa, domyślnie VIEWER, nierozpoznane pomijane" oznaczają, że nieznany ciąg roli nigdy nie eskaluje uprawnień — ale błędnie zapisana oczekiwana rola po cichu degraduje użytkownika. Tabele mapowania są jedynym kruchym punktem godzącym wszystkie trzy słowniki.


Backendowa macierz uprawnień

RBACService definiuje katalog 30 uprawnień, każde oznaczone requiredRole. Ponieważ model jest hierarchiczny, rola otrzymuje uprawnienie, gdy jej poziom jest poziomu wymaganej roli uprawnienia.

Uprawnienia według domeny

DomenaUprawnienie → wymagana rola
PipelineVIEW_PIPELINE→VIEWER; CREATE/EDIT/RUN/SCHEDULE_PIPELINE→ENGINEER; DELETE_PIPELINE→ADMIN
ConnectionVIEW_CONNECTION→VIEWER; CREATE/EDIT/TEST_CONNECTION→ENGINEER; DELETE_CONNECTION→ADMIN
MonitoringVIEW_MONITOR→VIEWER; ACKNOWLEDGE_ALERT→ANALYST; CONFIGURE_ALERT→ENGINEER; DELETE_ALERT→ADMIN
LineageVIEW_LINEAGE→VIEWER; EDIT_LINEAGE→ENGINEER
MigrationVIEW_MIGRATION→VIEWER; CREATE_MIGRATION→ENGINEER; EXECUTE_MIGRATION→ADMIN
AI CopilotUSE_COPILOT→ANALYST; CONFIGURE_COPILOT→ADMIN
WorkspaceVIEW_WORKSPACE→VIEWER; EDIT_WORKSPACE/MANAGE_MEMBERS→ADMIN
Zarządzanie użytkownikamiVIEW_USERS→ANALYST; MANAGE_USERS→ADMIN
AudytVIEW_AUDIT_LOG→ANALYST; EXPORT_AUDIT_LOG→ADMIN
SystemVIEW_SYSTEM_SETTINGS/MODIFY_SYSTEM_SETTINGS→ADMIN

Role × uprawnienia (hierarchicznie)

= przyznane. Poziomy: ADMIN 100, ENGINEER 75, ANALYST 50, STEWARD 40, VIEWER 25.

Poziom uprawnień (wymagana rola)ADMINENGINEERANALYSTSTEWARDVIEWER
VIEW_PIPELINE / VIEW_CONNECTION / VIEW_MONITOR / VIEW_LINEAGE / VIEW_MIGRATION / VIEW_WORKSPACE (VIEWER)
ACKNOWLEDGE_ALERT / USE_COPILOT / VIEW_USERS / VIEW_AUDIT_LOG (ANALYST)
CREATE/EDIT/RUN/SCHEDULE_PIPELINE / CREATE/EDIT/TEST_CONNECTION / CONFIGURE_ALERT / EDIT_LINEAGE / CREATE_MIGRATION (ENGINEER)
DELETE_PIPELINE / DELETE_CONNECTION / DELETE_ALERT / EXECUTE_MIGRATION / CONFIGURE_COPILOT / EDIT_WORKSPACE / MANAGE_MEMBERS / MANAGE_USERS / EXPORT_AUDIT_LOG / VIEW_SYSTEM_SETTINGS / MODIFY_SYSTEM_SETTINGS (ADMIN)

Inwersja hierarchii STEWARD

STEWARD znajduje się na poziomie 40, poniżej ANALYST na poziomie 50. STEWARD dziedziczy zatem tylko hierarchiczne uprawnienia poziomu VIEWER z RBACService. Wszelkie rzeczywiste uprawnienia stewarda pochodzą wyłącznie z kontrolerów, które wyraźnie wymieniają STEWARD na swoich listach @PreAuthorize — a nie z hierarchii ról. Model person frontendu (poniżej) zamiast tego nadaje stewardowi szerokie prawa zarządzania danymi, więc oba modele naprawdę nie zgadzają się co do tego, jak potężny jest steward.

Kontrole uwzględniające workspace

RBACService udostępnia także kontrole o zakresie workspace nałożone na kontrole uprawnień:

  • canAccessWorkspace — ADMIN widzi wszystkie workspace; workspace default jest otwarty dla wszystkich; każdy inny workspace wymaga członkostwa.
  • canModifyPipeline, canDeletePipeline, canRunPipeline — każda ocenia odpowiednie uprawnienie oraz kontrolę workspace.

Frontendowa macierz uprawnień

Frontendowy katalog uprawnień (frontend/src/types/permissions.ts) definiuje 28 uprawnień jako ciągi domain:action obejmujące domeny pipeline, quality, governance, lineage, code, admin, system oraz catalog. (Komentarz nagłówkowy pliku mówi „26"; rzeczywista lista to 28.) Uprawnienia są przypisywane per persona poprzez personaPermissions, a model jest opisany jako wspierany po stronie serwera przez PolicyEngine.kt w metadata-service.

Persona × uprawnienia

= przyznane. Persona admin posiada wszystkie 28 uprawnień.

Uprawnienieengineeranalystadminsteward
pipeline:view
pipeline:create
pipeline:edit
pipeline:run
pipeline:delete
pipeline:deploy
pipeline:debug
quality:view
quality:create
quality:edit
quality:evaluate
governance:policy
governance:review
governance:approve
lineage:view
lineage:edit
code:view
code:review
code:commit
admin:users
admin:workspace
admin:security
admin:infrastructure
admin:billing
system:settings
catalog:view
catalog:edit
catalog:classify

Zwróć uwagę, jak frontendowa persona steward posiada bogate uprawnienia governance:*, quality:*, lineage:edit oraz catalog:* — dokładnie te uprawnienia, których backendowa hierarchia odmawia STEWARD (poziom 40). Ta rozbieżność jest jedną ze znanych luk.


Jak działa egzekwowanie

Autoryzacja jest egzekwowana w dwóch warstwach: brama sprawdza ważność tokenu i obecność roli; każda usługa stosuje drobnoziarniste kontrole na poziomie metody oraz workspace/własności.

 Request ──▶ API Gateway ──▶ Downstream service ──▶ @PreAuthorize ──▶ workspace check
              │                  │                       │
              │ token valid?     │ JWT re-validated      │ method-level
              │ role present?    │ X-User-* → context    │ role/permission
              ▼                  ▼                       ▼
        coarse HTTP rule    SecurityContext        fine-grained grant

Reguły na poziomie bramy

Gdy dev-permit-reads=false, reaktywny SecurityConfig bramy stosuje gruboziarniste reguły oparte na metodzie do /api/v1/**:

Metoda HTTPWymagane uprawnienie
DELETEROLE_ADMIN
POST / PUT / PATCHROLE_ADMIN lub ROLE_ENGINEER
GETROLE_ADMIN, ROLE_ENGINEER, ROLE_ANALYST, ROLE_STEWARD lub ROLE_VIEWER
Każda inna wymianaUwierzytelniony

Gdy dev-permit-reads=true, wszystkie żądania GET plus POST-y copilot / ai / catalog-ask / search stają się permitAll.

Adnotacja @PreAuthorize na poziomie usługi

Usługi niższego poziomu uruchamiają @EnableMethodSecurity(prePostEnabled = true), więc kontrolery noszą adnotacje @PreAuthorize. Ponieważ KeycloakJwtConverter produkuje rzeczywiste uprawnienia ROLE_*, hasRole / hasAnyRole oceniają autentyczne role Keycloak. Reprezentatywna próbka zaobserwowanych zabezpieczeń:

Usługa / kontrolerGrupa punktów końcowychZabezpieczenie
lineage-service BiLineageControllerlineage BIhasAnyAuthority('ROLE_ADMIN','ROLE_STEWARD')
lineage-service PropagationControllerpropagacjahasRole('ADMIN')
lineage-service LineageAuthoringControllertworzeniehasAnyRole('STEWARD','ADMIN')
monitor-service AdminScheduledReportsControllerraporty zaplanowanehasAnyRole('ADMIN','STEWARD')
metadata-service WorkspaceControllerCRUD workspacehasRole('ADMIN') (wszystkie metody)
metadata-service UserControllerzarządzanie użytkownikamihasRole('ADMIN') (wszystkie metody)
metadata-service AuditLogControllerlog audytuhasRole('ADMIN')
metadata-service ConnectionControllerpołączeniaodczyt = 5 ról; create/edit/test = ADMIN/ENGINEER; delete = ADMIN
metadata-service CdrMetricsControllermetryki CDRodczyt = 5 ról; zapis = ADMIN/ENGINEER
metadata-service PiiClassifierControllerklasyfikacja PIIscan = ADMIN/ANALYST/STEWARD/ENGINEER; mutacja = ADMIN/STEWARD
metadata-service TagControllerpolityka tagówhasAnyRole('governance-admin','data-steward','admin') or hasAuthority('SCOPE_governance:policy')
metadata-service SearchControllerwyszukiwanie / reindeksacjawyszukiwanie = permitAll(); reindeksacja = hasAnyRole('ADMIN','PLATFORM_OPS')
pipeline-engine ErasureControllerusuwanie GDPRhasAnyRole('ADMIN','STEWARD')
pipeline-engine QuarantineControllerkwarantannaodczyt = ADMIN/DATA_STEWARD/DATA_ENGINEER; mutacja = ADMIN/DATA_STEWARD; release = ADMIN

Zabezpieczenia tras frontendu

RBAC frontendu jest tylko UX — SPA jest klientem publicznym, a rzeczywiste egzekwowanie zawsze odbywa się po stronie serwera. Mimo to frontend uniemożliwia użytkownikom nawigację do stron, których nie mogą używać:

  • ProtectedRoute pokazuje spinner podczas isLoading, przekierowuje do /login jeśli !isAuthenticated, następnie wywołuje canAccess(effectivePersona, pathname) i renderuje AccessDenied w przypadku niepowodzenia. effectivePersona to magazyn person w trybie deweloperskim, w przeciwnym razie user.persona.
Ekran Odmowy dostępu wyświetlany, gdy persona nawiguje do trasy poza jej dozwolonymi prefiksami
Ekran Odmowy dostępu — renderowany przez ProtectedRoute, gdy canAccess zwraca false, np. analityk wpisujący bezpośrednio adres URL /admin. To tylko zabezpieczenie UX; brama i usługi egzekwują tę samą granicę po stronie serwera.
  • RBAC oparty na prefiksie trasydata/permissions.ts definiuje personaRoutes; canAccess dopasowuje dozwolony prefiks dokładnie lub jako prefix + '/'. Ta mapa jest zablokowana przez permissions-rbac.test.ts (65 asercji).
  • PermissionGate to zabezpieczenie na poziomie komponentu zbudowane na hookach usePermission / usePermissions / useAnyPermission, obsługujące pojedyncze lub wiele uprawnień z requireAll oraz opcjonalnym fallback.
  • useAuth().hasRole(role) sprawdza realmRoles; useAuth().hasPermission(perm) sprawdza pochodzącą z persony tablicę permissions.

Dozwolone prefiksy tras per persona

PersonaDozwolone prefiksy tras
engineer/, /design-studio, /monitor, /governance, /migration, /connections, /data-marketplace, /marketplace, /my-pipelines, /pipelines, /data-browser, /templates, /admin/incidents, /telecom
analyst/, /my-pipelines, /data-browser, /data-marketplace, /marketplace, /monitor, /governance/quality, /governance/lineage
admin/, /design-studio, /monitor, /governance, /migration, /admin, /connections, /my-pipelines, /pipelines, /data-browser, /templates, /data-marketplace, /marketplace, /telecom
steward/, /monitor, /governance, /data-browser, /data-marketplace, /marketplace, /admin/audit-log, /admin/access-reviews, /admin/incidents

Znane ryzyka i luki

Badanie ujawniło kilka problemów z poprawnością autoryzacji wartych śledzenia.

Niedopasowane role @PreAuthorize

Kilka kontrolerów zabezpiecza punkty końcowe nazwami ról, których rzeczywisty token Keycloak nigdy nie może nosić. KeycloakJwtConverter emituje wyłącznie pięć kanonicznych uprawnień ROLE_ADMIN, ROLE_ENGINEER, ROLE_ANALYST, ROLE_STEWARD oraz ROLE_VIEWER. Zabezpieczenia takie jak:

  • hasRole('DATA_STEWARD') oraz hasRole('DATA_ENGINEER')QuarantineController
  • hasRole('PLATFORM_OPS') — reindeksacja SearchController
  • hasAnyRole('governance-admin','data-steward')TagController

...nigdy nie dopasują się do autentycznego użytkownika. Te punkty końcowe są faktycznie niedostępne dla rzeczywistych użytkowników — stają się osiągalne tylko w trybie dev-permit-reads, gdzie anonimowemu użytkownikowi przyznawany jest szeroki zestaw ról, który akurat obejmuje ROLE_DATA_STEWARD / ROLE_DATA_ENGINEER. To rzeczywista wada poprawności autoryzacji.

Inwersja hierarchii STEWARD

Jak zauważono powyżej, STEWARD (poziom 40) plasuje się poniżej ANALYST (poziom 50) w hierarchii backendu, więc STEWARD dziedziczy tylko uprawnienia poziomu VIEWER z RBACService — podczas gdy model person frontendu nadaje stewardowi szerokie prawa zarządzania, jakości, lineage oraz katalogu. Oba modele nie zgadzają się co do tego, jak potężny jest steward, a uprawnienia STEWARD w backendzie zależą całkowicie od jawnych list @PreAuthorize, a nie od hierarchii.

Furtka dev-permit-reads

dataflow.gateway.dev-permit-reads (domyślnie false) to potężny przełącznik. Gdy true, dopuszcza wszystkie żądania GET bez uwierzytelnienia i przyznaje anonimowemu użytkownikowi niższego poziomu szeroki zestaw ról (ROLE_ADMIN, ROLE_DPO, ROLE_COMPLIANCE_OFFICER, ROLE_AUDITOR, ROLE_STEWARD, ROLE_OPS, ROLE_ENGINEER, ROLE_USER, ROLE_DATA_ENGINEER, ROLE_DATA_STEWARD). W produkcji musi być false, a nie znaleziono żadnego zabezpieczenia środowiskowego, które by to egzekwowało.

Inne obserwacje

  • Fragmentacja słownika ról — trzy systemy ról godzone wyłącznie przez zakodowane na sztywno tabele mapowania w RBACService, KeycloakJwtConverter oraz keycloak.ts. Mapowania org_admin / developer były późną poprawką błędu.
  • Rozbieżność dokumentacji — przewodnik administratora opisuje rolę MANAGER oraz klienta dataflow-ui, które nie istnieją ani w kodzie, ani w eksporcie realmu.

Skutek netto dla operatorów

Podczas audytowania dostępu nigdy nie zakładaj, że trzy modele ról się zgadzają. Weryfikuj względem rzeczywistej hierarchii RBACService oraz tabeli mapowania KeycloakJwtConverter — i potwierdzaj, że dev-permit-reads ma wartość false w każdym wdrożeniu produkcyjnym.


Podsumowanie

TematKluczowy fakt
SłownikiRole realmu Keycloak, backendowa DataFlowRole, persony frontendu — godzone przez tabele mapowania
Hierarchia backenduADMIN(100) > ENGINEER(75) > ANALYST(50) > STEWARD(40) > VIEWER(25)
Uprawnienia backendu30 uprawnień, przyznawanych gdy poziom roli ≥ poziom wymaganej roli
Uprawnienia frontendu28 uprawnień domain:action przypisywanych per persona
EgzekwowanieGruboziarniste reguły HTTP bramy + @PreAuthorize usługi + kontrole workspace
RBAC frontenduZabezpieczenia tras tylko UX i PermissionGate — rzeczywiste egzekwowanie jest po stronie serwera
Najważniejsze ryzykaNiedopasowane role @PreAuthorize, inwersja STEWARD, furtka dev-permit-reads

Aby poznać stronę uwierzytelniania — jak tożsamość jest ustanawiana, zanim uruchomi się którakolwiek z tych kontroli — zobacz Uwierzytelnianie i SSO.

Poprzednia
Uwierzytelnianie i SSO
Następna
Przegląd API