Supabase Auth

supabase-authAuth29 lines

Email, OAuth and magic-link sign-in issuing the JWT that Row Level Security reads.

Current — as published in v1.3.2. Written by hand for Supabase Auth, not generated.

The rule

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.

As each tool receives it

The same guidance, in the shape each editor reads. Cursor and Claude Code are written separately by hand; the rest are derived from the Cursor rule.

.cursor/rules/supabase-auth.mdchand-written for this tool
.cursor/rules/supabase-auth.mdc
---
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.

What else this module writes

Selecting Supabase Auth contributes more than a rule file — all of it merged with every other module you pick, with conflicts resolved rather than duplicated.

Environment
EXPO_PUBLIC_AUTH_REDIRECT_URLoptionalDeep link the OAuth flow returns to. Must match the dashboard exactly.
Dependencies
@react-native-async-storage/async-storage^3.1.0expo-auth-session^57.0.0expo-web-browser^57.0.0
Folders
src/features/auth/screens/src/features/auth/components/src/hooks/auth/

Related

Put this in your repo

Adds Supabase Auth to a project this tool generated, without starting over. Files you have hand-edited are left alone.