Manage Postgres roles
This feature is in Public Preview in the following regions: us-east-1
, us-west-2
, eu-west-1
, ap-southeast-1
, ap-southeast-2
, eu-central-1
, us-east-2
, ap-south-1
.
A Postgres role for the Lakebase database instance owner’s Databricks identity is created automatically.
Initially, only the owner of the instance can log in and access the instance through Postgres. To allow other Databricks identities to log in to the database instance, the Databricks identity must have a corresponding Postgres role.
This page describes how to add and manage additional Databricks identity-based roles in PostgreSQL.
Create Postgres roles and grant privileges for Databricks identities
Create Postgres roles using the Databricks UI or PostgreSQL queries.
Role management actions are governed by the permissions granted on the database instance. Ensure you have the appropriate level of access before attempting to manage roles.
- UI
- PostgreSQL
Users with CAN USE
permission on the database instance can view the existing Postgres roles associated with Databricks identities or add a role for their own identity to the instance.
Users with CAN MANAGE
can additionally create roles for other Databricks identities, including with additional privileges, and drop roles for any Databricks identity.
You can assign additional permissions to any desired users, groups, or service principals in the Database instances overview page.
-
Click Compute in the workspace sidebar.
-
Click Database instances.
-
Click the Permissions tab.
-
Click Add PostgreSQL role in the upper-right side.
-
For Workspace identity, enter a user, group, or service principal and select the Databricks identity. You must select a Databricks identity that doesn’t already have a Postgres role in the instance.
-
Select a Role membership. If you have
CAN MANAGE
permission on the database instance, you can add membership to thedatabricks_superuser
role and enable some role attributes. -
Select which PostgreSQL attributes to grant to the new role.
CREATEDB
: grants permission to create new databasesCREATEROLE
: grants permission to create new rolesBYPASS RLS
: grants permission to bypass all row-level security in the instance
-
Click Confirm.
Before creating new Postgres roles, verify that you meet the following requirements:
- You must have the
CREATE
andCREATE ROLE
permissions on the database. - You must authenticate and log in to Postgres as a Databricks identity (user, service principal, or group). Native Postgres authenticated sessions cannot create Databricks roles.
- Your authentication token must be valid and not expired at the time of role creation.
Use the databricks_create_role
function to add and create Databricks identity-based PostgreSQL roles. The custom PostgreSQL extension databricks_auth
provides the databricks_create_role
function.
-
Create the
databricks_auth
extension. Each Postgres database must have its own extension.PostgreSQLCREATE EXTENSION IF NOT EXISTS databricks_auth;
-
Use the
databricks_create_role
function to add and create new Postgres roles for Databricks identities. The role must not already exist. If a role with the same name exists, drop it before creating the Databricks identity-based role.PostgreSQLSELECT databricks_create_role('identity_name', 'identity_type');
The
identity_name
andidentity_type
parameters depend on the Databricks identity type:-
Databricks User:
- identity_name: Email of the user e.g.
myuser@databricks.com
- identity_type:
USER
PostgreSQLSELECT databricks_create_role('myuser@databricks.com','USER');
- identity_name: Email of the user e.g.
-
Databricks Service Principal:
- identity_name: Application ID of Service Principal e.g.
8c01cfb1-62c9-4a09-88a8-e195f4b01b08
- identity_type:
SERVICE_PRINCIPAL
PostgreSQLSELECT databricks_create_role('8c01cfb1-62c9-4a09-88a8-e195f4b01b08','SERVICE_PRINCIPAL');
- identity_name: Application ID of Service Principal e.g.
-
Databricks Group:
- identity_name: Name of the group (case sensitive):
My Group 123
- identity_type:
GROUP
PostgreSQLSELECT databricks_create_role('My Group 123','GROUP');
- identity_name: Name of the group (case sensitive):
-
-
A role created using
databricks_create_role
only has privileges granted toPUBLIC
after creation. To grant or revoke additional privileges, use the standard Postgres privilege management commandsGRANT
andREVOKE
.Give the role read permission to access a table.
PostgreSQLGRANT SELECT ON "my_schema"."my_table" TO <role-name>;
Remove write access to a table from the role.
PostgreSQLREVOKE INSERT, UPDATE, DELETE ON TABLE "my_schema"."my_table" FROM <role-name>;
Revoke all access to a database from the role.
PostgreSQLREVOKE CONNECT ON DATABASE "example_database" FROM <role-name>;
View Databricks identity roles
- UI
- PostgreSQL
You can see which users, groups, and service principals has a corresponding Postgres role in the Database instances overview page.
- Click Compute in the workspace sidebar.
- Click Database instances.
- Click the Permissions tab.
Use PostgreSQL queries to list all the Databricks identity roles created by default and from using the databricks_create_role
function, use the databricks_list_roles
function in the databricks_auth
extension. This lists all Databricks users, service principals, and groups added to authenticate as Postgres roles.
CREATE EXTENSION IF NOT EXISTS databricks_auth;
SELECT * from databricks_list_roles;
Drop a Databricks identity-based Postgres role
- UI
- PostgreSQL
Dropping a role cannot be undone. You can recreate a role, but any object ownership reassignment is non-reversible without dropping the new role that owns reassigned objects.
- Click Compute in the workspace sidebar.
- Click Database instances.
- Click the Permissions tab.
- For the role identity you want to drop, on the rightmost side, click
.
- Click Drop role.
- If you need to drop a role that owns objects, turn on Reassign owned objects. This will reassign all reassignable owned objects (databases, schemas and tables) to the other role and then drop any non-reassignable owned objects.
- Click Confirm.
A Databricks identity-based Postgres role can be dropped and removed the same as any other Postgres role. For more details, see the PostgreSQL documentation on dropping roles. After a Databricks identity-based role is dropped, it cannot be used for token-based authentication and accessing Postgres.
Use PostgreSQL queries to check Postgres permissions
To read from or write to a table in Postgres, users require the following permissions:
- CONNECT on the database
- USAGE on the schema
- USAGE on the table
Check user permissions on a specific table
Run the following SQL statement to create a function named pg_temp.check_permissions
that checks a user's permissions, including inherited permissions.
CREATE OR REPLACE FUNCTION pg_temp.check_permissions(TEXT, TEXT, TEXT, TEXT)
RETURNS TABLE(database_connect BOOLEAN, schema_usage BOOLEAN, table_select BOOLEAN,
table_insert BOOLEAN, table_update BOOLEAN, table_delete BOOLEAN) AS $$
SELECT
has_database_privilege($1, $2, 'CONNECT'),
has_schema_privilege($1, $3, 'USAGE'),
has_table_privilege($1, $4, 'SELECT'),
has_table_privilege($1, $4, 'INSERT'),
has_table_privilege($1, $4, 'UPDATE'),
has_table_privilege($1, $4, 'DELETE')
$$ LANGUAGE sql
;
To use the function, substitute a Databricks username for <your_user>
, your instance name for databricks_postgres
, and your table name for <my_table>
in the following query:
SELECT * FROM pg_temp.check_permissions('<your_user>', 'databricks_postgres', 'public', '<my_table>');
View all permissions for database, schema, and table
The following SQL statement creates a function named pg_temp.make_owner_acl
that returns a detailed view of all granted permissions, excluding inherited permissions, for all users:
CREATE OR REPLACE FUNCTION pg_temp.make_owner_acl(owner_oid OID)
RETURNS TABLE(grantor OID, grantee OID, privilege_type TEXT, is_grantable BOOLEAN) AS $$
SELECT owner_oid, owner_oid,'OWNER'::TEXT, True
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION pg_temp.get_all_permissions(TEXT, TEXT, TEXT)
RETURNS TABLE(type TEXT, name TEXT, role TEXT, acl TEXT, can_grant TEXT) AS $$
SELECT type, name,
CASE WHEN grantee = 0 THEN 'PUBLIC' ELSE pg_get_userbyid(grantee) END AS role, privilege_type,
CASE WHEN privilege_type = 'OWNER' THEN 'YES, ALL' WHEN is_grantable THEN 'YES' ELSE 'NO' END AS can_grant
FROM (
SELECT 'DATABASE' type, datname as name, (pg_temp.make_owner_acl(datdba)).*
FROM pg_database
WHERE datname = $1
UNION ALL
SELECT 'DATABASE' type, datname as name, (aclexplode(datacl)).*
FROM pg_database
WHERE datname = $1
UNION ALL
SELECT 'SCHEMA' type, nspname as name, (pg_temp.make_owner_acl(nspowner)).*
FROM pg_namespace
WHERE nspname = $2
UNION ALL
SELECT 'SCHEMA' type, nspname as name, (aclexplode(nspacl)).*
FROM pg_namespace
WHERE nspname = $2
UNION ALL
SELECT 'TABLE' type, relname as name, (pg_temp.make_owner_acl(relowner)).*
FROM pg_class
WHERE relname = $3
UNION ALL
SELECT 'TABLE' type, relname as name, (aclexplode(relacl)).*
FROM pg_class
WHERE relname = $3
)
$$ LANGUAGE SQL
;
To use the function, substitute your instance name for databricks_postgres
and your table name for <my_table>
in the following query:
SELECT * FROM pg_temp.get_all_permissions('databricks_postgres', 'public', '<mytable>');
Check role inheritance hierarchy
In Postgres, a role can be a member of another role, and the membership specifies whether the permissions are inherited from the parent role. To see all the roles that a certain role is part of, use the following SQL statement to create the SQL function pg_temp.get_inherited_roles
:
CREATE OR REPLACE FUNCTION pg_temp.get_inherited_roles(
role_name TEXT
)
RETURNS TABLE(inherited_roles TEXT, member_via TEXT, inherits_permissions TEXT) AS $$
WITH RECURSIVE role_tree AS (
SELECT
m.roleid,
pg_get_userbyid(m.roleid) rolname,
'DIRECT' COLLATE "C" as member_via,
m.inherit_option as inherits_permissions
FROM pg_auth_members m
WHERE m.member = (SELECT oid FROM pg_roles WHERE rolname = $1)
UNION ALL
SELECT
m.roleid,
pg_get_userbyid(m.roleid) rolname,
rt.rolname::text as member_via,
(rt.inherits_permissions AND m.inherit_option) as inherits_permissions
FROM pg_auth_members m
JOIN role_tree rt ON m.member = rt.roleid
)
SELECT
rolname AS inherited_roles,
member_via,
CASE WHEN inherits_permissions THEN 'YES' ELSE 'NO' END as inherits_permissions
FROM role_tree
GROUP BY inherited_roles, member_via, inherits_permissions
ORDER BY inherits_permissions DESC
$$ LANGUAGE sql
;
To use the function, substitute a Databricks username for <your_user>
:
SELECT * FROM pg_temp.get_inherited_roles('<your role>');
Find role administrators
To see the admin of a role, use the following SQL query and substitute the role name for <target_role>
:
SELECT pg_get_userbyid(m.member) admin
FROM pg_auth_members m
WHERE m.roleid = (SELECT oid FROM pg_roles WHERE rolname = '<target_role>')
AND m.admin_option = true;