Zasady bezpieczeństwa na poziomie wierszy
Automatycznie filtruj wiersze dla poszczególnych użytkowników
Zasady bezpieczeństwa na poziomie wierszy to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Academy zawiera 4 lekcji w sumie.
Czym jest bezpieczeństwo na poziomie wierszy?
Bezpieczeństwo na poziomie wierszy (RLS) to funkcja PostgreSQL, która pozwala kontrolować, które wiersze tabeli dany użytkownik bazy danych lub rola mogą wyświetlać albo modyfikować. Zamiast filtrować wiersze w każdym zapytaniu, definiuje się politykę raz, a PostgreSQL automatycznie wymusza jej stosowanie przy każdym SELECT, INSERT, UPDATE i DELETE.
Można myśleć o tym jak o niewidocznej klauzuli WHERE dołączonej do samej tabeli, a nie do konkretnego zapytania.
Włączanie RLS dla tabeli
RLS jest domyślnie wyłączone. Należy jawnie włączyć je dla każdej tabeli za pomocą ALTER TABLE ... ENABLE ROW LEVEL SECURITY. Po włączeniu każda rola, która nie jest właścicielem tabeli, nie zobaczy żadnych wierszy, dopóki nie zostanie utworzona co najmniej jedna polityka.
-- Create a sample table
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
owner TEXT NOT NULL,
amount NUMERIC(10,2)
);
-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;Tworzenie pierwszej polityki
Politykę tworzy się za pomocą CREATE POLICY. Nadaje się jej nazwę, określa tabelę i podaje wyrażenie USING. Klauzula USING jest wyrażeniem logicznym ocenianym dla każdego wiersza — użytkownik widzi tylko te wiersze, dla których wyrażenie zwraca TRUE.
-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
ON orders
FOR SELECT
USING (owner = current_user);Klauzule USING a WITH CHECK
Polityki mają dwie klauzule filtrujące, które służą różnym celom:
- USING — filtruje wiersze podczas operacji odczytu (SELECT, UPDATE, DELETE). Wiersz jest widoczny tylko wtedy, gdy USING zwraca TRUE.
- WITH CHECK — sprawdza poprawność wierszy podczas operacji zapisu (INSERT, UPDATE). Zapis jest dozwolony tylko wtedy, gdy WITH CHECK zwraca TRUE. Jeśli klauzula zostanie pominięta, do sprawdzania zapisu ponownie używana jest USING.
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
ON orders
FOR ALL
USING (owner = current_user)
WITH CHECK (owner = current_user);Zakres polityki: FOR SELECT, INSERT, UPDATE, DELETE
Jedna polityka może obejmować wszystkie polecenia (FOR ALL) lub konkretne polecenie. Rozdzielenie polityk według poleceń zapewnia szczegółową kontrolę — na przykład umożliwia każdemu użytkownikowi odczyt wszystkich wierszy, ale modyfikowanie tylko własnych.
-- Everyone can read all orders
CREATE POLICY read_all_orders
ON orders
FOR SELECT
USING (true);
-- But each user can only update their own orders
CREATE POLICY update_own_orders
ON orders
FOR UPDATE
USING (owner = current_user)
WITH CHECK (owner = current_user);Używanie session_user i current_user
PostgreSQL udostępnia wbudowane funkcje do identyfikowania aktywnego użytkownika wewnątrz wyrażenia polityki:
- current_user — rola, której uprawnienia są obecnie aktywne (może się zmienić po SET ROLE).
- session_user — rola, która otworzyła połączenie (nigdy nie zmienia się w trakcie sesji).
Większość polityk RLS korzysta z current_user, ponieważ odzwierciedla on efektywną rolę po przełączeniu roli.
-- Inspect the current identity inside a query
SELECT current_user, session_user;Stosowanie RLS do określonych ról
Domyślnie polityka dotyczy PUBLIC (wszystkich ról). Można ograniczyć ją do określonej roli za pomocą klauzuli TO. Jest to przydatne, gdy potrzebna jest jedna polityka dla zwykłych użytkowników, a inna dla roli administratora.
-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
ON orders
FOR SELECT
TO app_user
USING (owner = current_user);
-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
ON orders
FOR ALL
TO admin
USING (true)
WITH CHECK (true);Polityki PERMISSIVE a RESTRICTIVE
Wiele polityk dotyczących tej samej tabeli może oddziaływać na siebie na dwa sposoby:
- PERMISSIVE (domyślne) — wszystkie polityki permisywne są łączone operatorem OR. Wiersz jest dostępny, jeśli zezwala na to dowolna polityka PERMISSIVE.
- RESTRICTIVE — polityki restrykcyjne są łączone operatorem AND z wynikiem działania polityk permisywnych. Wiersz jest dostępny tylko wtedy, gdy przejdzie politykę restrykcyjną i co najmniej jedną politykę permisywną.
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
ON orders
AS RESTRICTIVE
FOR SELECT
USING (amount > 0);Omijanie RLS: BYPASSRLS i właściciele tabel
Właściciel tabeli i superużytkownicy domyślnie omijają RLS i zawsze widzą wszystkie wiersze. Można nadać roli atrybut BYPASSRLS, jeśli potrzebuje ona nieograniczonego dostępu bez uprawnień superużytkownika. Z kolei właściciela można zobowiązać do przestrzegania RLS za pomocą FORCE ROW LEVEL SECURITY.
-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;Modyfikowanie i usuwanie polityk
Istniejącą politykę można zaktualizować za pomocą ALTER POLICY lub całkowicie usunąć za pomocą DROP POLICY. Usunięcie wszystkich polityk, gdy RLS jest nadal włączone, oznacza, że role niebędące właścicielami nie mają dostępu do żadnych wierszy. Aby całkowicie usunąć RLS, należy wyłączyć je za pomocą ALTER TABLE.
-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
RENAME TO user_isolation_policy;
-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
USING (owner = current_user AND amount >= 0);
-- Remove a policy
DROP POLICY admin_full_access ON orders;
-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;Praktyczny wzorzec: izolacja danych w architekturze multi-tenant
Częsty wzorzec RLS w aplikacjach SaaS opartych na modelu multi-tenant polega na przechowywaniu kolumny tenant_id w każdej tabeli i używaniu zmiennej na poziomie sesji (set_config) do przekazania identyfikatora dzierżawcy w momencie nawiązywania połączenia. Następnie polityka porównuje tenant_id każdego wiersza z wartością tego ustawienia.
-- Table with tenant isolation column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
title TEXT
);
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
ON documents
FOR ALL
USING (tenant_id = current_setting('app.tenant_id'))
WITH CHECK (tenant_id = current_setting('app.tenant_id'));
-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);
-- Now only tenant_42 documents are visible
SELECT * FROM documents;Sprawdzenie wiedzy
Sprawdź swoją wiedzę na temat polityk Row-Level Security w PostgreSQL.
Podsumowanie lekcji
W tej lekcji pokazano, jak Row-Level Security zapewnia automatyczne filtrowanie wierszy sterowane politykami bezpośrednio na poziomie bazy danych:
- Włączanie RLS na tabeli za pomocą ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
- Używanie CREATE POLICY z klauzulą USING do filtrowania wierszy możliwych do odczytu oraz klauzulą WITH CHECK do sprawdzania poprawności zapisywanych wierszy.
- Ograniczanie zakresu polityk do określonych poleceń (SELECT, INSERT, UPDATE, DELETE, ALL) i określonych ról za pomocą klauzuli TO.
- Łączenie polityk PERMISSIVE (logika OR) i RESTRICTIVE (logika AND) w celu tworzenia wielowarstwowej kontroli dostępu.
- Właściciele tabel i superużytkownicy domyślnie omijają RLS; można to zmienić za pomocą FORCE ROW LEVEL SECURITY.
- Wzorzec multi-tenant wykorzystujący current_setting() to potężne praktyczne zastosowanie RLS.
RLS to standardowy sposób czystego i spójnego egzekwowania izolacji danych bez rozpraszania klauzul WHERE w każdym zapytaniu aplikacji.
Często zadawane pytania
Czy lekcja „Zasady bezpieczeństwa na poziomie wierszy” jest bezpłatna?
Tak — pełny tekst „Zasady bezpieczeństwa na poziomie wierszy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Academy, przejdź na CoddyKit PRO. Kurs SQL Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Zasady bezpieczeństwa na poziomie wierszy”?
Automatycznie filtruj wiersze dla poszczególnych użytkowników Ćwiczysz SQL Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć SQL Academy?
Nie wymagamy żadnego doświadczenia. SQL Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Zasady bezpieczeństwa na poziomie wierszy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji SQL Academy?
Tak. Każda lekcja SQL Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Role i uprawnienia
- Zasady bezpieczeństwa na poziomie wierszy
- Uprawnienia na poziomie kolumn
- Audytowanie dostępu