⚠  PROJEKT — niezweryfikowany prawnie. Wymaga akceptacji przed publikacją.

Biała Księga Bezpieczeństwa

Produkt: Exceptao / paraKSCol / CyberZgodność EDU  ·  Ostatnia aktualizacja: 2026-05-15  ·  Odbiorcy: Potencjalni klienci, recenzenci bezpieczeństwa, audytorzy, oficerowie ds. zgodności

Niniejszy dokument jest publicznym podsumowaniem architektury bezpieczeństwa platformy. Każde twierdzenie powinno być weryfikowalne przez dziennik audytowy, endpoint weryfikacji lub aneksy DPA. Ostatnia sekcja („Czego jeszcze nie robimy”) jest uczciwa w kwestii luk.

1. Filozofia bezpieczeństwa

Produkt jest sprzedawany specjalistom ds. bezpieczeństwa, którzy będą go dokładnie analizować przed zaufaniem mu z danymi compliance swojej organizacji. Trzy zasady kierują każdą decyzją projektową:

1. Awaria zamknięta (fail closed). Jeżeli mechanizm bezpieczeństwa nie może działać — Vault niedostępny, łańcuch audytu uszkodzony, dostawca kopii zapasowych niedostępny — system odmawia obsługi tej powierzchni i ujawnia awarię wprost. Nie degraduje się po cichu.

2. Baza danych jest granicą bezpieczeństwa. Izolacja dzierżawców jest egzekwowana przez Row-Level Security PostgreSQL na poziomie bazy danych, nie przez filtry warstwy aplikacji. Błąd aplikacji, który zapomni filtrować po dzierżawcy, jest nieszkodliwy: baza danych zwraca zero wierszy.

3. Wykrywalność manipulacji zamiast jej zapobiegania. Architektura sprawia, że każda manipulacja jest wykrywalna i identyfikowalna przez łańcuch skrótów, znaczniki kotwic i endpoint weryfikacji.

2. Izolacja dzierżawców

2.1 FORCE ROW LEVEL SECURITY PostgreSQL

Każda tabela powiązana z dzierżawcą ma następujące ustawienia stosowane w czasie migracji:

ALTER TABLE <tabela> ENABLE ROW LEVEL SECURITY;
ALTER TABLE <tabela> FORCE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON <tabela>
  USING (tenant_id::text = current_setting('app.current_tenant_id', true));

FORCE ROW LEVEL SECURITY stosuje politykę nawet do właściciela tabeli. Para GUC (app.current_tenant_id, app.current_org_unit_id) jest ustawiana w bloku SET LOCAL na początku transakcji każdego żądania:

# apps/tenants/context.py
with connection.cursor() as cur:
    cur.execute("SET LOCAL ROLE app")
    cur.execute("SET LOCAL app.current_tenant_id = %s", [str(tenant.id)])
    cur.execute("SET LOCAL app.current_org_unit_id = %s", [str(org_unit.id)])

SET LOCAL oznacza, że wartości GUC wygasą z końcem transakcji. pgbouncer działa w trybie puli transakcyjnej — żadna wartość GUC nie wycieka do kolejnego żądania.

2.2 Podział ról bazy danych

RolaUprawnieniaUżywana przez
migratorDDL; właściciel tabel; BYPASSRLSWyłącznie migracje Django — nigdy w czasie działania
appSELECT, INSERT, UPDATE, DELETE; ograniczona przez RLSŚrodowisko uruchomieniowe aplikacji (ORM Django, widoki DRF)
audit_writerWyłącznie INSERT na audit_log; brak UPDATE i DELETESerwis audytowy (wyłącznie zapisy)
superadminBYPASSRLS; SELECT na wszystkich tabelachPanel super-admina — każde działanie rejestrowane w audycie

2.3 Izolacja jednostki organizacyjnej

Druga oś izolacji — org_unit_id — ogranicza dostęp dla ról powiązanych z placówkami. ITSO Szkoły A widzi wyłącznie Zadania Kontrolne, incydenty i rekordy samoidentyfikacji Szkoły A. Egzekwowane przez RLS na poziomie (tenant_id, org_unit_id).

3. Uwierzytelnianie

3.1 Konta lokalne

3.2 WebAuthn passkeys

Passkeys WebAuthn (FIDO2) są dostępne na wszystkich kontach. Obsługiwane uwierzytelniające: platformy (Touch ID, Windows Hello, biometria Android) i sprzętowe klucze FIDO2 (YubiKey). Walidacja licznika logowań przy każdej asercji; spadł licznika wyzwala automatyczne unieważnienie i alert.

3.3 SSO OIDC

Konfiguracja per Dzierżawca. Obsługiwane przepływy: wyłącznie Authorization Code z PKCE. Walidacja tokenu: podpis (JWKS), iss, aud, exp, nbf, nonce. Preset „Zaloguj się przez Microsoft” (Entra ID / Azure AD).

3.4 SSO SAML 2.0

Konfiguracja per Dzierżawca przez przesłanie metadanych XML IdP. SSO inicjowane przez SP; SSO inicjowane przez IdP domyślnie wyłączone. Mapowanie atrybutów konfigurowalne (e-mail, imię i nazwisko, rola). Provisioning JIT z mapowaniem odkładań grupowych na role.

3.5 Sesje

Sesje Django po stronie serwera przechowywane w bazie danych. Atrybuty cookie: Secure; HttpOnly; SameSite=Lax. Sesja unieważniana po stronie serwera przy wylogowaniu. Timeout po 15 minutach nieaktywności (konfigurowalne per Dzierżawca, maksimum 8 godzin).

