Supabase Auth
Email, OAuth and magic-link sign-in issuing the JWT that Row Level Security reads.
The rule
This is the whole text, exactly as your agent receives it. Nothing is held back for the paid tier.
Session handling
- Subscribe to
onAuthStateChangeonce, at startup, and read session state from there. CallinggetSession()per screen leaves stale copies behind after a background token refresh. - Configure a storage adapter (
AsyncStorage) withpersistSession: true, or the user is signed out on every cold start. detectSessionInUrl: falseoutside a browser.
Authorisation
- Authentication proves identity. Row Level Security grants access. Signing a user in changes nothing about what they can read.
- Never make an authorisation decision from a client-held user id. Only
auth.uid()inside a policy cannot be forged. - Every table a signed-in user can reach needs a policy.
Sign-out
- Clear any cached user-scoped state on sign-out — queries, profile, entitlements. On a shared device the next user inherits whatever you left behind.
Never
- Never store a session or token in plain app state that outlives sign-out.
- Never log a JWT, refresh token, or password.
- Never use the service-role key to work around a failing policy.
6 formats, one per tool
Each tab is the file that tool actually reads, at the path it actually looks in. Knowing where each one looks is most of the work of supporting it.
---
description: Supabase Auth conventions
globs: ["src/services/**", "src/features/auth/**"]
alwaysApply: false
---
# Supabase Auth
## Session handling
- Subscribe to `onAuthStateChange` **once**, at startup, and read session state
from there. Calling `getSession()` per screen leaves stale copies behind after
a background token refresh.
- Configure a storage adapter (`AsyncStorage`) with `persistSession: true`, or
the user is signed out on every cold start.
- `detectSessionInUrl: false` outside a browser.
## Authorisation
- Authentication proves identity. **Row Level Security grants access.** Signing
a user in changes nothing about what they can read.
- Never make an authorisation decision from a client-held user id. Only
`auth.uid()` inside a policy cannot be forged.
- Every table a signed-in user can reach needs a policy.
## Sign-out
- Clear any cached user-scoped state on sign-out — queries, profile, entitlements.
On a shared device the next user inherits whatever you left behind.
## Never
- Never store a session or token in plain app state that outlives sign-out.
- Never log a JWT, refresh token, or password.
- Never use the service-role key to work around a failing policy.
Hand-written by the module author, frontmatter and all. It is the source the four derived formats are rendered from, so a correction lands here first.
What else this module writes
The rule is one file of several. Selecting Supabase Auth contributes all of this too — merged with every other module you pick, with conflicts resolved rather than duplicated.
{{envPrefix}}AUTH_REDIRECT_URLoptional{{#if has.react-native}}Deep link the OAuth flow returns to.{{/if}}{{#unless has.react-native}}URL the OAuth flow returns to. Point it at the route that exchanges the code for a session.{{/unless}} Must match the dashboard exactly.Advisory history
Every time this rule turned out to be wrong, and what we did about it.
This rule has been accurate since it was published. That is a fact about the rule, not a promise about the future — which is the whole reason this section exists.
Pro tells you the day a correction lands that affects a repo you actually have.
See what Pro adds →Rules people add alongside this one
The wizard picks the rest of the stack with you, writes all 6 formats, and leaves a manifest so check can tell you when any of it drifts.