Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

permission denied for table - jak nadać właściwe uprawnienia

W skrócie

  • Problem: aplikacja albo użytkownik dostaje ERROR: permission denied for table przy zapytaniu do istniejącej tabeli.
  • Dlaczego: rola nie ma nadanego przywileju (SELECT, INSERT, UPDATE, DELETE) na tej tabeli - samo istnienie tabeli nie daje do niej dostępu.
  • Rozwiązanie: nadajemy właściwe przywileje poleceniem GRANT, a dla przyszłych tabel ustawiamy przywileje domyślne.

PostgreSQL domyślnie nie udostępnia tabel każdemu, kto potrafi się zalogować - dostęp do danych trzeba nadać jawnie. Dlatego świeżo utworzona rola aplikacji często widzi bazę, ale przy pierwszym SELECT dostaje odmowę. Problem dotyczy każdego, kto rozdziela role - osobną do właściciela schematu i osobną do aplikacji. Pokazujemy, jak nadać dokładnie te przywileje, których trzeba, i jak sprawić, by obejmowały też tabele tworzone w przyszłości.

Jak to wygląda w praktyce

Rola aplikacji łączy się bez problemu, ale zapytanie kończy się odmową:

sklep=> SELECT * FROM zamowienia LIMIT 5;
ERROR:  permission denied for table zamowienia

Co mylące, tabela istnieje i widać ją w katalogu - problemem nie jest jej brak, tylko brak przywileju. Podobnie wygląda odmowa przy zapisie, tylko z inną operacją:

sklep=> INSERT INTO zamowienia (kwota) VALUES (99);
ERROR:  permission denied for table zamowienia

To odróżnia sytuację od relation does not exist (tabeli nie ma albo jest poza search_path) - tutaj tabela jest, ale rola nie ma do niej prawa.

Dlaczego tak się dzieje

W PostgreSQL dostęp do danych opiera się na przywilejach nadawanych rolom. Utworzenie tabeli daje pełne prawa jej właścicielowi, ale nie innym rolom - te muszą dostać przywilej jawnie poleceniem GRANT. Przywileje są ziarniste - osobno SELECT (odczyt), INSERT (dodawanie), UPDATE (zmiana) i DELETE (usuwanie). Co ważne, GRANT działa tylko na tabele, które już istnieją w chwili jego wykonania - nowe tabele utworzone później nie odziedziczą tych przywilejów automatycznie. Dlatego typowy scenariusz to nadanie praw na bieżące tabele plus ustawienie tak zwanych przywilejów domyślnych (ALTER DEFAULT PRIVILEGES), które obejmą obiekty tworzone w przyszłości przez danego właściciela.

Jak to rozwiązać krok po kroku

  1. Nadaj odczyt na konkretną tabelę: GRANT SELECT ON zamowienia TO app;. Dla roli zapisującej dodaj pozostałe operacje: GRANT SELECT, INSERT, UPDATE, DELETE ON zamowienia TO app;.
  2. Aby nadać prawa hurtowo na wszystkie istniejące tabele w schemacie: GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app;.
  3. Jeśli rola korzysta z sekwencji (kolumny serial lub GENERATED ... AS IDENTITY), nadaj też prawo do nich: GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app;.
  4. Ustaw przywileje domyślne, aby przyszłe tabele właściciela były od razu dostępne dla roli: ALTER DEFAULT PRIVILEGES FOR ROLE wlasciciel IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app;.
  5. Rozważ nadawanie przywilejów przez rolę grupową (na przykład app_rw) i przypisywanie do niej ludzi lub aplikacji - łatwiej wtedy zarządzać dostępem niż nadając prawa każdej roli osobno.
  6. Wykonuj polecenia GRANT jako właściciel tabel albo superuser - tylko oni mogą nadawać do nich przywileje.

Jak sprawdzić, że zadziałało

Sprawdź nadane przywileje wprost, funkcją, która pyta serwer o efektywne prawo danej roli do tabeli:

SELECT has_table_privilege('app', 'zamowienia', 'SELECT') AS moze_czytac,
       has_table_privilege('app', 'zamowienia', 'INSERT') AS moze_dodawac;

Obie kolumny powinny zwrócić t. Pełną listę przywilejów obejrzysz w psql poleceniem \dp zamowienia, a najlepszym testem jest wykonanie zapytania jako rola aplikacji - powinno przejść bez odmowy.

Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Szkolenie Zaawansowana administracja PostgreSQL - HA, DR, monitoring, skalowanie

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Dlaczego rola widzi tabelę, ale dostaje permission denied for table?
Bo widoczność tabeli w katalogu to nie to samo co prawo dostępu do jej danych. W PostgreSQL przywileje odczytu i zapisu trzeba nadać roli jawnie poleceniem GRANT. Właściciel tabeli ma je z automatu, ale każda inna rola musi je otrzymać. Bez przywileju SELECT czy INSERT każde zapytanie do tej tabeli kończy się odmową, mimo że tabela istnieje.
Jak nadać prawa od razu na wszystkie tabele w schemacie?
Poleceniem GRANT z klauzulą ON ALL TABLES IN SCHEMA, na przykład GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app. Obejmuje ono jednak tylko tabele istniejące w chwili wykonania. Dla tabel tworzonych później trzeba dodatkowo ustawić przywileje domyślne przez ALTER DEFAULT PRIVILEGES, inaczej nowe tabele znów będą niedostępne dla roli.
Do czego służy ALTER DEFAULT PRIVILEGES?
To polecenie ustala, jakie przywileje mają automatycznie otrzymywać obiekty tworzone w przyszłości przez wskazaną rolę. Dzięki temu nie trzeba po każdym utworzeniu tabeli ponawiać GRANT. Ustawia się je per rola tworząca i per schemat, na przykład ALTER DEFAULT PRIVILEGES FOR ROLE wlasciciel IN SCHEMA public GRANT SELECT ON TABLES TO app. Działa tylko na obiekty tworzone po jego wykonaniu.
Jak sprawdzić, jakie przywileje ma rola do konkretnej tabeli?
Najprościej funkcją has_table_privilege, na przykład SELECT has_table_privilege('app', 'zamowienia', 'SELECT'), która zwraca true albo false. Pełną listę praw dla tabeli pokaże w psql polecenie \dp zamowienia. Warto pamiętać, że przywileje mogą pochodzić też z ról grupowych, do których należy dana rola, dlatego has_table_privilege liczy prawo efektywne.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...