4. Autoryzacja

5. Integralność dziennika audytowego

5.1 Egzekwowanie tylko do dołączania

Rola Postgres audit_writer ma uprawnienie INSERT na audit_log i brak UPDATE i DELETE. Potok CI/CD weryfikuje ten zestaw uprawnień przy każdym wdrożeniu.

5.2 łańcuch skrótów SHA-256

row_hash_n = sha256( prev_hash_(n-1) || canonical_json(row_n) )

Gdzie canonical_json = RFC 8785 JSON Canonicalization Scheme zastosowany do jawnej, wersjonowanej listy pól. Wersja listy pól (schema_version) jest przechowywana w każdym wierszu.

5.3 Endpoint weryfikacji

GET /api/audit/verify przechodzi przez pełny łańcuch skrótów dla żądającego Dzierżawcy i zwraca:

{
  "ok": true,
  "broken_at": null,
  "total_rows": 47291,
  "first_row_at": "2026-01-15T09:00:00Z",
  "last_row_at": "2026-05-15T14:23:11Z",
  "last_anchor_at": "2026-05-15T14:00:00Z",
  "schema_versions_seen": [1]
}

5.4 Godzinne migawki kotwic

Zadanie Celery beat uruchamiane co godzinę rejestruje bieżący row_hash najnowszego wiersza per Dzierżawca w tabeli audit_anchor.

5.5 Pseudonimizacja przy usuwaniu

Na zweryfikowane żądanie usunięcia (art. 17 RODO), pola actor_email i actor_ip są zastępowane stabilnymi znacznikami (actor_tombstone_<uuid>). łańcuch skrótów jest przeliczany na wartości znacznika, zachowując integralność.

6. Szyfrowanie

6.1 W transmisji

6.2 W spoczynku

6.3 Nagłówki bezpieczeństwa HTTP

Wszystkie odpowiedzi zawierają nagłówki: Strict-Transport-Security (preload), Content-Security-Policy (oparty na nonce), X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Cross-Origin-Opener-Policy: same-origin, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy (odmowa domyślna).

7. Zarządzanie sekretami

8. Architektura sieciowa

9. Kopie zapasowe i odtwarzanie po awarii

10. Bezpieczeństwo łańcucha dostaw

11. Zarządzanie podatnościami

WażnośćWynik CVSSSLA naprawy
Krytyczna≥ 9,072 godziny od potwierdzonej podatności
Wysoka7,0–8,914 dni
Średnia4,0–6,930 dni
Niska< 4,0Następne wydanie mniejsze

Skoordynowane ujawnianie: security@parakscol.pl. .well-known/security.txt opublikowany na wszystkich domenach marki. Zewnętrzny test penetracyjny planowany przed pierwszym płatnym klientem.

12. Reagowanie na incydenty

Udokumentowany podręcznik IR: wykrywanie i triage, izolacja, eliminacja, odtwarzanie, post-mortem i powiadamianie regulacyjne.

Jurysdykcja / prawoPowiadomienie organu nadzorczegoPowiadomienie osób dotkniętych
RODO / UE≤ 72 godziny od powzięcia wiadomości (art. 33)Bez zbędnej zwłoki dla naruszeń wysokiego ryzyka (art. 34)
Polska (KSC / NIS2)24h wczesne ostrzeżenie; 72h zgłoszenie; 30 dni raport końcowy (art. 23 NIS2)Zgodnie z obowiązującym prawem

Obowiązek Operatora powiadamiania Administratora (Dzierżawcy) o naruszeniu: ≤ 72 godziny, zgodnie z DPA §8.

13. Czego jeszcze nie robimy (uczciwa sekcja)

Wierzymy w nienadmiarowe twierdzenia. Poniższa lista jest uczciwa w kwestii luk.

ElementStatusPlan
Certyfikacja SOC 2 Type IIJeszcze nie — zaangażowanie audytorskie nie rozpoczęteArchitektura zaprojektowana pod kątem gotowości SOC 2. Zaangażowanie audytora planowane po fazie GA.
Certyfikacja ISO 27001Jeszcze niePlanowana po SOC 2 Type II.
FedRAMPNie dotyczy w v1Brak klientów federalnych USA w v1.
Zewnętrzny urząd znaczników czasu RFC 3161Architektura to obsługuje; jeszcze niepodłączony do produkcyjnego TSAFaza 2.
Cykliczny zewnętrzny test penetracyjnyPierwszy test planowany przed pierwszym płatnym klientemRoczna kadencja po osiągnięciu odpowiednich przychodów.
Program bug bountyJeszcze nieFaza 2/3 — Intigriti lub HackerOne.
Warm-standby DR (RTO ≤ 30 min)Jeszcze nie — obecny RTO ≤ 4 godzinyFaza 3 — wymaga repliki hot-standby i automatycznego przełączania awaryjnego.
Zdalny atest LUKS[DO UZUPEŁNIENIA: udokumentować produkcyjny mechanizm odblokowania LUKS]Aktualnie wymaga ręcznego wprowadzania klucza przy restarcie VPS.

14. Kontakt

CelKontakt
Ujawnianie luk bezpieczeństwasecurity@parakscol.pl
Prywatność / DPAiod@parakscol.pl
.well-known/security.txtOpublikowany na każdej domenie marki
Klucz publiczny PGP[DO UZUPEŁNIENIA: opublikować pod adresem .well-known/security.txt]