🧱 Суть

В 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'
  • После изменения роли нужен новый вход пользователя.

🔗 Связано