sqlpostgresqlrevokepermissions

SQL REVOKE: Safely Taking Back Granted Privileges

How to use REVOKE to take back granted privileges, handle CASCADE and RESTRICT, and not get caught out by PUBLIC or role-based access.

2 min de lectureReferencesql · postgresql · revoke · permissions · security
Cet article est actuellement en russe — la traduction en anglais est en cours.

REVOKE — это зеркальное отражение GRANT: команда забирает ранее выданные привилегии у пользователя или роли. На практике отзыв прав оказывается заметно коварнее выдачи, потому что один и тот же доступ может приходить из нескольких источников сразу.

Базовый синтаксис

Чтобы отозвать конкретную привилегию на таблице, перечисляете право, объект и того, у кого его забираете:

REVOKE INSERT ON orders FROM analyst;

Можно отзывать сразу несколько прав и работать с конкретными столбцами:

REVOKE SELECT, UPDATE ON users FROM analyst;
REVOKE UPDATE (salary) ON employees FROM analyst;
REVOKE ALL PRIVILEGES ON orders FROM analyst;

Ключевой принцип: REVOKE отзывает только то, что было выдано напрямую этому грантополучателю. Если право пришло другим путём, команда тихо выполнится без ошибки, но эффективный доступ останется.

CASCADE против RESTRICT

Если привилегия выдавалась с WITH GRANT OPTION, её получатель мог передать право дальше. При отзыве PostgreSQL должен решить судьбу этих производных грантов.

  • RESTRICT (поведение по умолчанию) — отказать в отзыве, если от этого права зависят выданные дальше гранты.
  • CASCADE — отозвать само право и все производные гранты по цепочке.
GRANT SELECT ON orders TO manager WITH GRANT OPTION;
-- manager passed it on:
GRANT SELECT ON orders TO analyst;

-- This fails because manager re-granted the right:
REVOKE SELECT ON orders FROM manager RESTRICT;

-- This removes manager's grant AND analyst's:
REVOKE SELECT ON orders FROM manager CASCADE;

Отдельно можно отозвать только право на дальнейшую передачу, оставив сам доступ:

REVOKE GRANT OPTION FOR SELECT ON orders FROM manager CASCADE;

Грабли: CASCADE способен снести доступ у учётных записей, о которых вы даже не подозревали. Перед отзывом с CASCADE посмотрите цепочку грантов в information_schema.role_table_grants, иначе рискуете уронить чужой отчёт или ETL-джобу.

Почему PUBLIC всё ещё имеет доступ

Самая частая ловушка: вы отозвали право у пользователя, а он всё равно читает таблицу. Причина — псевдороль PUBLIC, которой неявно принадлежат все роли в кластере. Если право выдано PUBLIC, отзыв у отдельного пользователя ничего не меняет.

-- Someone granted broad access earlier:
GRANT SELECT ON users TO PUBLIC;

-- This looks right but analyst still reads users:
REVOKE SELECT ON users FROM analyst;

-- You must revoke from PUBLIC itself:
REVOKE SELECT ON users FROM PUBLIC;

Помните и про права владельца: владелец таблицы и суперпользователь сохраняют полный доступ независимо от REVOKE. Обычным отзывом их доступ не убрать.

Роль против пользователя

Доступ удобно раздавать через роли-группы, но это усложняет отзыв. Если пользователь analyst входит в роль analytics_team, отзыв права лично у analyst не затронет то, что он получает через членство в роли.

GRANT SELECT ON orders TO analytics_team;
GRANT analytics_team TO analyst;

-- No effect: analyst gets SELECT via the role, not directly:
REVOKE SELECT ON orders FROM analyst;

-- Option A: revoke from the role (affects everyone in it):
REVOKE SELECT ON orders FROM analytics_team;

-- Option B: remove this user from the role:
REVOKE analytics_team FROM analyst;

В MySQL модель похожа, но REVOKE ... CASCADE/RESTRICT не поддерживается, а роли появились только в версии 8.0; до неё привилегии назначались напрямую аккаунтам. ClickHouse поддерживает REVOKE и роли, но привилегии и синтаксис заметно отличаются от стандарта SQL.

Как безопасно ужесточать права

  • Сначала проверьте эффективный доступ: загляните в information_schema.role_table_grants и пройдите по членству в ролях, прежде чем что-то отзывать.
  • Не забывайте про PUBLIC — для чувствительных таблиц явно выполняйте REVOKE ... FROM PUBLIC.
  • Используйте RESTRICT (или просто не пишите CASCADE), чтобы команда упала, если есть зависимые гранты, и вы увидели проблему заранее.
  • Отзывайте через тот же уровень, через который выдавали: роль отзывайте у роли, прямой грант — у пользователя.
  • Заворачивайте серию REVOKE в транзакцию и проверяйте результат SELECT от лица пользователя, прежде чем коммитить.

Итог: отзыв прав — это не одна команда, а маленький аудит маршрутов доступа. Сначала найдите, откуда право приходит, затем отзывайте ровно на этом уровне и только после этого проверяйте эффективный доступ глазами роли-получателя.

Entraînez-vous sur de vrais exercices

Résolvez des exercices dans l'entraîneur SQL avec évaluation et indices instantanés.

Ouvrir l'entraîneur