Привилегии: GRANT/REVOKE

Рейтинг: 59.6% · 10 голосов
Подробный курс по PostgreSQL: SQL по демобазе, типы данных и JSONB, индексы, транзакции и MVCC, VACUUM, EXPLAIN и планировщик, роли и привилегии, репликация, бэкап, настройка под нагрузку и под 1С. Актуально на 2026.
Ответить
Аватара пользователя
Egor_DBA
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Привилегии: GRANT/REVOKE

Сообщение Egor_DBA »

Оглавление курса (47)
  1. Что такое PostgreSQL: история, философия, где применяется
  2. Урок 1. Что нового в PostgreSQL 15 и далее (15 -> 16 -> 17)
  3. Установка и первый запуск: Linux, Windows, Docker
  4. psql детально: метакоманды и работа в консоли
  5. Демобаза Авиаперевозки Postgres Pro: структура и развёртывание
  6. SELECT: проекция, фильтрация, сортировка
  7. Транзакции и ACID
  8. Уровни изоляции транзакций: Read Committed, Repeatable Read, Serializable
  9. Соединения таблиц (JOIN)
  10. Агрегация: GROUP BY, HAVING, GROUPING SETS
  11. Подзапросы и CTE (WITH), рекурсия
  12. Оконные функции
  13. Изменение данных: INSERT/UPDATE/DELETE, UPSERT, MERGE
  14. Числовые и булевы типы, NULL и трёхзначная логика
  15. Строки, текст, дата и время, таймзоны
  16. Массивы, диапазоны, enum, составные типы
  17. JSON и JSONB: операторы и индексация
  18. DDL: CREATE TABLE, схемы, ALTER
  19. Ограничения целостности
  20. Представления и материализованные представления
  21. Последовательности, IDENTITY, генерируемые столбцы
  22. Индексы: B-tree и когда индекс не используется
  23. Типы индексов: Hash, GiST, SP-GiST, GIN, BRIN
  24. Продвинутые индексы: частичные, по выражению, покрывающие
  25. Обслуживание индексов и таблиц: bloat, REINDEX, CONCURRENTLY
  26. Полнотекстовый поиск
  27. Роли и пользователи
  28. Привилегии: GRANT/REVOKE (вы здесь)
  29. Row-Level Security и безопасность данных
  30. Подключение приложения: pg_hba.conf, SSL, пулы соединений
  31. Серверное программирование: функции и процедуры
  32. Триггеры и события
  33. Архитектура PostgreSQL: процессы и память
  34. MVCC: версии строк и видимость
  35. VACUUM, autovacuum, freeze и wraparound
  36. WAL, контрольные точки и долговечность
  37. Блокировки и взаимоблокировки
  38. Планировщик запросов
  39. EXPLAIN и EXPLAIN ANALYZE: чтение планов
  40. Конфигурация сервера: ключевые параметры
  41. Настройка под нагрузку и под 1С
  42. Параллельные запросы и партиционирование
  43. Резервное копирование и восстановление
  44. Репликация: потоковая и hot standby
  45. Логическая репликация и кластерные решения
  46. Внешние данные, расширения и сертификация
  47. Разбор планов запросов на explain.tensor.ru: глубокое чтение EXPLAIN ANALYZE
Урок 27. Привилегии: GRANT/REVOKE

В этом уроке разбираемся, кто и что имеет право делать с объектами в postgresql. Аутентификация отвечает на вопрос "кто ты" (логин, пароль, SCRAM), а привилегии - на вопрос "что тебе можно". Это две разные стены, и путать их нельзя: успешный вход в базу еще не дает доступа ни к одной таблице. Научимся раздавать права командой GRANT, отбирать их через REVOKE, понимать роль владельца объекта, настраивать права по умолчанию через ALTER DEFAULT PRIVILEGES и строить схему доступа по принципу наименьших прав.

Изображение

Как это работает

У каждого объекта в базе (таблица, последовательность, функция, схема, сама база данных) есть владелец - роль, которая его создала или которой его передали через ALTER ... OWNER TO. Владелец и суперпользователь могут с объектом все, и им не нужно отдельно выдавать права. Всем остальным ролям доступ выдается явно. Если роли ничего не выдали - она объект как бы не видит и получает ошибку permission denied при первой же попытке прочитать или изменить данные.

