What is intentionally open — and why.
Companion to @security-memory. Use this when a scanner flags something on this list — it's accepted, not a regression.
Public HTTP routes
- POST
/api/public/ingestWebhook ingestion for external tools (GitHub, CI, bots) to create or update tasks.
Database functions running as definer
has_role / has_workspace_role / workspace_role / is_workspace_member / current_user_kindRole/membership lookups used inside RLS policies. Must run as definer so the policy itself doesn't recursively re-trigger RLS on memberships/profiles.
track_workspace_id / column_workspace_idResolve the workspace owner of a track/column from inside RLS policies on board_columns and tasks. Without definer, RLS on tracks would block the lookup.
handle_new_userauth.users → public.profiles bootstrap trigger. Runs as definer because the auth schema is privileged.
seed_workspace_defaults / seed_track_defaultsOn workspace/track creation, seed default task_types, board_columns and the creator's assigner membership. The creator may not yet hold the role that RLS would require for these inserts.
set_task_workspace_idBEFORE INSERT trigger that fills tasks.workspace_id from the parent track. Needs definer to read tracks for any caller.
prevent_profile_user_kind_escalationBEFORE UPDATE trigger on profiles. Blocks an external user from changing their own user_kind to 'internal'. Definer is needed to read the caller's current user_kind without recursion.
prevent_last_assigner_removalBEFORE DELETE/UPDATE trigger on memberships. Performs SELECT ... FOR UPDATE over sibling assigner rows; definer ensures sibling rows aren't filtered out by the caller's RLS (which would produce false negatives under concurrency).
audit_writeInternal helper that inserts into audit_log. The table has no INSERT policy by design — only definer paths may write. EXECUTE is revoked from public/anon/authenticated.
audit_memberships / audit_task_approval / audit_api_keysTrigger handlers that log sensitive changes. Need definer to write into audit_log (which is locked down). EXECUTE is revoked from public/anon/authenticated.