Roles & Permissions
Pulsabase offers a built-in Role-Based Access Control (RBAC) system. Roles and permissions are created through the Auth SDK (or the Dashboard), attached to users, and then automatically encoded into the user’s JWT so your database Row-Level Security (RLS) policies can enforce them at the database level.
RBAC Concepts
Section titled “RBAC Concepts”| Concept | Description |
|---|---|
| Role | A named label assigned to users (e.g. admin, moderator) |
| Permission | A fine-grained capability key (e.g. rooms.create, invoices.delete) |
| Role ↔ Permission | Roles contain a set of permissions |
| User ↔ Role | Users are assigned one or more roles |
Creating Roles & Permissions
Section titled “Creating Roles & Permissions”Roles and permissions are created via the SDK from an admin context (a user with an admin role). You typically run this once in a setup script or admin panel.
// 1. Create fine-grained permissionsawait pb.auth.createPermission('rooms.create', 'Can create new rooms');await pb.auth.createPermission('messages.delete', 'Can delete any message');await pb.auth.createPermission('users.manage', 'Can manage users and roles');
// 2. Create rolesawait pb.auth.createRole('admin', 'Full platform access');await pb.auth.createRole('moderator', 'Can moderate content');await pb.auth.createRole('member', 'Standard access level');
// 3. Assign permissions to rolesawait pb.auth.setRolePermissions('admin', [ 'rooms.create', 'messages.delete', 'users.manage',]);await pb.auth.setRolePermissions('moderator', ['messages.delete']);Assigning Roles to Users
Section titled “Assigning Roles to Users”Once roles exist, you can assign them to users. Roles are included in the user’s next JWT as user.roles.
// Assign the 'moderator' role to a specific user (requires admin)await pb.auth.assignRoles(targetUserId, ['moderator']);
// Inspect the current user's roles from the local JWT (no network call)const myRoles = pb.auth.getRoles(); // ['member']const myPerms = pb.auth.getPermissions(); // ['messages.delete']
// Check roles inline (useful for conditional rendering)if (pb.auth.hasRole('admin')) { showAdminPanel();}
if (pb.auth.hasPermission('rooms.create')) { showCreateRoomButton();}Querying Roles & Permissions (Admin)
Section titled “Querying Roles & Permissions (Admin)”// List all roles in the projectconst allRoles = await pb.auth.listAllRoles();
// List all permissionsconst allPerms = await pb.auth.listAllPermissions();
// Get permissions for a specific roleconst moderatorPerms = await pb.auth.getRolePermissions('moderator');
// Get a specific user's effective permissionsconst userPerms = await pb.auth.getUserPermissions(targetUserId);
// Update a user's info or rolesawait pb.auth.updateUser(targetUserId, { roles: ['admin', 'member'], email_verified: true,});Securing Data with RLS
Section titled “Securing Data with RLS”Roles and permissions are deeply integrated with your database via Row-Level Security (RLS). When a user makes a database request, their JWT is verified and its claims are injected into the PostgreSQL session, where RLS policies can enforce access.
import { ModelSchema, primary, text } from 'pulsabase';
export default class Room { @primary id: string; @text(false) name: string;
static schema: ModelSchema = { tableName: 'rooms', policies: [ // Any authenticated user can read rooms { action: ['SELECT'], authenticated: true },
// Only users with the 'rooms.create' permission can insert { action: ['INSERT'], permission: 'rooms.create' },
// Only admins can delete rooms { action: ['DELETE'], role: 'admin' },
// Moderators and admins can update rooms { action: ['UPDATE'], role: ['admin', 'moderator'] }, ] };}When a user calls pb.from(Room).insert(...), PostgreSQL extracts their JWT from the session context, checks permissions @> 'rooms.create', and enforces the policy.
User Management (Admin)
Section titled “User Management (Admin)”Full user management is available for admin users:
// List all users in the projectconst users = await pb.auth.listUsers();
// Get a specific user by IDconst user = await pb.auth.getUserById(userId);
// Set user-specific permission overridesawait pb.auth.setUserPermissions(userId, ['billing.read'], // allowed permissions ['billing.write'], // denied permissions (overrides role permissions));[!NOTE] Because JWT claims cannot be invalidated mid-session, role and permission changes only take effect when a user’s token is next refreshed (typically within 60 seconds by default) or when they sign in again.