🧱 Суть
В Supabase есть несколько уровней ролей пользователя.
Важно понимать:
auth.users.roleи
auth.users.raw_app_meta_data.role– это разные вещи.
Обычно путаница возникает из-за того, что оба поля называются role.
📦 Два типа ролей
1. Системная роль auth.users.role
Пример:
{
"role": "authenticated"
}Это внутренняя роль Supabase.
Она:
- устанавливается автоматически;
- показывает состояние авторизации пользователя;
- обычно не изменяется вручную.
Стандартные значения:
anon
authenticated
2. Кастомная роль raw_app_meta_data.role
Пример:
{
"role": "admin"
}Это уже роль приложения.
Она:
- создаётся разработчиком;
- используется для бизнес-логики;
- попадает в JWT;
- может проверяться через RLS.
Например:
auth.jwt()->>'role' = 'admin'Как это работает
У пользователя может быть:
auth.users.role
↓
authenticatedи одновременно:
raw_app_meta_data.role
↓
adminТо есть:
- Supabase знает: “это авторизованный пользователь”
- твоё приложение знает: “это администратор”
💻 Код
Изменение кастомной роли:
update auth.users
set raw_app_meta_data = jsonb_set(
raw_app_meta_data,
'{role}',
'"admin"',
true
)
where id = 'USER_ID';Разбор:
'{role}'– путь к изменяемому полю.
'"admin"'– новое значение JSON-строки.
true– создать поле, если его ещё нет.
Важно
После изменения:
raw_app_meta_dataтекущий JWT пользователя останется старым.
Пользователь должен:
- выйти из аккаунта;
- войти заново.
Только после этого будет получен новый токен с новой ролью.
Использование в RLS
Например, разрешить доступ только администраторам:
CREATE POLICY "Admins only"
ON public.some_table
FOR ALL
USING (
auth.jwt()->>'role' = 'admin'
);Теперь запрос разрешён только пользователям с ролью admin в JWT.
🎯 Вывод
auth.users.role– системная роль Supabase, обычно не трогается.raw_app_meta_data.role– твоя роль приложения.- Кастомная роль попадает в JWT.
- Для RLS чаще всего проверяют именно JWT:
auth.jwt()->>'role'- После изменения роли нужен новый вход пользователя.