Assigning privileges and roles to PostgreSQL users
PostgreSQL manages database access permissions using roles. Roles can own database objects and have privileges.
In PostgreSQL, a user is a role that can log in to the database. The user created for a new Managed Service for PostgreSQL cluster is the owner of its first database.
You can create more users and configure their permissions as needed:
Warning
For new users, the privilege to create tables in the public schema depends on the PostgreSQL version:
- Version 14 and below: The privilege is granted automatically and cannot be revoked.
- 15 and above: The privilege must be granted to the user manually.
For more information about creating users
Editing user’s roles
To assign a role to a user, use the Yandex Cloud interfaces. A role assigned via a GRANT statement will be revoked during the next database operation.
Note
PostgreSQL supports nested roles. A user, i.e., a role allowed to authenticate in a database, may be a member of one or multiple other roles and inherit their permissions. Learn more about role membership
Managed Service for PostgreSQL does not allow access to predefined roles
mdb_adminmdb_monitormdb_replicationmdb_superuser
Note
You cannot create custom roles in Managed Service for PostgreSQL. A user’s permissions are determined by the combination of granted privileges.
- Go to Managed Service for PostgreSQL.
- Click the name of your cluster and open the Users tab.
- Find the user you want to update in the list, click
in their row, and select Configure. - Expand the DBMS settings list and select the roles you want to assign to the user in the Grants field.
- Click Save.
If you do not have the Yandex Cloud CLI installed yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the yc config set folder-id <folder_ID> command. You can also set a different folder for any specific command using the --folder-name or --folder-id parameter.
To assign roles to a cluster user, provide the list of required roles in the --grants argument. This will completely overwrite the existing roles. To add or remove roles from the current list, you must first retrieve the user’s current roles using the yc managed-postgresql user get command.
To assign roles, run this command:
yc managed-postgresql user update <username> \
--grants=<role_1>,<role_2> \
--cluster-id <cluster_ID>
You can get the cluster name from the folder’s cluster list and the username from the list of users.
To assign roles to a cluster user:
-
Open the current Terraform configuration file describing your infrastructure.
For more information about creating this file, see this guide.
For a complete list of configurable fields of Managed Service for PostgreSQL cluster user accounts, refer to the Terraform provider guides.
-
Locate the user's
yandex_mdb_postgresql_userresource. -
Add the
grantsattribute with the list of required roles:resource "yandex_mdb_postgresql_user" "<username>" { ... name = "<username>" grants = [ "<role_1>","<role_2>" ] ... } -
Validate your configuration.
-
In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
-
Run this command:
terraform validateTerraform will show any errors found in your configuration files.
-
-
Confirm resource changes.
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
-
-
Get an IAM token for API authentication and place it in an environment variable:
export IAM_TOKEN="<IAM_token>" -
To check the list of current roles, call the User.Get method, for instance, via the following cURL
request:curl \ --request GET \ --header "Authorization: Bearer $IAM_TOKEN" \ --url 'https://mdb.api.cloud.yandex.net/managed-postgresql/v1/clusters/<cluster_ID>/users/<username>'You can get the cluster ID from the folder’s cluster list, and the username from the cluster’s user list.
You can find the list of current roles in the
grantsfield of the command output. -
To change the list of roles for a user, call the User.Update method, for instance, via the following request:
Warning
The API method will assign default values to all the parameters of the object you are modifying unless you explicitly provide them in your request. To avoid this, list the settings you want to change in the
updateMaskparameter as a single comma-separated string.curl \ --request PATCH \ --header "Authorization: Bearer $IAM_TOKEN" \ --header "Content-Type: application/json" \ --url 'https://mdb.api.cloud.yandex.net/managed-postgresql/v1/clusters/<cluster_ID>/users/<username>' \ --data '{ "updateMask": "grants", "grants": [ "role_1", "role_2", ..., "role_N" ] }'Where:
-
updateMask: Comma-separated list of settings you want to update.Here, we provide only one setting.
-
grants: New roles as a string array. Each string represents an individual role. The possible values are:mdb_adminmdb_monitormdb_replicationmdb_superuser
-
-
Check the server response to make sure your request was successful.
-
Get an IAM token for API authentication and place it in an environment variable:
export IAM_TOKEN="<IAM_token>" -
Clone the cloudapi
repository:cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapiBelow, we assume that the repository contents reside in the
~/cloudapi/directory. -
To check the list of current roles, call UserService.Get method, for instance, via the following gRPCurl
request: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": "<cluster_ID>", "user_name": "<username>" }' \ mdb.api.cloud.yandex.net:443 \ yandex.cloud.mdb.postgresql.v1.UserService.GetYou can find the list of current roles in the
grantsfield of the command output. -
To change the list of roles for a user, call UserService.Update method, for instance, via the following request:
Warning
The API method will assign default values to all the parameters of the object you are modifying unless you explicitly provide them in your request. To avoid this, list the settings you want to change in the
update_maskparameter as an array ofpaths[]strings.Format for listing settings
"update_mask": { "paths": [ "<setting_1>", "<setting_2>", ... "<setting_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": "<cluster_ID>", "user_name": "<username>", "update_mask": { "paths": [ "grants" ] }, "grants": [ "role_1", "role_2", ..., "role_N" ] }' \ mdb.api.cloud.yandex.net:443 \ yandex.cloud.mdb.postgresql.v1.UserService.UpdateWhere:
-
update_mask: List of settings you want to update as an array of strings (paths[]).Here, we provide only one setting.
-
grants: New roles as a string array. Each string represents an individual role. The possible values are:mdb_adminmdb_monitormdb_replicationmdb_superuser
You can get the cluster ID from the folder’s cluster list, and the username from the list of cluster users.
-
-
Check the server response to make sure your request was successful.
Granting a privilege to a user
- Connect to the database using the owner's account.
- Run the
GRANTcommand. For full command syntax, see this PostgreSQL guide .
You can only grant user privileges via Terraform in a cluster that has publicly accessible hosts.
You can grant user privileges via Terraform using a third-party tool, Terraform Provider for PostgreSQL
Note
Terraform Provider for PostgreSQL is not part of Managed Service for PostgreSQL. Therefore, it is not maintained by Yandex Cloud support and development teams and its use falls outside the scope of the Yandex Managed Service for PostgreSQL Terms of Use
To grant a privilege to a cluster user:
-
Add the
postgresqlprovider to therequired_providerssection in the provider configuration file:terraform { required_providers { ... postgresql = { source = "cyrilgdn/postgresql" } ... } } -
Open the Terraform configuration file describing your infrastructure.
For more information about creating this file, see this guide.
-
Add the
postgresqlprovider and configure it to access your target database using its owner’s credentials:provider "postgresql" { host = <host_FQDN> port = 6432 database = <DB_name> username = <DB_owner_username> password = <user_password> }For instructions on retrieving a host’s FQDN, see this guide.
The full list of settings is available in the provider documentation
. -
Add the
postgresql_grantresource:resource "postgresql_grant" "<resource_name>" { database = "<DB_name>" role = "<username>" object_type = "<object_type>" privileges = ["<list_of_privileges>"] schema = "<schema>" objects = ["<list_of_objects>"] columns = ["<list_of_columns>"] with_grant_option = <permission_to_grant_privileges> }Where:
<resource_name>: Name of the Terraform resource that grants the privileges. This name must be unique within the Terraform manifest.database: Name of the target database for granting privileges.role: Name of the user receiving the privileges.object_type: Type of the target PostgreSQL object for granting privileges. The possible values are:database,schema,table,sequence,function,procedure,routine,foreign_data_wrapper,foreign_server,column.privileges: Array of privileges. The possible values areSELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER,CREATE,CONNECT,TEMPORARY,EXECUTEandUSAGE. For privilege descriptions see this PostgreSQL article .schema: Target schema for granting privileges. You cannot use this option with thedatabaseobject type.objects: Array of target objects for granting privileges. This is an optional argument. If you omit it, the system will grant privileges on all objects of the specified type. You cannot use this option withdatabaseandschemaobject types. For thecolumnobject type, the array of target objects cannot contain more than one item.columns: Array of target columns for granting privileges. This argument is required for thecolumnobject type and cannot be used with any other type.with_grant_option: Iftrue, a user with the granted privileges can grant them to other users. This is an optional argument. The default value isfalse.
-
Reinitialize Terraform:
terraform init -
Validate your configuration.
-
In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
-
Run this command:
terraform validateTerraform will show any errors found in your configuration files.
-
-
Confirm resource changes.
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
-
Revoking a privilege from a user
- Connect to the database using the owner's account.
- Run the
REVOKEcommand. For full command syntax, see this PostgreSQL guide .
If you previously granted a privilege using Terraform:
-
Open the Terraform configuration file describing your infrastructure.
-
In the
postgresql_grantsection, remove the privilege you want to revoke from theprivilegesattribute.To revoke all privileges, leave the
privilegesarray empty or remove the entirepostgresql_grantsection. -
Validate your configuration.
-
In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
-
Run this command:
terraform validateTerraform will show any errors found in your configuration files.
-
-
Confirm resource changes.
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
-
Examples
Add a user with read-only permissions
Alert
Do not use this example for users created with Terraform as subsequent changes made via Terraform may overwrite privileges granted via SQL.
To add a new user2 account with read-only access for the db1 database to an existing cluster:
-
Create a user named
user2. While creating the user, specify which databases they can access. -
Connect to the
db1database as the owner. -
Grant
user2the required permissions.Examples:
-
Grant access to the
Productstable in the defaultpublicschema:GRANT SELECT ON public.Products TO user2; -
Grant access to all objects in
myschema:GRANT USAGE ON SCHEMA myschema TO user2; -
Grant access to all tables and sequences in
myschema:GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO user2; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA myschema to user2; -
Grant execution permission for
my_functioninmyschema:GRANT EXECUTE ON FUNCTION myschema.my_function TO user2; -
Change the default privileges for tables and sequences in
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;The
ALTER DEFAULT PRIVILEGEScommands allow you to change the default access privileges for future objects, without affecting existing ones. In the example above, we change default privileges for newmyschematables and sequences.To update privileges for existing objects, use the
GRANTandREVOKEstatements.
-
You can only grant user privileges via Terraform in a cluster with publicly accessible hosts.
You can grant user privileges via Terraform using the third-party Terraform Provider for PostgreSQL
Note
Terraform Provider for PostgreSQL is not part of Managed Service for PostgreSQL. Therefore, it is not maintained by Yandex Cloud support and development teams and its use falls outside the scope of the Yandex Managed Service for PostgreSQL Terms of Use
To learn more about granting privileges, see Granting a privilege to a user.
Suppose you have a cluster named mypg with a user named user1 as its owner. To add a new cluster account user2 with read-only access to the tables in the public schema of the db1 database, do the following:
-
Add the
postgresqlprovider to therequired_providerssection in the provider configuration file:terraform { required_providers { ... postgresql = { source = "cyrilgdn/postgresql" } ... } } -
Open the Terraform configuration file describing your infrastracture.
-
Add the
yandex_mdb_postgresql_userresource: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 } } -
Add the
postgresqlprovider and configure its access permissions to thedb1database: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 } -
Add the
postgresql_grantresource with the following attributes: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" } -
Reinitialize Terraform:
terraform init -
Validate your configuration.
-
In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
-
Run this command:
terraform validateTerraform will show any errors found in your configuration files.
-
-
Confirm resource changes.
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
-
Revoking privileges
-
Connect to the
db1database as the owner. -
Revoke access privileges from
user2.Examples:
-
Revoke all privileges for the tables within the
myschemaschema:REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschema FROM user2; -
Revoke access to the
Productstable in the defaultpublicschema:REVOKE SELECT ON public.Products FROM user2; -
Revoke access to all tables in
myschema:REVOKE SELECT ON ALL TABLES IN SCHEMA myschema FROM user2; -
Revoke access to all objects in
myschema:REVOKE USAGE ON SCHEMA myschema FROM user2;
-
-
Open the Terraform configuration file used for granting privileges.
-
In the
postgresql_grantsection, remove the privilege you want to revoke from theprivilegesattribute.To revoke all privileges, leave the
privilegesarray empty or remove the entirepostgresql_grantsection.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" } -
Validate your configuration.
-
In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
-
Run this command:
terraform validateTerraform will show any errors found in your configuration files.
-
-
Confirm resource changes.
-
Run this command to view the planned changes:
terraform planIf you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
-
If everything looks correct, apply the changes:
-
Run this command:
terraform apply -
Confirm updating the resources.
-
Wait for the operation to complete.
-
-