Skip to main content

Roles and permissions

PostgreSQL uses roles to manage database permissions. In CloudBase PostgreSQL, frontend user requests usually map to roles such as anon or authenticated, while servers and management tools use database accounts.

Common roles

RoleDescription
anonUsed by unauthenticated users
authenticatedUsed by signed-in users
service_roleHigh-privilege role for server-side administration scenarios; can bypass RLS
Application service accountUsed by Cloud Functions, CloudBase Run, or backend services
Admin accountUsed by DMC, operations, and database administration

Actual roles and accounts are shown in the console. Do not use admin accounts in business code.

warning

service_role can bypass RLS policies. Use it only in Cloud Functions, CloudBase Run, backend services, or controlled operations environments. Do not expose the corresponding key, connection information, or admin account in Web, Mini Program, App, or other client-side code.

Authenticated and unauthenticated roles

Unauthenticated requests usually access the database as the anon role. Signed-in user requests usually access the database as the authenticated role. The TO clause in an RLS Policy limits which roles that policy applies to.

If data should be readable by everyone, usually write TO anon, authenticated. Otherwise, allowing only anon may prevent signed-in users from matching the policy, while allowing only authenticated prevents unauthenticated users from accessing it.

create policy "public read"
on public.articles
for select
to anon, authenticated
using (published = true);

Grants

Use grant to add table permissions and revoke to remove them.

grant usage on schema public to authenticated;
grant select, insert, update, delete on public.todos to authenticated;

revoke delete on public.todos from authenticated;

If a table uses identity sequences, grant sequence permissions as well.

grant usage, select on all sequences in schema public to authenticated;

Relationship with RLS

grant decides whether a role can operate on a table. RLS decides which rows are accessible after the role has table permission. Both must pass.

grant select on public.todos to authenticated;

alter table public.todos enable row level security;

create policy "read own rows"
on public.todos
for select
to authenticated
using (user_id = (select auth.uid()));

If table permissions are granted without RLS, frontend users may read more data than expected. If RLS is enabled but table permissions are missing, requests still fail. For frontend roles such as anon / authenticated, design RLS first, then grant table, sequence, and function permissions with least privilege.

service_role can bypass RLS and usually does not need separate Policies. Still, use it only in controlled server-side logic and restrict the business entry points that can exercise it.

Create a service account

Server-side applications should use independent accounts with scoped permissions.

create role app_server login password 'change-me';

grant usage on schema public to app_server;
grant select, insert, update on public.orders to app_server;
grant select on public.users to app_server;

Manage passwords through the console or a secret system. The example password is for illustration only.

Permission diagnostics

Query table permissions and roles:

select grantee, privilege_type
from information_schema.role_table_grants
where table_schema = 'public'
and table_name = 'todos';

If a request returns empty data without an error, check RLS policies. If it returns permission denied, check schema, table, sequence, or function grants first.

For more, see Permission and RLS issues.