Привилегии бывают разные под разные типы объектов. Для таблиц это SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES (на создание внешних ключей), TRIGGER. Для последовательностей - USAGE, SELECT, UPDATE. Для функций - EXECUTE. Для схем - USAGE (право заглянуть внутрь и обращаться к объектам по имени) и CREATE (право создавать в схеме новые объекты). Для базы данных - CONNECT, TEMP, CREATE. Отдельно стоит USAGE на пользовательских типах и доменах. Запомните пару USAGE плюс что-то еще: чтобы прочитать таблицу в схеме app, роли нужны и USAGE на схему app, и SELECT на саму таблицу. Нет USAGE на схему - и SELECT на таблицу бесполезен.

GRANT добавляет привилегию роли, REVOKE забирает. Особый получатель - PUBLIC, это псевдороль "все роли вообще, включая будущие". Если выдать SELECT для PUBLIC, читать сможет любой, кто залогинился. Есть и опция WITH GRANT OPTION: она разрешает роли не только пользоваться привилегией, но и передавать ее дальше другим. Именно из-за таких цепочек передачи у REVOKE появляются режимы CASCADE и RESTRICT, о которых ниже.

Важное изменение начиная с PostgreSQL 15: схема public больше не дает CREATE для PUBLIC автоматически. Раньше любой пользователь мог насоздавать таблиц в public, теперь по умолчанию нет - это закрыло целый класс проблем безопасности. Также владельцем схемы public теперь считается псевдороль pg_database_owner. Если у вас старые скрипты или интеграция вроде postgresql для 1с, которые рассчитывали на свободную запись в public, права придется выдать руками.

SQL и примеры

Возьмем демобазу "Авиаперевозки" (схема bookings). Заведем роль для аналитика, которому нужно только читать.

Код: Выделить всё

CREATE ROLE analytic LOGIN PASSWORD 'secret';
GRANT USAGE ON SCHEMA bookings TO analytic;
GRANT SELECT ON bookings.flights, bookings.tickets TO analytic;
Теперь analytic видит две таблицы на чтение и больше ничего. Чтобы выдать SELECT сразу на все таблицы схемы, есть форма ALL TABLES IN SCHEMA:

Код: Выделить всё

GRANT SELECT ON ALL TABLES IN SCHEMA bookings TO analytic;
Но осторожно: ALL TABLES IN SCHEMA охватывает только те таблицы, что существуют на момент выполнения команды. Создадите завтра bookings.boarding_passes - на нее права не появятся. Эту дыру закрывает ALTER DEFAULT PRIVILEGES: он говорит "для будущих объектов, которые создаст такая-то роль в такой-то схеме, сразу выдавай вот это".

Код: Выделить всё

ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA bookings
  GRANT SELECT ON TABLES TO analytic;
Учтите тонкость: права по умолчанию привязаны к роли-создателю объекта (FOR ROLE app_owner). Если новые таблицы будет создавать другая роль, правило на них не сработает. Посмотреть действующие умолчания можно через psql командой \ddp.

Проверим, что реально выдано. Привилегии на таблицу удобно смотреть командой \dp:

Код: Выделить всё

\dp bookings.flights
В колонке Access privileges будет строка вида analytic=r/app_owner. Расшифровка: слева роль-получатель, после знака равенства буквы привилегий (r это SELECT, a это INSERT, w это UPDATE, d это DELETE), после слэша - кто выдал. Пустое значение в этой колонке означает "только владелец", а не "никаких прав".

Заберем лишнее. Допустим, мы случайно дали UPDATE - отзываем:

Код: Выделить всё

REVOKE UPDATE ON bookings.flights FROM analytic;
А теперь про каскад. Пусть мы дали роли lead право SELECT с WITH GRANT OPTION, а lead передал SELECT роли junior. Если просто отозвать у lead, Postgres выдаст ошибку RESTRICT по умолчанию, потому что от него зависит выданное junior. Нужно явно указать каскад:

Код: Выделить всё

REVOKE SELECT ON bookings.tickets FROM lead CASCADE;
CASCADE отзовет привилегию у lead и заодно у всех, кому он ее передал. Без CASCADE (то есть RESTRICT) команда откажется работать, пока есть зависимые получатели.

Частые грабли
  • Выдали SELECT на таблицу, но забыли USAGE на схему - роль все равно получает permission denied for schema.
  • Думают, что GRANT ... ON ALL TABLES охватит и будущие таблицы. Нет, только существующие на момент команды. Будущие - это ALTER DEFAULT PRIVILEGES.
  • ALTER DEFAULT PRIVILEGES настроили под одну роль-создателя, а таблицы создает другая роль - умолчания молча не применяются.
  • REVOKE без CASCADE падает с ошибкой dependent privileges exist, и человек считает, что команда вообще не работает. Нужен CASCADE.
  • Доступ к последовательности забыт: дали INSERT на таблицу с колонкой GENERATED ... AS IDENTITY или serial, но не дали USAGE на саму последовательность - вставка падает на nextval.
  • Рассчитывают на старое поведение public после миграции на PG 15+: CREATE в public для PUBLIC больше не выдается по умолчанию.
  • Путают права на функцию: по умолчанию EXECUTE есть у PUBLIC, и иногда это надо явно отозвать у чувствительных функций.
Мини-лаба
  • Создайте роль reporter с LOGIN и паролем, и убедитесь, что без выданных прав она не может прочитать bookings.flights (войдите под ней через psql -U reporter).
  • Выдайте reporter USAGE на схему bookings и SELECT на flights и airports. Проверьте, что чтение заработало, а INSERT по-прежнему запрещен.
  • Командой \dp bookings.flights разберите строку Access privileges по буквам.
  • Настройте ALTER DEFAULT PRIVILEGES так, чтобы будущие таблицы, создаваемые владельцем схемы, сразу давали reporter SELECT. Создайте тестовую таблицу и проверьте.
  • Выдайте SELECT с WITH GRANT OPTION другой роли, передайте право от нее третьей роли, затем отзовите через REVOKE ... CASCADE и убедитесь, что у третьей роли права тоже пропали.
  • Отзовите у PUBLIC лишние права на схему public (REVOKE CREATE ON SCHEMA public FROM PUBLIC) и зафиксируйте принцип наименьших прав.
Подсказка по версиям: в PostgreSQL 16 у GRANT членства в роли появились опции WITH ADMIN/SET/INHERIT (более тонкое управление наследованием прав). В PostgreSQL 17 добавили привилегию MAINTAIN (право выполнять VACUUM, ANALYZE, REINDEX и подобное без владения таблицей) и предопределенную роль pg_maintain - удобно для сервисных задач обслуживания.

Контрольные вопросы
  • Чем владелец объекта отличается от роли, которой выдали все привилегии через GRANT?
  • Почему SELECT на таблицу не работает без USAGE на схему, в которой эта таблица лежит?
  • В чем разница между GRANT ON ALL TABLES IN SCHEMA и ALTER DEFAULT PRIVILEGES?
  • Когда REVOKE требует ключевого слова CASCADE и что произойдет без него?
  • Что изменилось в правах на схему public начиная с PostgreSQL 15 и почему это важно для безопасности?
  • Как сформулировать принцип наименьших прав применительно к роли только для чтения отчетов?
👍4 ❤️ 🔥1 😄 🤔
Аватара пользователя
studer
Сообщения: 1
Зарегистрирован: 31 май 2026, 05:37

Re: Привилегии: GRANT/REVOKE

Сообщение studer »

А если роль состоит в группе, которой выдали SELECT - она читает через членство или права надо дублировать лично? Запутался с INHERIT.
👍1 ❤️1 🔥 😄 🤔
Аватара пользователя
caffeineraccoon
Сообщения: 1
Зарегистрирован: 24 май 2026, 17:25

Re: Привилегии: GRANT/REVOKE

Сообщение caffeineraccoon »

Поймал грабли с serial: INSERT дал, а вставка падала на nextval. Помог USAGE на последовательность, спасибо что предупредили заранее.
👍 ❤️ 🔥2 😄 🤔
Ответить
← Предыдущая глава
Роли и пользователи
Следующая глава →
Row-Level Security и безопасность данных

Все главы курса «PostgreSQL: от первого запроса до продакшена»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «PostgreSQL: от первого запроса до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя