Назначение привилегий и ролей пользователям PostgreSQL
PostgreSQL управляет правами доступа к базе данных с помощью ролей. Роли могут владеть объектами базы данных и иметь привилегии.
Пользователь в PostgreSQL — это роль, которая может авторизоваться в базе данных. Пользователь, создаваемый вместе с кластером Managed Service for PostgreSQL, является владельцем первой базы данных в кластере.
Вы можете создавать других пользователей и настраивать их права по своему усмотрению:
- Изменить список ролей пользователя.
- Выдать привилегию пользователю.
- Отозвать привилегию у пользователя.
Важно
Для новых пользователей привилегия на создание таблиц в схеме public зависит от версии PostgreSQL:
- 14 и ниже — привилегия выдается автоматически и отозвать ее нельзя.
- 15 и выше — привилегию необходимо предоставить пользователю вручную.
Подробнее о создании пользователей
Изменить список ролей пользователя
Для назначения роли пользователю используйте интерфейсы Yandex Cloud: назначение роли запросом GRANT отменится при следующей операции с базой.
Примечание
В PostgreSQL роли могут включать в себя другие роли. Пользователь (то есть роль, которая может авторизоваться в базе данных) может быть членом одной или нескольких других ролей и получать их права. Подробнее о членстве в ролях
Сервис Managed Service for PostgreSQL не дает доступа к предопределенным ролям
- mdb_admin
- mdb_monitor
- mdb_replication
Примечание
В Managed Service for PostgreSQL не предусмотрено создание пользовательских ролей. Права пользователя определяются совокупностью назначенных ему привилегий.
- Перейдите на страницу каталога и выберите сервис Managed Service for PostgreSQL.
- Нажмите на имя нужного кластера и выберите вкладку Пользователи.
- В строке с именем нужного пользователя нажмите на значок - Разверните список Настройки СУБД и в поле Grants выберите роли, которые хотите назначить пользователю.
- Нажмите кнопку Сохранить.
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
Чтобы назначить роли пользователю кластера, передайте список нужных ролей в параметре --grants. Имеющиеся роли будут полностью перезаписаны: если вы хотите дополнить или уменьшить имеющийся список, сначала запросите текущие роли с информацией о пользователе командой yc managed-postgresql user get.
Чтобы назначить роли, выполните команду:
yc managed-postgresql user update <имя_пользователя> \
       --grants=<роль1>,<роль2> \
       --cluster-id <идентификатор_кластера>
Имя кластера можно запросить со списком кластеров в каталоге, имя пользователя — со списком пользователей.
Чтобы назначить роли пользователю кластера:
- 
Откройте актуальный конфигурационный файл Terraform с планом инфраструктуры. О том, как создать такой файл, см. в разделе Создание кластера. Полный список доступных для изменения полей конфигурации пользователей кластера Managed Service for PostgreSQL см. в документации провайдера Terraform. 
- 
Найдите ресурс yandex_mdb_postgresql_userнужного пользователя.
- 
Добавьте атрибут grantsсо списком нужных ролей:resource "yandex_mdb_postgresql_user" "<имя_пользователя>" { ... name = "<имя_пользователя>" grants = [ "<роль1>","<роль2>" ] ... }
- 
Проверьте корректность настроек. - 
В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры. 
- 
Выполните команду: terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет. 
 
- 
- 
Подтвердите изменение ресурсов. - 
Выполните команду для просмотра планируемых изменений: terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены. 
- 
Если вас устраивают планируемые изменения, внесите их: - 
Выполните команду: terraform apply
- 
Подтвердите изменение ресурсов. 
- 
Дождитесь завершения операции. 
 
- 
 
- 
- 
Получите IAM-токен для аутентификации в API и поместите токен в переменную среды окружения: export IAM_TOKEN="<IAM-токен>"
- 
Чтобы проверить список текущих ролей, воспользуйтесь методом User.Get и выполните запрос, например, с помощью cURL curl \ --request GET \ --header "Authorization: Bearer $IAM_TOKEN" \ --url 'https://mdb.api.cloud.yandex.net/managed-postgresql/v1/clusters/<идентификатор_кластера>/users/<имя_пользователя>'Идентификатор кластера можно запросить со списком кластеров в каталоге, а имя пользователя — со списком пользователей в кластере. Список текущих ролей указан в параметре grantsв выводе команды.
- 
Чтобы изменить список ролей пользователя, воспользуйтесь методом User.Update и выполните запрос: Важно Метод API переопределит все параметры изменяемого объекта, которые не были явно переданы в запросе, на значения по умолчанию. Чтобы избежать этого, перечислите настройки, которые вы хотите изменить, в параметре updateMask(одной строкой через запятую).curl \ --request PATCH \ --header "Authorization: Bearer $IAM_TOKEN" \ --header "Content-Type: application/json" \ --url 'https://mdb.api.cloud.yandex.net/managed-postgresql/v1/clusters/<идентификатор_кластера>/users/<имя_пользователя>' \ --data '{ "updateMask": "grants", "grants": [ "роль_1", "роль_2", ..., "роль_N" ] }'Где: - 
updateMask— перечень изменяемых параметров в одну строку через запятую.В данном случае передается только один параметр. 
- 
grants— массив строк с новыми ролями. Каждая строка соответствует отдельной роли. Возможные значения:- mdb_admin
- mdb_monitor
- mdb_replication
 
 
- 
- 
Убедитесь, что запрос был выполнен успешно, изучив ответ сервера. 
- 
Получите IAM-токен для аутентификации в API и поместите токен в переменную среды окружения: export IAM_TOKEN="<IAM-токен>"
- 
Клонируйте репозиторий cloudapi cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapiДалее предполагается, что содержимое репозитория находится в директории ~/cloudapi/.
- 
Чтобы проверить список текущих ролей, воспользуйтесь вызовом UserService.Get и выполните запрос, например, с помощью gRPCurl grpcurl \ -format json \ -import-path ~/cloudapi/ \ -import-path ~/cloudapi/third_party/googleapis/ \ -proto ~/cloudapi/yandex/cloud/mdb/postgresql/v1/user_service.proto \ -rpc-header "Authorization: Bearer $IAM_TOKEN" \ -d '{ "cluster_id": "<идентификатор_кластера>", "user_name": "<имя_пользователя>" }' \ mdb.api.cloud.yandex.net:443 \ yandex.cloud.mdb.postgresql.v1.UserService.GetСписок текущих ролей указан в параметре grantsв выводе команды.
- 
Чтобы изменить список ролей пользователя, воспользуйтесь вызовом UserService.Update и выполните запрос: Важно Метод API переопределит все параметры изменяемого объекта, которые не были явно переданы в запросе, на значения по умолчанию. Чтобы избежать этого, перечислите настройки, которые вы хотите изменить, в параметре update_mask(в виде массива строкpaths[]).Формат перечисления настроек"update_mask": { "paths": [ "<настройка_1>", "<настройка_2>", ... "<настройка_N>" ] }grpcurl \ -format json \ -import-path ~/cloudapi/ \ -import-path ~/cloudapi/third_party/googleapis/ \ -proto ~/cloudapi/yandex/cloud/mdb/postgresql/v1/user_service.proto \ -rpc-header "Authorization: Bearer $IAM_TOKEN" \ -d '{ "cluster_id": "<идентификатор_кластера>", "user_name": "<имя_пользователя>", "update_mask": { "paths": [ "grants" ] }, "grants": [ "роль_1", "роль_2", ..., "роль_N" ] }' \ mdb.api.cloud.yandex.net:443 \ yandex.cloud.mdb.postgresql.v1.UserService.UpdateГде: - 
update_mask— перечень изменяемых параметров в виде массива строкpaths[].В данном случае передается только один параметр. 
- 
grants— массив строк с новыми ролями. Каждая строка соответствует отдельной роли. Возможные значения:- mdb_admin
- mdb_monitor
- mdb_replication
- mdb_superuser
 
 Идентификатор кластера можно запросить со списком кластеров в каталоге, а имя пользователя — со списком пользователей в кластере. 
- 
- 
Убедитесь, что запрос был выполнен успешно, изучив ответ сервера. 
Выдать привилегию пользователю
- Подключитесь к базе данных с помощью учетной записи владельца базы данных.
- Выполните команду GRANT. Подробное описание синтаксиса команды смотрите в документации PostgreSQL
Выдать привилегию пользователю через Terraform можно только в кластере с хостами в публичном доступе.
Вы можете выдавать привилегии пользователям через Terraform, используя сторонний провайдер — Terraform Provider for PostgreSQL
Примечание
Terraform Provider for PostgreSQL не является частью сервиса Managed Service for PostgreSQL и не сопровождается командой разработки и службой поддержки Yandex Cloud, а его использование не входит в условия использования Yandex Managed Service for PostgreSQL
Чтобы выдать привилегию пользователю кластера:
- 
Добавьте провайдер postgresqlв блокrequired_providersв файле с настройками провайдера:terraform { required_providers { ... postgresql = { source = "cyrilgdn/postgresql" } ... } }
- 
Откройте конфигурационный файл Terraform с планом инфраструктуры. О том, как создать такой файл, см. в разделе Создание кластера. 
- 
Добавьте провайдер postgresqlи настройте для него доступ к интересующей базе данных от имени ее владельца:provider "postgresql" { host = <FQDN_хоста> port = 6432 database = <имя_БД> username = <имя_пользователя_владельца_БД> password = <пароль_пользователя> }О том, как получить FQDN хоста, см. инструкцию. Полный список настроек см. в документации провайдера - 
Добавьте ресурс postgresql_grant:resource "postgresql_grant" "<название_ресурса>" { database = "<имя_БД>" role = "<имя_пользователя>" object_type = "<тип_объекта>" privileges = ["<список_привилегий>"] schema = "<схема>" objects = ["<список_объектов>"] columns = ["<список_столбцов>"] with_grant_option = <разрешение_на_выдачу_привилегий> }Где: - <название_ресурса>— название Terraform-ресурса с привилегиями. Должно быть уникальным в рамках манифеста Terraform.
- database— имя базы данных, на которую выдаются привилегии.
- role— имя пользователя, которому выдаются привилегии.
- object_type— тип PostgreSQL-объекта, на который выдаются привилегии. Возможные значения:- database,- schema,- table,- sequence,- function,- procedure,- routine,- foreign_data_wrapper,- foreign_server,- column.
- privileges— массив выдаваемых привилегий. Возможные значения:- SELECT,- INSERT,- UPDATE,- DELETE,- TRUNCATE,- REFERENCES,- TRIGGER,- CREATE,- CONNECT,- TEMPORARY,- EXECUTEи- USAGE. Описание привилегий см. в документации PostgreSQL- schema— схема, на которую выдаются привилегии. Нельзя задать, если выбран тип объекта- database.
- (Опционально) objects— массив объектов, на которые выдаются привилегии. Если параметр не задан, привилегии будут выданы на все объекты указанного типа. Нельзя задать, если выбран тип объектаdatabaseилиschema. Если выбран тип объектаcolumn, массив может содержать только одно значение.
- columns— массив столбцов, на которые выдаются привилегии. Параметр обязателен, если выбран тип объекта- column. Нельзя задать, если выбран любой другой тип объекта, кроме- column.
- (Опционально) with_grant_option— еслиtrue, то пользователь с выданными привилегиями сможет выдавать эти привилегии другим пользователям. По умолчаниюfalse.
 
- 
Повторно инициализируйте Terraform: terraform init
- 
Проверьте корректность настроек. - 
В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры. 
- 
Выполните команду: terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет. 
 
- 
- 
Подтвердите изменение ресурсов. - 
Выполните команду для просмотра планируемых изменений: terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены. 
- 
Если вас устраивают планируемые изменения, внесите их: - 
Выполните команду: terraform apply
- 
Подтвердите изменение ресурсов. 
- 
Дождитесь завершения операции. 
 
- 
 
- 
Отозвать привилегию у пользователя
- Подключитесь к базе данных с помощью учетной записи владельца базы данных.
- Выполните команду REVOKE. Подробное описание синтаксиса команды смотрите в документации PostgreSQL
Если вы ранее выдали привилегию с использованием Terraform:
- 
Откройте конфигурационный файл Terraform с планом инфраструктуры. 
- 
В блоке postgresql_grantудалите привилегию, которую хотите отозвать, из параметраprivileges.Чтобы отозвать все привилегии, оставьте массив privilegesпустым или удалите ресурсpostgresql_grantцеликом.
- 
Проверьте корректность настроек. - 
В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры. 
- 
Выполните команду: terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет. 
 
- 
- 
Подтвердите изменение ресурсов. - 
Выполните команду для просмотра планируемых изменений: terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены. 
- 
Если вас устраивают планируемые изменения, внесите их: - 
Выполните команду: terraform apply
- 
Подтвердите изменение ресурсов. 
- 
Дождитесь завершения операции. 
 
- 
 
- 
Примеры
Добавить пользователя с правами только на чтение
Внимание
Не используйте этот пример, если пользователь создан с помощью Terraform: последующие изменения, сделанные через Terraform, могут отменить привилегии пользователя, сделанные через SQL.
Чтобы добавить в существующий кластер нового пользователя user2 с доступом только на чтение к базе данных db1:
- 
Создайте пользователя с именем user2. При этом выберите базы данных, к которым должен иметь доступ пользователь.
- 
Подключитесь к базе данных db1с помощью учетной записи владельца БД.
- 
Выдайте пользователю user2нужные права доступа.Примеры: - 
Разрешить доступ только к таблице Productsв схеме по умолчаниюpublic:GRANT SELECT ON public.Products TO user2;
- 
Разрешить доступ к объектам схемы myschema:GRANT USAGE ON SCHEMA myschema TO user2;
- 
Разрешить доступ ко всем таблицам и последовательностям схемы myschema:GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO user2; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA myschema to user2;
- 
Разрешить вызов функции my_functionв схемеmyschema:GRANT EXECUTE ON FUNCTION myschema.my_function TO user2;
- 
Изменить привилегии по умолчанию для таблиц и последовательностей схемы myschema:ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO user2; ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE, SELECT ON SEQUENCES TO user2;Команды ALTER DEFAULT PRIVILEGESпозволяют изменить права доступа к объектам (в данном случае — к таблицам и последовательностям схемыmyschema), которые будут созданы в будущем, но не затрагивают права, назначенные уже существующим объектам.Чтобы изменить привилегии существующих объектов, используйте команды GRANTиREVOKE.
 
