Как временно предоставить пользователю повышенные права доступа?

Вопрос немного сложнее, чем кажется на первый взгляд. Он касается реализации функционала, схожего с indirect_role в Sybase. Я имею в виду процедуру, текст которой скрыт, где происходит проверка на наличие indirect роли пользователя в системе управления базами данных (СУБД). Если такая роль имеется, то временно предоставляются повышенные права, например, выдача определенной роли, после чего права возвращаются назад. 

Есть ли аналогичная возможность в PostgreSQL? Важно, чтобы данное решение было безопасным и не требовало значительных затрат ресурсов. 

Моя цель — предоставить пользователям возможность просматривать все процессы в pg_stat_activity (не ограничиваясь только своими) и иметь возможность завершать процессы, при этом не предоставляя им полные административные права. 

Я нашел предопределенную роль <a href="https://postgrespro.ru/docs/postgresql/15/predefined-roles" rel="nofollow">pg_read_all_stats</a>. Насколько безопасно выдавать её обычным пользователям, а не только тем, кто занимается мониторингом? Как можно временно предоставить права на завершение процессов, не предоставляя полные административные права? 

Также я наткнулся на <a href="https://postgrespro.ru/docs/postgrespro/14/sql-createfunction" rel="nofollow">SECURITY DEFINER</a> в параметрах создания функций, но, судя по описанию, это подходит только для операций чтения.
  • 23 апреля 2025 г. 7:05
Ответы на вопрос 2
В PostgreSQL действительно существует возможность управлять правами доступа с помощью функций с атрибутом `SECURITY DEFINER`, но давайте разберем вашу задачу более подробно.

### Временное предоставление прав

1. **Использование `SECURITY DEFINER`:** Вы можете создать функцию, которая будет выполняться с правами владельца функции, а не с правами пользователя, её вызывающего. Это позволяет управлять доступом к определённым операциям. Например, чтобы позволить пользователю завершать процессы, вы можете создать функцию для этого, которая будет использовать `pg_terminate_backend`.

2. **Создание функции для завершения процессов:**
   ```sql
   CREATE OR REPLACE FUNCTION terminate_backend(pid bigint)
   RETURNS void AS $$
   BEGIN
       PERFORM pg_terminate_backend(pid);
   END;
   $$ LANGUAGE plpgsql SECURITY DEFINER;
   ```
   Не забудьте установить владельца функции таким образом, чтобы у него были правильные права и он имел возможность завершать процессы.

3. **Предоставление прав:**
   Вы можете предоставить доступ к этой функции определенной роли или только точно определённому пользователю.
   ```sql
   GRANT EXECUTE ON FUNCTION terminate_backend(bigint) TO your_user;
   ```

### Использование роли `pg_read_all_stats`

- Роль `pg_read_all_stats` предоставляет доступ к статистической информации о всех базе данных, включая `pg_stat_activity`. Она обычно предназначена для пользователей, занимающихся мониторингом, но в общем случае её можно предоставлять другим пользователям, если вы уверены, что они не будут злоупотреблять этой информацией.
  
- Если вы хотите предоставить пользователям возможность видеть информацию о всех процессах, вы можете предоставить им роль `pg_read_all_stats`, но рассматривайте это как часть вашей политики безопасности.

### Рекомендации по безопасности

- **Минимизируйте привилегии:** Дайте только те права, которые необходимы. Например, если пользователю не требуется завершать процессы, не предоставляйте ему правомочий на `pg_terminate_backend`.

- **Логи и аудит:** Включите логирование действий, чтобы отслеживать любые операции, которые выполняются пользователями с повышенными правами.

- **Документируйте предоставление прав:** Обеспечьте документирование всех изменений в правах доступа, чтобы иметь возможность отслеживать, кто и когда получил доступ к повышенным правам.

### Заключение

Создание функций с `SECURITY DEFINER` — это безопасный и эффективный способ временного предоставления повышенных прав в PostgreSQL. Это предлагает гибкость без необходимости предоставления пользователям доступа к полным административным правам.
security definer и есть: проверка прав вызова функции (grant execute) будет проверять, может ли её вызвать этот пользователь, но сама функция дальше будет выполняться с правами владельца функции. В том числе с правами супера, если владелец - суперпользователь. 

Не забудьте revoke execute on function .. from public;
begin;
create role specific_activity;
create function stat_activity() .. security definer;
revoke execute on function stat_activity() from public; -- права на запуск не всем
grant execute on function stat_activity() to specific_activity; -- а только этой роли
commit;
grant specific_activity to someuser;


btw, для pg_terminate_backend есть предопределённая роль pg_signal_backend.
Похожие вопросы