Injects tenant ID and RBAC permissions into JWT via Postgres Auth Hooks during token issuance.
77
97%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Injects tenant ID and RBAC permissions into JWT via Postgres Auth Hooks during token issuance.
This tile implements a Postgres Auth Hook that runs during Supabase token issuance. The hook queries role-mapping tables and uses jsonb_set to inject tenant_id and serialized permissions into the JWT app_metadata. Downstream RLS policies then extract these values via auth.jwt() -> 'app_metadata', eliminating the need for recursive JOINs in client queries.
CREATE OR REPLACE FUNCTION public.custom_access_token_hook(event jsonb)
RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
claims jsonb;
tenant_id uuid;
BEGIN
claims := event->'claims';
SELECT tm.tenant_id INTO tenant_id
FROM tenant_members tm
WHERE tm.user_id = (event->>'user_id')::uuid;
claims := jsonb_set(claims, '{app_metadata, tenant_id}', to_jsonb(tenant_id));
event := jsonb_set(event, '{claims}', claims);
RETURN event;
END;
$$;CREATE POLICY tenant_isolation ON some_table
USING ((auth.jwt() -> 'app_metadata' ->> 'tenant_id')::uuid = tenant_id);GRANT EXECUTE ON FUNCTION public.custom_access_token_hook TO supabase_auth_admin;
REVOKE EXECUTE ON FUNCTION public.custom_access_token_hook FROM public, anon, authenticated;tenant_members) MUST exist before this tile is executed.supabase-mcp-verification. RLS policies and downstream tiles consume the injected JWT claims.