M0: add department_id JWT claim, rewrite RLS to avoid profiles queries
auth-hook.sql now copies department_id into JWT claims alongside role/org_id, so RLS can scope Staff reads without joining profiles from another table's policy. policies.sql: sops/sop_versions Staff read policies now use the department_id claim directly; every create policy paired with a matching drop policy if exists so the file is safe to re-run. Folds in the supabase_auth_admin profiles-select grant so policies.sql is self-contained. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FcktbLXSSXzx23GCue813e
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f539d43136
commit
1b3ba67468
+11
-3
@@ -3,6 +3,11 @@
|
||||
-- "A Postgres function copies role/org_id into JWT claims (custom
|
||||
-- access token hook) so RLS can check them cheaply."
|
||||
--
|
||||
-- Also copies department_id — needed so RLS policies can scope Staff
|
||||
-- reads to "published + assigned to their department" (04-database-
|
||||
-- schema.md section 3) using JWT claims only, without any policy ever
|
||||
-- querying the profiles table from another table's policy.
|
||||
--
|
||||
-- Run this AFTER schema.sql (needs the profiles table to exist).
|
||||
-- After running, enable the hook in the Supabase dashboard (see bottom
|
||||
-- of this file for the exact steps) — running the SQL alone does not
|
||||
@@ -17,10 +22,11 @@ as $$
|
||||
claims jsonb;
|
||||
user_role public.user_role;
|
||||
user_org_id uuid;
|
||||
user_department_id uuid;
|
||||
begin
|
||||
-- Look up this user's role and org_id from profiles.
|
||||
select role, org_id
|
||||
into user_role, user_org_id
|
||||
-- Look up this user's role, org_id, and department_id from profiles.
|
||||
select role, org_id, department_id
|
||||
into user_role, user_org_id, user_department_id
|
||||
from public.profiles
|
||||
where id = (event->>'user_id')::uuid;
|
||||
|
||||
@@ -29,9 +35,11 @@ as $$
|
||||
if user_role is not null then
|
||||
claims := jsonb_set(claims, '{role}', to_jsonb(user_role));
|
||||
claims := jsonb_set(claims, '{org_id}', to_jsonb(user_org_id));
|
||||
claims := jsonb_set(claims, '{department_id}', to_jsonb(user_department_id));
|
||||
else
|
||||
claims := jsonb_set(claims, '{role}', 'null');
|
||||
claims := jsonb_set(claims, '{org_id}', 'null');
|
||||
claims := jsonb_set(claims, '{department_id}', 'null');
|
||||
end if;
|
||||
|
||||
event := jsonb_set(event, '{claims}', claims);
|
||||
|
||||
Reference in New Issue
Block a user