Supabase Security Advisor
What does authenticated_security_definer_function_executable mean, and how do I fix it?
authenticated_security_definer_function_executable is the Supabase Security Advisor warning (lint 0029, level WARN) for a security definer function in an exposed schema that the authenticated role can execute. Any signed-in user, and with open sign-up that means anyone with an email address, can call it at /rest/v1/rpc/<name>, and it runs with its owner's rights, so row level security does not limit what it reads or writes. For a function only your server calls, the fix is to revoke EXECUTE from authenticated, together with anon and public.

It is the signed-in half of lint 0028. For the signed-out half and policy helpers such as has_role, see whether anyone can call your Supabase RPC functions with the anon key.
Checklist
How to fix authenticated_security_definer_function_executable, then check the fix
- 01List the security definer functions in public and who can call them. A function you already closed to anon often still shows true for signed-in users, because Supabase grants EXECUTE on new functions in public to anon and authenticated separately from the Postgres default to public:
select p.oid::regprocedure as function, pg_catalog.pg_get_userbyid(p.proowner) as owner, has_function_privilege('anon', p.oid, 'execute') as anon_can_call, has_function_privilege('authenticated', p.oid, 'execute') as signed_in_can_call from pg_catalog.pg_proc p join pg_catalog.pg_namespace n on n.oid = p.pronamespace where n.nspname = 'public' and p.prosecdef order by 1; - 02Only your server calls it: revoke all three in one statement, in a migration.
revoke execute on function public.all_todos() from public, anon, authenticated; - 03It does not need to bypass RLS: make it security invoker, so the caller's policies apply. On the test container this also cleared the lint.
alter function public.all_todos() security invoker; - 04A trigger function, such as one that creates a profile row at sign-up, is flagged too, but it cannot be called at /rest/v1/rpc: Postgres says trigger functions can only be called as triggers. Revoking is safe. On a Supabase Postgres 17.11 container on 22 October 2026, a trigger kept firing after its function was revoked from all three roles.
revoke execute on function public.handle_new_user() from public, anon, authenticated; - 05Run the Security Advisor again in the dashboard. Supabase CLI 2.121.0 db advisors, run against a local database, did not report lint 0028 or 0029 at all, so it cannot confirm this fix.
- 06Call the function as a signed-in user. On the container, after a revoke from public and anon, a signed-in user got their own todo and another user's through all_todos(); after the revoke from authenticated, the call failed with permission denied for function all_todos.
Exceptions
When signed-in users should call it
The lint's source flags every security definer function that authenticated can execute in a schema the Data API exposes, including trigger functions. A function in a private schema is not flagged.
A per-user privileged operation
Supabase's lint docs name a "create my profile" or "submit feedback" function as intentional. Close it to anon, keep it for authenticated, and limit it to the caller inside. On the container, this returned 1 to a signed-in user and permission denied to anon. The Advisor keeps listing it.
create function public.my_todo_count()
returns bigint
language sql
stable
security definer
set search_path = ''
as $$
select count(*) from public.todos where user_id = (select auth.uid())
$$;
revoke execute on function public.my_todo_count() from public, anon;
grant execute on function public.my_todo_count() to authenticated;An owner with no extra rights
If the function's owner can do no more than the caller, security definer gains nothing. The owner column above shows it; on Supabase it is usually postgres, which bypasses RLS.
Related
Related guides
Sources
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
How is it different from anon_security_definer_function_executable?
Lint 0028 is the same check for the anon role, so anyone holding your publishable key. Lint 0029 is for signed-in users. Supabase's lint docs say to fix them together, because revoking from one role usually leaves the other able to call it.
Does turning off pg_graphql fix it?
No. Supabase's lint docs say it closes the /graphql/v1 route only; /rest/v1/rpc still runs the function, and the lint keeps firing.