| name | supabase-enterprise-rbac |
| description | Implement custom role-based access control via JWT claims in Supabase:
app_metadata.role, RLS policies with auth.jwt() role extraction,
organization-scoped access, and API key scoping.
Use when implementing role-based permissions, configuring organization-level
access, building admin/member/viewer hierarchies, or scoping API keys per role.
Trigger with "supabase RBAC", "supabase roles", "supabase permissions",
"supabase JWT claims", "supabase organization access", "supabase custom roles",
"supabase app_metadata".
|
| allowed-tools | Read, Write, Edit, Bash(npx supabase:*), Bash(supabase:*), Bash(psql:*) |
| version | 1.53.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","supabase","rbac","security","enterprise","roles","permissions"] |
| compatibility | Designed for Claude Code, also compatible with Codex and OpenClaw |
Supabase Enterprise RBAC
Overview
Supabase supports custom role-based access control (RBAC) by storing role information in app_metadata on the user's JWT, then reading those claims in RLS policies via auth.jwt() ->> 'role'. This skill implements a complete RBAC system: roles in app_metadata, RLS policies that enforce role hierarchies, organization-scoped access, role management through the Admin API, and API endpoints protected with role checks — all using real createClient from @supabase/supabase-js.
When to use: Building multi-role applications (admin/editor/viewer), implementing organization-scoped access, creating custom permission systems beyond Supabase's built-in anon/authenticated roles, or scoping API operations by user role.
Prerequisites
@supabase/supabase-js v2+ with service role key for admin operations
- Understanding of JWT claims and Supabase's
auth.jwt() SQL function
- Database access via SQL Editor or
psql for RLS policy creation
- Supabase project with authentication configured
Instructions
The workflow has three steps: assign roles into the JWT, enforce them in the database with RLS, then enforce them again in application code.
Step 1: Define Roles via app_metadata and JWT Claims
Store custom roles in the user's app_metadata using the Admin API. These claims appear in every JWT the user receives and are readable in RLS policies. Assign roles with the service-role client:
type AppRole = 'admin' | 'editor' | 'viewer' | 'member';
async function setUserRole(userId: string, role: AppRole, orgId: string) {
{ data, error } = supabase...(userId, {
: { role, : orgId },
});
(error) ();
data.;
}