Назначение привилегий и ролей пользователям PostgreSQL
Атомарные полномочия в PostgreSQL называются привилегиями, группы полномочий — ролями. Подробнее об организации прав доступа читайте в документации PostgreSQL
Пользователь, создаваемый вместе с кластером Managed Service for PostgreSQL, является владельцем первой базы данных в кластере. Вы можете создавать других пользователей и настраивать их права по своему усмотрению:
- Изменить список ролей пользователя.
- Выдать привилегию пользователю.
- Отозвать привилегию у пользователя.
Важно
Для новых пользователей привилегия на создание таблиц в схеме public
зависит от версии PostgreSQL:
- 14 и ниже — привилегия выдается автоматически и отозвать ее нельзя.
- 15 и выше — привилегию необходимо предоставить пользователю вручную.
Изменить список ролей пользователя
Для назначения роли пользователю используйте интерфейсы Yandex Cloud: назначение роли запросом GRANT
отменится при следующей операции с базой.
Сервис Managed Service for PostgreSQL не дает доступа к предопределенным ролям
mdb_superuser
mdb_admin
mdb_monitor
mdb_replication
Максимальные привилегии при работе с кластером имеет пользователь с ролью mdb_superuser
. Подробнее см. в разделе Назначение ролей.
Примечание
В Managed Service for PostgreSQL не предусмотрено создание пользовательских ролей. Права пользователя определяются совокупностью назначенных ему привилегий.
- Перейдите на страницу каталога и выберите сервис Managed Service for PostgreSQL.
- Нажмите на имя нужного кластера и выберите вкладку Пользователи.
- В строке с именем нужного пользователя нажмите на значок
и выберите пункт Настроить. - Разверните список Настройки СУБД и в поле Grants выберите роли, которые хотите назначить пользователю.
- Нажмите кнопку Сохранить.
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --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
mdb_superuser
-
-
Убедитесь, что запрос был выполнен успешно, изучив ответ сервера.
-
Получите 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
с помощью учетной записи владельца БД. -
Чтобы выдать права доступа только к таблице
Products
в схеме по умолчаниюpublic
, выполните команду:GRANT SELECT ON public.Products TO user2;
-
Чтобы выдать доступ ко всем таблицам схемы
myschema
, выполните команду:GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO user2; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA myschema to user2;
-
(Опционально) Чтобы изменить привилегии по умолчанию, выполните команду:
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;
Для отзыва выданных привилегий выполните команды:
REVOKE SELECT ON public.Products FROM user2;
REVOKE SELECT ON ALL TABLES IN SCHEMA myschema FROM user2;
REVOKE USAGE ON SCHEMA myschema FROM user2;
Выдать привилегию пользователю через 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
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
-
Чтобы отозвать выданную привилегию, удалите ее из списка privileges
и подтвердите изменение ресурсов.