- 
Выдать привилегию пользователю через Terraform можно только в кластере с хостами в публичном доступе.
Для выдачи привилегий пользователям через Terraform используется сторонний провайдер — Terraform Provider for PostgreSQL
Примечание
Terraform Provider for PostgreSQL не является частью сервиса Managed Service for PostgreSQL и не сопровождается командой разработки и службой поддержки Yandex Cloud, а его использование не входит в условия использования Yandex Managed Service for PostgreSQL
Подробнее о выдаче привилегий см. в разделе Выдать привилегию пользователю.
Допустим, существует кластер mypg с пользователем user1 в роли владельца. Чтобы добавить в него нового пользователя user2 с доступом только на чтение из таблиц в схеме public базы данных db1:
- 
Добавьте провайдер postgresqlв блокrequired_providersв файле с настройками провайдера:terraform { required_providers { ... postgresql = { source = "cyrilgdn/postgresql" } ... } }
- 
Откройте конфигурационный файл Terraform с планом инфраструктуры. 
- 
Добавьте ресурс yandex_mdb_postgresql_user:resource "yandex_mdb_postgresql_user" "user2" { cluster_id = yandex_mdb_postgresql_cluster.mypg.id name = "user2" password = "user2user2" permission { database_name = yandex_mdb_postgresql_database.db1.name } }
- 
Добавьте провайдер postgresqlи настройте для него доступ к базе данныхdb1:provider "postgresql" { host = yandex_mdb_postgresql_cluster.mypg.host[0].fqdn port = 6432 database = yandex_mdb_postgresql_database.db1.name username = yandex_mdb_postgresql_user.user1.name password = yandex_mdb_postgresql_user.user1.password }
- 
Добавьте ресурс postgresql_grantсо следующими атрибутами:resource "postgresql_grant" "readonly_tables" { database = yandex_mdb_postgresql_database.db1.name role = yandex_mdb_postgresql_user.user2.name object_type = "table" privileges = ["SELECT"] schema = "public" }
- 
Повторно инициализируйте Terraform: terraform init
- 
Проверьте корректность настроек. - 
В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры. 
- 
Выполните команду: terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет. 
 
- 
- 
Подтвердите изменение ресурсов. - 
Выполните команду для просмотра планируемых изменений: terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены. 
- 
Если вас устраивают планируемые изменения, внесите их: - 
Выполните команду: terraform apply
- 
Подтвердите изменение ресурсов. 
- 
Дождитесь завершения операции. 
 
- 
 
- 
Отозвать права доступа
- 
Подключитесь к базе данных db1с помощью учетной записи владельца БД.
- 
Отзовите у пользователя user2нужные права доступа.Примеры: - 
Отозвать все привилегии для таблиц схемы myschema:REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschema FROM user2;
- 
Отозвать доступ к таблице Productsв схеме по умолчаниюpublic:REVOKE SELECT ON public.Products FROM user2;
- 
Отозвать доступ ко всем таблицам схемы myschema:REVOKE SELECT ON ALL TABLES IN SCHEMA myschema FROM user2;
- 
Отозвать доступ к объектам схемы myschema:REVOKE USAGE ON SCHEMA myschema FROM user2;
 
- 
- 
Откройте конфигурационный файл Terraform, с помощью которого назначались привилегии. 
- 
В блоке postgresql_grantудалите привилегию, которую хотите отозвать, из параметраprivileges.Чтобы отозвать все привилегии, оставьте массив privilegesпустым или удалите ресурсpostgresql_grantцеликом.resource "postgresql_grant" "readonly_tables" { database = yandex_mdb_postgresql_database.db1.name role = yandex_mdb_postgresql_user.user2.name object_type = "table" privileges = [] schema = "public" }
- 
Проверьте корректность настроек. - 
В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры. 
- 
Выполните команду: terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет. 
 
- 
- 
Подтвердите изменение ресурсов. - 
Выполните команду для просмотра планируемых изменений: terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены. 
- 
Если вас устраивают планируемые изменения, внесите их: - 
Выполните команду: terraform apply
- 
Подтвердите изменение ресурсов. 
- 
Дождитесь завершения операции. 
 
- 
 
-