Next.js + Supabase Security Audit: A Simple Pre-Production Checklist
A focused checklist is better than a false sense of security. Here is what to verify before going live with Next.js and Supabase.
Before going into production, many teams think “we’ll see later”. This is often the worst window to discover a rights problem, an exposed key or poorly filtered public content.
A security audit doesn't have to be heavy to be useful. Above all, it must be clear, repeatable, and focused on what really breaks a Next.js + Supabase project.
1. Check keys and secrets
First mandatory pass:
- no server key in the front
- no sensitive variable prefixed by
NEXTPUBLIC - no committee key in the repo
- no informal sharing of secrets in the doc or team chat
If this basis is not clean, the rest of the audit already loses a lot of value.
2. Verify Supabase customers
Make sure there is a clear separation between:
- the public customer
- the server client
The critical point is simple: service_role must remain server only.
3. Check the tables exposed via the Data API
List the tables that must be reachable via the Data API and ask yourself, for each:
- what role is there?
- for what action?
- is this really necessary?
Since 2026, Supabase has been pushing a more explicit model on new tables. Take advantage of this to avoid wide exposures inherited from the past.
4. Check GRANT
For each table displayed:
- Does
anononly have what he should have? - Does
authenticatedonly have useful operations? - Is
service_rolereserved for the server?
This step forces you to move from implicit security to readable security.
5. Check the EPIRB
Once the GRANT is checked, switch to the EPIRB:
- is the table in row level security?
- is there a policy for each expected action?
- does the policy filter according to the correct business key?
If you do not have a clear answer to these questions, you must reread the table.
6. Check authorization sources
Also check what your access decisions are based on:
- Is
user_metadataused where it shouldn't? - Does
app_metadataor the business database serve as a reliable source? - is the front just hiding buttons, or are the server and base really in control?
This point avoids a lot of false security.
7. Check sensitive routes and actions
Review:
- login
- reset password
- account deletion
- role change
- access documents, invoices, messages
- admin operations
Every sensitive action must have explicit verification. If you see a "if the button is hidden then it's good", that's not good.
8. Check public content
A hybrid project often has:
- a blog
- a CMS
- a private portal
This mixture creates confusion. Verify that public tables do not contain drafts, internal config or private data readable by anon.
9. Check useful security headers
On the web part, keep a clean base:
Content-Security-PolicyStrict-Transport-SecurityX-Content-Type-OptionsReferrer-PolicyPermissions-Policy
The goal is not to aim for the perfect collection of headers. The goal is to close the main surfaces without breaking the site.
10. Check actual behavior
A good audit ends with concrete tests:
- a legitimate user takes the normal route
- a user without rights attempts the same access
- an anon visitor tries to read what should not be public
- an admin action is tested without admin privilege
It is these tests that reveal the gaps between intention and reality.
A short version of the checklist
If you have to go fast, at least keep this:
- own secrets
- client server separation
GRANTexplicit- EPIRB activated
- readable policies
- limited public content
- verified sensitive actions
This is the hard core.
What to remember
A useful Next.js + Supabase security audit is not a mountain of theory. It's a disciplined review of the points that really open loopholes: secrets, clients, GRANT, EPIRBs, public content and sensitive actions.
If you do this pass before production, you avoid a lot of the errors that then cost time, confidence, and sometimes data.
Official sources
Keep reading on the same topic
These links reinforce the blog's topical cluster and help search engines understand the article's primary subject.
