Skip to content
Documentation

Roles and permissions

Access is stored in Postgres, and every table is protected by row level security. The app checks permissions on the server, and the database checks them again, so a request that gets past one layer still meets the other.

Roles

RoleWho gets itWhat it can do
memberEveryone, automatically at sign-upManage their own account
adminGranted by SQL or by another adminOpen the admin panel and manage content, media, settings, users, and roles

Both are system roles and can't be deleted.

Permissions

PermissionAllowsadmin has it
admin.accessOpen the admin panelYes
profiles.read_allRead every profileYes
roles.read_allRead every user's role assignmentsYes
roles.manageAssign and revoke rolesYes
content.readRead content entriesYes
content.writeCreate and edit content entriesYes
media.readRead the media libraryYes
media.writeUpload and delete mediaYes
settings.readRead site settingsYes
settings.writeUpdate site settingsYes

Members have none of these. They can still read and edit their own profile.

Granting the first admin

The first admin is always granted in SQL. Run this in the Supabase SQL Editor:

SQL
insert into public.user_roles (user_id, role_code)
select user_id, 'admin'
from public.profiles
where lower(email) = lower('you@example.com')
on conflict do nothing;

Changing roles in the admin panel

After that, admins can change anyone's role from Admin > Users. Two rules protect the site:

  • You can't remove your own admin role.
  • There must always be at least one admin.

The same rules apply through the REST API and MCP server. There, admins can also deactivate an account, with two more limits: you can't deactivate yourself, and you can't deactivate the last admin.

Every role change is written to the audit log.

Roles and API tokens

An API token can never do more than the person who created it. Its scopes are checked against that person's current permissions on every request, so if someone loses the admin role, their tokens lose admin access at the same moment. See Tokens and safety.