Custom Claims are special attributes attached to a user that you can use to control access to portions of your application. For example:
{
"user_role": "admin",
"plan": "TRIAL",
"user_level": 100,
"group_name": "Super Guild!",
"joined_on": "2022-05-20T14:28:18.217Z",
"group_manager": false,
"items": ["toothpick", "string", "ring"]
}
To implement Role-Based Access Control (RBAC) with custom claims, use a Custom Access Token Auth Hook. This hook runs before a token is issued. You can use it to add additional claims to the user's JWT.
To utilize Role-Based Access Control (RBAC) in Row Level Security (RLS) policies, create an authorize method that reads the user's role from their JWT and checks the role's permissions:
supabase/migrations/init.sql
create or replace function public.authorize(
requested_permission app_permission
)
returns boolean as $$
declare
bind_permissions int;
user_role public.app_role;
begin
-- Fetch user role once and store it to reduce number of calls
select (auth.jwt() ->> 'user_role')::public.app_role into user_role;
select count(*)
into bind_permissions
from public.role_permissions
where role_permissions.permission = requested_permission
and role_permissions.role = user_role;
return bind_permissions > 0;
end;
$$ language plpgsql stable security definer set search_path = '';
You can read more about using functions in RLS policies in the RLS guide.
You can then use the authorize method within your RLS policies. For example, to enable the desired delete access, you would add the following policies:
create policy "Allow authorized delete access" on public.channels for delete to authenticated using ( (SELECT authorize('channels.delete')) );
create policy "Allow authorized delete access" on public.messages for delete to authenticated using ( (SELECT authorize('messages.delete')) );
The auth hook will only modify the access token JWT but not the auth response. Therefore, to access the custom claims in your application, e.g. your browser client, or server-side middleware, you will need to decode the access_token JWT on the auth session.
In a JavaScript client application you can for example use the jwt-decode package: