Supabase Auth vs Auth0: The Lie of Easy Authentication and the Real Risk
When someone says “let’s wire up OAuth2 with Google”, most developers think: “Meh, 10 minutes. A couple of endpoints, copy the client_id and off we go”.
Like hell.
Reality is going to slap you in the face sooner rather than later. Running authentication in production is one of the biggest headaches you can take on, and a lot of people don’t realise it until the water is up to their neck.
These days there are two religions for solving this:
- Hand the problem over to a giant like Auth0.
- Play the brave one and run it yourself with Supabase Auth, the old GoTrue.
Both are valid. Both have costs. But one charges you in euros and the other can charge you in anxiety and sleepless nights.
This post isn’t here to sell you anything. It’s here so you understand what you’re getting into.
What Supabase Auth actually is (marketing aside)
Supabase Auth is the identity service of the Supabase ecosystem. Underneath there’s an open source authentication server that does what it promises: manage users, issue JWTs and talk to providers like Google or GitHub.
You’ll see it quoted as GoTrue everywhere, but that name is no longer the current one: the repository and the image are now called supabase/auth. The old supabase/gotrue is still published and nothing breaks, but the environment variables keep the GOTRUE_ prefix, and that mix is confusing.
When you use managed Supabase, they operate it. But when you use self-hosted Supabase Auth (because you’re a “hacker” and you don’t want to pay for the cloud), that server is yours.
And “yours” means:
- Your identity database.
- Your JWT secrets.
- Your OAuth flows breaking when Google changes the API.
- Your legal liability.
There’s no magic control panel like in Auth0. Here you play with Docker Compose and environment variables.
The “minimum viable” setup already looks a bit scary if you look closely:
services:
auth:
image: supabase/auth:v2.194.0
environment:
GOTRUE_DB_DRIVER: postgres
GOTRUE_DB_DATABASE_URL: postgres://postgres:password@db:5432/auth
GOTRUE_JWT_SECRET: a-secret-you-definitely-copied-from-stackoverflow
GOTRUE_EXTERNAL_GOOGLE_ENABLED: "true"
# ... 50 more variables to make this genuinely secure
It works. And it works very well. But this is where the part nobody tells you about in the “Netflix clone in 10 minutes” tutorials begins.
Authenticating isn’t just “doing login”
When you set up your own auth shop, you automatically become the Head of Security, Compliance and Operations of your company. Congratulations on the promotion (unpaid).
You’re now responsible for:
1. Security (the real kind)
- Key custody. If someone steals your
GOTRUE_JWT_SECRET, you’ve compromised every one of your users. You have to rotate it. Do you know how to rotate keys without taking down the service? - Attacks. Rate limiting, brute force protection, user enumeration… The server gives you some pieces, but you’re the one who has to configure them properly.
2. Privacy and legal
- Personal data, emails, IPs, consents.
- Right to be forgotten. When a user asks to be deleted, you have to actually delete them. From everywhere.
- Logs: are you logging sensitive information? That’s a fine waiting to happen.
3. Availability
If your auth Postgres goes down, nobody gets in and your product stops existing for everyone at once. You need backups, replicas and a disaster recovery plan that isn’t “cry in a corner”.
Why Auth0 exists (and why it’s so expensive)
Auth0 doesn’t exist to give you OAuth2. It exists to absorb your risk.
When you buy Auth0, you’re paying (and paying well) for operational peace of mind:
- They store the passwords and hash them better than you do.
- They rotate the keys.
- They fight the SOC2 audits and ISO 27001 for you.
- They monitor global attacks and block malicious IPs before they reach you.
You get on with building your product. They get on with keeping people out of where they shouldn’t be.
It’s expensive, sure. But how much is your time worth if you have a security breach on a Saturday at 3 in the morning?
The brutal comparison
Let’s get to the point. No sugarcoating.
One clarification before the table: what I’m comparing here is self-hosted Supabase Auth against managed Auth0, which is how the decision gets framed almost every time. But there’s a third path worth remembering. Supabase Auth also exists as a managed service, and the moment they run it half the column collapses: operations, most of the risk and nearly all of the compliance stop being yours. That doesn’t change the thesis of this post, because the cost of running identity still gets underestimated. What changes is that you can decide not to run it without changing product.
| Supabase Auth (self-hosted) | Auth0 | |
|---|---|---|
| Price | Free, or whatever your infrastructure costs | Expensive, and pricing can scale very fast if you’re successful |
| Control | Total: your code, your database, your rules | Whatever their panel gives you: you don’t touch the infrastructure |
| Risk | Also total: everything is your fault and, if it breaks, you fix it | They absorb it; that’s what the product is for |
| Operations | Keys, backups, replicas and updates: a job in itself | They rotate keys, monitor attacks and block IPs for you |
| Compliance | GDPR becomes your problem, not theirs | They fight SOC2 and ISO 27001 audits in your place |
| Dependency | None: it’s open source, and if Supabase disappears you’re still alive | Total: if Auth0 goes down (rare, but it happens), you’re done for |
| Maturity | Whatever your team brings to the table | It’s the standard: it works, end of story, and it takes whatever you throw at it |
| Fit | It gets along beautifully with your backend, especially if you use Postgres | External service: identity lives outside your database |
The Supabase column assumes self-hosted. With managed Supabase, the operations, risk and compliance rows look a lot more like Auth0’s.
The million dollar question
The decision isn’t technical. It isn’t “which technology is cooler?”.
The right question is whether you want to (and can) take on the risk of running identity in production.
There are contexts where Supabase Auth is the sensible choice:
- Small or medium product.
- A strong technical team that knows security.
- You need granular control and you’re on a tight budget.
- An environment that isn’t heavily regulated.
And there are contexts where Auth0 is mandatory:
- B2B SaaS selling to large companies (Enterprise).
- Highly sensitive data (health, financial).
- External security audits required.
- Zero tolerance for outages or incidents.
Delegating authentication doesn’t make you a worse programmer or “less of a hacker”. It’s risk management, which is a different thing altogether.
Authentication is the front door of your house. You decide whether you put a professional bouncer on it or hand the key to your cousin and pray he doesn’t lose it.