Supabase Auth, and how it actually connects to RLS
Auth, Authorization & Multi-Tenancy's own domain taught the full mechanics of building authentication yourself — password hashing, sessions, JWTs, OAuth. Supabase Auth is a managed implementation of exactly those mechanics, and the genuinely distinctive part isn't the auth system alone, it's precisely how it plugs into lesson 2's RLS policies.
Intermediate
3 min read
What Supabase Auth actually provides, mapped onto what Auth's own domain already taught
Password-based signup/login → Auth's own password-hashing lesson, managed for you
Social OAuth (Google, GitHub) → Auth's own OAuth2/OIDC lesson, pre-integrated
JWT issuance → Auth's own JWT lesson, issued automatically on login
Session management → Auth's own sessions/refresh-tokens lessons, handled
Supabase Auth is a managed implementation of the exact mechanisms Auth, Authorization & Multi-Tenancy's own domain already covered in depth — this lesson isn't re-deriving password hashing or JWT structure; it's showing where a managed version sits, and naming the one thing that's genuinely distinctive about using it specifically inside Supabase rather than as a standalone auth service.
The distinctive part: auth.uid() is available directly inside Postgres itself
CREATE POLICY "users can only see their own documents"ON documents FOR SELECTUSING (auth.uid() = owner_id);
When a request arrives through Supabase's API using a logged-in user's JWT, Supabase decodes it and makes that user's ID available to Postgres during the query itself, as the auth.uid() function lesson 2 already used directly. This is the actual integration point that makes Supabase's auth system different from bolting a standalone auth provider onto an unrelated database: the identity established at the HTTP layer becomes something the database can reference directly, inside an RLS policy, with no application code manually passing a user ID into every single query as a parameter.
Why this matters more than it might sound like on paper
Without this integration, connecting authentication to row-level access control means application code has to look up the current user, then manually pass that user's ID as a parameter into every single query that needs it — exactly the fragile, forgettable pattern Auth & Multi-Tenancy's own domain already warned against for tenant isolation generally. With auth.uid() available inside the database itself, an RLS policy references the current user's identity directly, with the same structural guarantee lesson 2 established: there's no code path that can forget to pass it, because it isn't being passed by application code at all.
anon and authenticated roles: the two Postgres roles every request maps onto
CREATE POLICY "anyone, even logged out, can read public posts"ON posts FOR SELECTTO anon, authenticatedUSING (status = 'published');
Every request through Supabase's API runs as one of two actual Postgres database roles — anon for a request with no valid JWT (a logged-out visitor), authenticated for one with a valid JWT. A policy can be scoped to apply TO anon, TO authenticated, or both — this is how "logged-out users can see public content, but only logged-in users can see their own private data" gets expressed as two genuinely different Postgres roles interacting with the same table's policies, rather than one undifferentiated "logged in or not" boolean check in application code.