3.1. Управление доступом #

Поскольку pgpro_metastore работает с собственными объектами, для разграничения прав и гибкого управления доступом к таким объектам используется система на основе прокси-таблиц.

Прокси-таблицы — это пустые таблицы без столбцов, созданные в схеме pgpro_metastore. Имя каждой прокси-таблицы соответствует формату префикс_имя, где:

  • префикс: префикс, определяющий объект, обёрнутый в прокси-таблицу.

    Возможные значения:

  • имя: имя объекта, обёрнутого в прокси-таблицу.

Например, именем прокси-таблицы может быть s_localstorage.

Прокси-таблицы создаются и удаляются одновременно с объектами, которые они оборачивают.

За подробной информацией о настройке доступа к СУБД Postgres Pro AXE обратитесь к официальной документации Postgres Pro.

3.1.1. Настройка роли администратора #

В Postgres Pro AXE роль администратора называется metastore_admin. Она может взаимодействовать с pgpro_axe, выполнять ETL-операции, а также предоставлять другим пользователям права на управление объектами.

Чтобы настроить роль администратора:

  1. Создайте роль metastore_admin:

    ALTER SYSTEM SET duckdb.postgres_role TO 'metastore_admin';
  2. Предоставьте роли metastore_admin полный доступ к схеме pgpro_metastore и перезагрузите сервер pgpro_metastore.

3.1.2. Сценарий управления правами #

Рассмотрим сценарий управления правами, в котором они предоставляются по иерархии: от главного администратора локальным администраторам групп пользователей и аналитикам (обратитесь к диаграмме ниже).

Рисунок 3.1.


Где:

  • Суперпользователь — это суперпользователь Postgres Pro с полными правами.

  • metastore_admin — главный администратор с ролью metastore_admin, который является владельцем всех объектов pgpro_metastore.

  • Администраторы A и B — это локальные администраторы групп пользователей, у которых есть доступ к объектам pgpro_metastore, связанным с этими группами.

    Права этим администраторам предоставляет главный администратор. Локальные администраторы в свою очередь могут предоставлять права аналитикам в рамках своих групп.

  • Аналитики A, B, C и D — пользователи, которые работают с OLAP-данными.

Чтобы настроить этот сценарий управления правами:

  1. Создайте пользователей в базе данных от имени суперпользователя:

    postgres=# SELECT current_user;
    current_user
    --------------
    root
    postgres=# CREATE USER metastore_admin;
    postgres=# CREATE USER admin_a;
    postgres=# CREATE USER admin_b;
    postgres=# CREATE USER analyst_a;
    postgres=# CREATE USER analyst_b;
    postgres=# CREATE USER analyst_c;
    postgres=# CREATE USER analyst_d;
  2. Создайте аналитические схемы для групп пользователей:

    postgres=# SELECT current_user;
    current_user
    --------------
    root
    postgres=# CREATE SCHEMA schema_a;
    postgres=# CREATE SCHEMA schema_b;
  3. Предоставьте пользователю admin_a права на аналитическую схему schema_a:

    postgres=# SELECT current_user;
    current_user
    --------------
    root
    postgres=# GRANT ALL ON SCHEMA schema_a to metastore_admin WITH GRANT OPTION;
    postgres=# GRANT ALL ON SCHEMA schema_a to admin_a WITH GRANT OPTION;
  4. Предоставьте пользователю metastore_admin права на аналитическую схему metastore и сделайте его администратором:

    postgres=# SELECT current_user;
    current_user
    --------------
    root
    postgres=# GRANT ALL ON SCHEMA metastore TO metastore_admin ;
    postgres=# ALTER SYSTEM SET duckdb.postgres_role TO 'metastore_admin';
  5. Перезапустите сервер.

Теперь пользователь metastore_admin может настроить каталог pgpro_metastore:

postgres=> SELECT current_user;
  current_user
-----------------
metastore_admin
postgres=> SELECT metastore.define_catalog_connection('localhost','5433','postgres','','');
postgres=> SELECT metastore.init();

