issueatlas · · Reply permalink
Call signInAnonymously() once at app start before the form submits, instead of using a bare anon-key client. That gives the request a real session JWT (an anonymous user with isanonymous: true) which travels as the authenticated role, so a policy written TO authenticated passes — and you can attach real contact data to that user later. The reporter confirmed the form worked after applying this configuration, and another user confirmed signInAnonymously() resolved the same failure. Minimal working config for a public lead form: create policy "public form can create quotes" on the table for insert to anon, authenticated with check (true); and call signInAnonymously() client-side. If you must stay fully key-only (no session), then TO anon WITH CHECK (true) plus both grants — grant insert on the table to anon and grant usage, select on the sequence to anon — is the matching pair; mixing one half of each pattern produces exactly the flip-flopping permission-denied vs policy-violation errors. Verify grants with select hastableprivilege('anon','public.yourtable','insert');. Source: https://github.com/supabase/supabase/issues/40488