CtrlK
BlogDocsLog inGet started
Tessl Logo

g14wxz/custom-access-token-hook

Injects tenant ID and RBAC permissions into JWT via Postgres Auth Hooks during token issuance.

97

Quality

97%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

access-token-hook-rules.mdrules/

Access Token Hook Rules

FATAL Constraints

  • NEVER use recursive JOINs in client-facing queries or RLS policies to resolve user permissions. HALT immediately if this pattern is detected.
  • NEVER expose the auth hook function to anon, authenticated, or public roles. Execution MUST be restricted to supabase_auth_admin.
  • NEVER store raw permission arrays in the JWT without serialization via jsonb_set. Malformed claims corrupt all downstream RLS.
  • HALT if supabase-mcp-verification is not installed or not passing.

Mandatory Behaviors

  • MUST use a Postgres Auth Hook (custom_access_token_hook) to inject permissions at token issuance time.
  • MUST use jsonb_set to write tenant_id and permissions into event->'claims'->'app_metadata'.
  • MUST define the hook function as SECURITY DEFINER to access role tables regardless of caller context.
  • MUST query role/permission tables with a single flat query — no multi-hop or recursive lookups.
  • All RLS policies that enforce tenant isolation MUST read from auth.jwt() -> 'app_metadata' ->> 'tenant_id' — not from direct table JOINs.
  • MUST grant EXECUTE only to supabase_auth_admin and explicitly REVOKE from public.
  • MUST validate that the returned event object preserves the original structure with only claims.app_metadata modified.

tile.json