Предположим, в схеме группы A есть таблица Postgres Pro, которую для выполнения аналитических запросов необходимо перенести в pgpro_metastore:

  1. Пользователь metastore_admin создаёт хранилище и аналитическую таблицу:

    postgres=> SELECT current_user;
      current_user
    -----------------
    metastore_admin
    postgres=> SELECT metastore.add_storage('mt_storage', 'file:///tmp/mt_storage/', 'file:///tmp/mt_storage/tmp_dir/');
    postgres=> SELECT metastore.add_table('mt_table1', 'mt_storage', 'schema_alpha.pg_table');
  2. Пользователь metastore_admin предоставляет права пользователю admin_a:

    postgres=> SELECT current_user;
      current_user
    -----------------
    metastore_admin
    postgres=> GRANT ALL ON metastore.t_mt_table1_00001 TO admin_a WITH GRANT OPTION;

    Параметр WITH GRANT OPTION позволяет пользователю admin_a при необходимости предоставлять права другим пользователям.

  3. Пользователь admin_a копирует таблицу Postgres Pro в аналитическую таблицу и создаёт представление Postgres Pro:

    postgres=> SELECT current_user;
    current_user
    --------------
    admin_a
    postgres=> SELECT metastore.copy_table('mt_table1', 'select * from schema_a.pg_table');
    postgres=> SELECT metastore.create_view('mt_table1', 'schema_a');
  4. Как владелец объекта пользователь metastore_admin разрешает пользователю admin_a предоставлять права на чтение этого объекта другим пользователям:

    postgres=> SELECT current_user;
      current_user
    -----------------
    metastore_admin
    postgres=> GRANT SELECT ON schema_a.t_mt_table1_00001 TO admin_a WITH GRANT OPTION ;
  5. Пользователь admin_a предоставляет аналитикам права на чтение представления Postgres Pro:

    postgres=> SELECT current_user;
    current_user
    --------------
    admin_a
    (1 row)
    
    postgres=> GRANT USAGE ON SCHEMA schema_a to analyst_a;
    postgres=> GRANT SELECT ON schema_a.t_mt_table1_00001 TO analyst_a;
  6. Аналитик читает аналитическую таблицу:

    postgres=> SELECT current_user;
      current_user
      --------------
      analyst_a
      (1 row)
    
      postgres=> SELECT count(*) FROM schema_a.mt_table1 ;
      count
      -------
          50
      (1 row)

3.1.3. ETL-операции и права на них #

В этом разделе описываются права, необходимые для выполнения доступных ETL-операций.

cleanup #

Только пользователь metastore_admin.

define_catalog_connection() #

Только пользователь metastore_admin.

Эта операция является SECURITY DEFINER (определяющей контекст безопасности) и может выполняться только суперпользователем. Она может потребовать изменения в системном каталоге СУБД Postgres Pro AXE, к которому у пользователя metastore_admin нет права доступа.

init() #

Только пользователь metastore_admin.

add_storage/remove_storage #

Только пользователь metastore_admin.

Когда выполняется одна из этих ETL-операций, прокси-таблица, которой владеет пользователь metastore_admin и которая относится к хранилищу, создаётся в схеме pgpro_metastore или удаляется из неё.

add_table/remove_table #

Только пользователь metastore_admin.

Когда выполняется одна из этих ETL-операций, прокси-таблица, которой владеет пользователь metastore_admin и которая относится к таблице, создаётся в схеме pgpro_metastore или удаляется из неё.

add_folder/remove_folder #

Только пользователь metastore_admin.

Когда выполняется одна из этих ETL-операций, прокси-таблица, которой владеет пользователь metastore_admin и которая относится к общему каталогу, создаётся в схеме pgpro_metastore или удаляется из неё.

add_files #

Пользователи, которым предоставлены права:

copy_table #

Пользователи, которым предоставлены права:

Эта ETL-операция является SECURITY DEFINER (определяющей контекст безопасности).

