Skip to content

Debugging auth

Supabase manages auth. Plaintext passwords are never stored — GoTrue bcrypts them on signup and keeps only the hash in auth.users.encrypted_password.

The auth schema is locked down: anon and authenticated roles have no select on it. Only the service_role key (or a direct Postgres superuser connection) can read it.

Dashboard → Authentication → Users:

  • Email, UUID, provider, last sign-in, created-at.
  • Password hash is not shown in the UI.
  • You can trigger a password reset email or set a new password as admin, but cannot view the existing one.

Local stack only — Postgres exposed on 127.0.0.1:54322 by supabase start.

Terminal window
psql "postgres://postgres:postgres@127.0.0.1:54322/postgres" \
-c "select id, email, encrypted_password, last_sign_in_at from auth.users;"

Hash format is bcrypt: $2a$10$.... Useless without cracking — verifies a guess, doesn’t reveal the password.

Dump the whole auth schema (data only):

Terminal window
supabase db dump --local --data-only -s auth
  1. Dashboard → Project settings → Database → Connection string (use the direct connection, not the pooler, for psql).
  2. Run the same select query as above.
  3. Service role key works for the REST admin API (/auth/v1/admin/users) but returns metadata only, not the hash.
  • App side: trigger Supabase password recovery email.
  • Admin: dashboard user row → “Send recovery” or “Reset password”.
  • Local seed: edit projects/db/supabase/seed.sql and re-run supabase db reset. Default dev user is rhys@example.com / password123.
  • auth.users is not in the public schema — RLS policies on public.profiles reference auth.uid() but you cannot join directly from anon-role queries.
  • New Supabase CLI uses sb_publishable_* / sb_secret_* keys. Service role key is the sb_secret_* one — guard it like a root credential.
  • A password reset invalidates existing refresh tokens for that user. Expect re-login on all devices.