TL;DR: Supabase auth security is not one setting. It is seven decisions. AI builders accept the default on all of them. A working login screen proves none of it. Before launch, check seven things. Email confirmation. Password rules. Rate limits on every auth route. JWT expiry. Server-side logout. Redirect allowlists. RLS. This page is the exact checklist we run on every audit. The free scan tests your live app in about 30 seconds.

Ask an AI builder to "add login" and you get a clean form in under a minute. That form works. It is also the least of it. The login screen is the front door. The settings behind it decide what that door really is. A lock, a chain, and an alarm — or just a handle.

QuestionAnswer
Is Supabase Auth secure out of the box?
No. The defaults favor speed. Each setting needs a launch decision.
Biggest auth gap we find?
No rate limits on auth routes, paired with loose or missing RLS.
Does a long JWT life matter?
Yes. A stolen token stays valid until it expires. Keep it short.
Are open redirects a real threat?
Yes. A loose allowlist turns your own login into a phishing tool.
How do I check my app?
Scan your live URL. No code access. About 30 seconds.
What does it cost?
The scan is $0. The full audit report is $499, one time.

The checklist at a glance

Seven checks. Run them in order. The table shows what ships by default, what can go wrong, and the fix.

CheckThe defaultThe riskThe fix
Email confirmationCan be skippedThrowaway signups get live sessionsRequire it before a session is issued
Password policyShort minimumWeak and reused passwords passLonger floor plus breach-list checks
Rate limitsHosted routes onlyBots hammer custom auth flowsThrottle sign-up, sign-in, reset, magic links
JWT expiryGenerousStolen tokens stay valid for hoursShort expiry, about an hour or less
SessionsClient-side logout"Logged out" tokens keep workingRotate refresh tokens; kill them on the server
Redirect allowlistLoose until setLogin links that deliver users to attackersStrict allowlist, no wildcards
RLSOff until enabledAny user reads every rowOn for all tables, owner-scoped policies

1. No session until the email is confirmed

Left off, anyone can register with a throwaway address and get a working session at once. Bots love this. So do abusers of free tiers. Flip the setting so no session is issued until the address is confirmed. Then test it. Sign up with a fake address and see what your app hands back. If a fresh, unchecked account can write data, fix that first.

2. Password policy: raise the floor

The default minimum is short. Real users pick the shortest thing the form allows. They reuse it from other sites. Raise the length floor. Turn on checks against known-leaked passwords. This blunts credential stuffing, where bots replay leaked passwords against your login form.

3. Rate limits on every auth endpoint

This is the silent one. Missing limits cause no error and no broken demo. Logins keep working. What is gone is the layer that stops a script from trying 10,000 passwords an hour against your sign-in route.

Supabase throttles its own hosted auth endpoints. The gap is everything you built beside them. Custom sign-up flows. Magic-link senders. Reset forms on edge functions. These often ship with no limits at all. Our load engine flags this word for word as "No rate limiting detected under concurrent load." (k6Scanner.js:170). It is one of the most common findings we raise. Test one endpoint yourself with the free API rate limit checker.

4. JWT expiry: keep stolen tokens short-lived

Supabase issues a JWT on login, plus a refresh token. The default JWT life is generous. It is built for dev comfort, not production. Why it matters: a stolen token stays valid until it expires. Leak one through an injected script or a logging slip, and a long token life turns that one leak into a long, quiet session.

Cut the token life to an hour or less. Rotate refresh tokens on every use. And mind where the client keeps the token. Many AI builds park it in localStorage. Any injected script can read it there. We cover that trade-off in storing JWTs in localStorage.

5. Sessions: logout must mean logout

Ask one question of your app. When a user logs out, does the server kill the session? Or does the client just clear a cookie while the JWT stays valid? In many scaffolds it is the second. That means "logged out" tokens keep working until they expire. Make logout revoke the session on the server. Then check that a captured token stops working. Test it. Do not assume it.

6. Redirect allowlists: your login as a phishing tool