create_view #

Пользователи, которым предоставлены права:

Эта ETL-операция является SECURITY DEFINER (определяющей контекст безопасности).

3.1.4. Примеры использования #

Пример 3.1.

Чтобы создать роль mt_admin, выполните следующий запрос:

CREATE USER mt_admin;
GRANT ALL ON SCHEMA metastore TO mt_admin;
ALTER SYSTEM SET duckdb.postgres_role TO 'mt_admin';

Затем перезагрузите сервер.


Пример 3.2.

Чтобы предоставить пользователю user1 право для добавления OLAP-данных в аналитическую таблицу mt_table1 из общего каталога mt_storage, выполните следующий запрос:

postgres=# GRANT INSERT ON metastore.t_mt_table1_00001 TO user1;
postgres=# GRANT SELECT ON metastore.f_mt_folder to user1;

3.1.5. Секреты #

Секреты DuckDB можно настроить с помощью вспомогательных функций или обёртки сторонних данных для более продвинутых сценариев.

Секреты хранятся в виде комбинаций SERVER и USER MAPPING в обёртке сторонних данных DuckDB. В USER MAPPING размещаются конфиденциальные элементы, такие как token, session_token и secret. Каждый раз, когда pgpro_axe создаёт экземпляр DuckDB, а также при изменении секрета, секреты загружаются в менеджер секретов DuckDB как непостоянные.

Важно

Не предоставляйте право USAGE для обёртки сторонних данных duckdb обычным пользователям.

Владелец стороннего сервера может создавать сопоставления для любого пользователя. Поэтому это право следует предоставлять только администраторам. В противном случае обычный пользователь смог бы создавать секреты для определённых областей доступа без ведома других пользователей.

Postgres Pro AXE поддерживает следующие типы секретов:

Секретами можно управлять с помощью функций pgpro_axe.

3.1.5.1. Простые секреты #

Настроить учётные данные проще всего с использованием вспомогательных функций:

Пример 3.3.

  -- Базовый секрет S3 (наиболее распространённый)
  SELECT duckdb.create_simple_secret(
      type := 'S3',
      key_id := 'your_access_key_id',
      secret := 'your_secret_access_key',
      region := 'us-east-1'
  );
  

У этой функции есть другие параметры:

Пример 3.4.

  SELECT duckdb.create_simple_secret(
      type          := 'S3',          -- Тип: один из (S3, GCS, R2)
      key_id        := 'идентификатор_ключа_доступа',
      secret        := 'xxx',
      session_token := 'yyy',         -- (необязательно)
      region        := 'us-east-1',   -- (необязательно)
      url_style     := 'xxx',         -- (необязательно)
      provider      := 'xxx',         -- (необязательно)
      endpoint      := 'xxx',         -- (необязательно)
      scope         := 'xxx',         -- (необязательно)
      validation    := 'xxx',         -- (необязательно)
      use_ssl       := 'xxx'          -- (необязательно)
  )
  

3.1.5.2. Секреты с поставщиком credential_chain #

Для более продвинутых сценариев можно определять секреты с SERVER и USER MAPPING в обёртке сторонних данных DuckDB:

Пример 3.5.

    CREATE SERVER my_s3_secret
    TYPE 's3'
    FOREIGN DATA WRAPPER duckdb
    OPTIONS (PROVIDER 'credential_chain');
  

3.1.5.3. Секреты с secret_access_key #

Если секрет содержит конфиденциальную информацию, необходимо создать дополнительный USER MAPPING:

Пример 3.6.

    CREATE SERVER my_s3_secret TYPE 's3' FOREIGN DATA WRAPPER duckdb;

    CREATE USER MAPPING FOR CURRENT_USER SERVER my_s3_secret
    OPTIONS (KEY_ID 'my_secret_key', SECRET 'my_secret_value');
  

Поддерживаемые DuckDB типы секретов можно использовать, если установлено соответствующее расширение. За более подробной информацией обратитесь к официальной документации DuckDB.