Magic links and OAuth callbacks send users somewhere after login. That "somewhere" is a URL. If it is not locked to a strict allowlist, it is attacker input. The play is simple. Craft a real login link for the real app. Point the redirect at a lookalike domain. The user logs in — truly logs in — and lands on the attacker's page with their session in play.

Lock the allowlist to exact URLs. No wildcards. Check it each time you add a new deploy target. Preview URLs are how wildcards creep back in.

7. RLS: the gate behind the door

Auth proves who someone is. Row Level Security decides what they can see once inside. They are two systems. Vibe-coded apps keep treating them as one. With RLS off — or set to USING (true) — any logged-in user can read every row. With the anon key exposed, even login is optional. CVE-2025-48757 showed the scale. 170 or more AI-built apps were left readable on this exact stack.

Turn RLS on for every table. Write owner-scoped policies with auth.uid(). Know your keys. The anon key is public by design. The service_role key is not. Mixing them up undoes everything above. Our anon key vs service role key guide draws the line. The RLS policies guide covers the SQL. The free RLS checker probes your live app for the gap.

Why AI builders miss all seven

None of these checks show up in a demo. That is the whole story. The tools chase a feature that runs. Every item on this list is unseen when wrong. The numbers say how often: Symbiotic Security scanned 1,072 AI-built apps. 98% had at least one flaw. 16% had critical issues. CMU's SusVibes study found flaws in 61% of AI-written code. Across 100 apps we scanned ourselves, the average Launch Readiness Score was 42/100. Auth gaps were a steady reason.

The legal layer on top

Weak auth around personal data is a GDPR problem, not just a bug. An exposed table is a breach you must report. The fines scale with the leak, not with your company size. Ship an AI-facing feature to EU users? Article 50 of the EU AI Act applies from August 2, 2026. Users must be told they are talking to an AI. Its transparency fines run up to €15 million or 3% of global turnover. Our GDPR guide covers the data side; the Compliance Wing checks both against your live app.

What checking this costs

The free scan is $0 and takes about 30 seconds. You give it your live URL. You get a Launch Readiness Score out of 100 across security, reliability, performance, and monitoring. Auth checks included. The full Launch Readiness Audit is $499 one time. It adds a branded report with every finding, a ranked fix plan, and a benchmark against 200+ audited apps. Want it fixed for you? Done-for-you setup starts at $1,999. A named CTO ships each fix as a pull request you approve. The full list of what we probe on this stack is on the Supabase security audit page.

FAQ

Is Supabase Auth secure by default?

No. The product is solid. The defaults are built for speed. Email checks can be skipped. The password floor is short. JWTs live long. Redirects are loose until you set an allowlist. Each one needs a decision.

What rate limits does a Supabase app need on auth endpoints?

Sign-up, sign-in, magic links, and password reset all need limits. Supabase throttles its own hosted routes. Custom flows on edge functions often ship with none. Without limits, a script can try thousands of passwords an hour.

How long should a Supabase JWT live?

Short. An hour is a common ceiling; many teams go lower. A stolen token stays valid until it expires. Long expiry turns one leak into a long session. Pair a short life with refresh token rotation and logout on the server.

Why do redirect URL allowlists matter?

Magic links and OAuth callbacks send users to a URL after login. If that URL is not locked to a strict allowlist, an attacker can abuse it. They craft a real login link that hands the session to their own domain. It is a textbook phishing vector.

Does RLS replace auth checks?

No. Auth proves who someone is. Row Level Security decides what they can see once inside. A logged-in user with no RLS, or a policy of USING (true), can read every row in the table. You need both layers.

What does a Supabase auth security audit cost?

The scan is $0 and returns a Launch Readiness Score out of 100 in about 30 seconds. The full Launch Readiness Audit is $499 one time: a branded report, a ranked fix plan, and a benchmark against 200+ audited apps.

Seven checks, one afternoon. That is the gap between a login form that works and an auth layer that holds. The pattern matches every stack in our vibe coding security guide: the code works, the defaults do not. Start with the scan and see which of the seven your app fails today.

Which of the seven does your app fail?

Scan your live app. No code access. A Launch Readiness Score out of 100, in about 30 seconds.

Run the free scan — $0