fix(auth): decouple provider enabled from signup control
Correction
Updated to Documentation-Only
After reviewer feedback, this is now a documentation improvement rather than code change.
What Changed
Updated [auth.email].enable_signup and [auth.sms].enable_signup comments in config templates to clarify:
- These control the entire provider (GOTRUE_EXTERNAL_*_ENABLED), not just signup
-
false= provider disabled (no login/invites/OTP/signup) -
true= provider enabled (signup requires[auth].enable_signup=true) - Added configuration examples for invite-only, open signups, and disabled providers
Issue: supabase/supabase#40582 Companion PR: supabase/supabase#40575
Original PR
Fixes supabase/supabase#40582
Problem
When using invite-only authentication ([auth].enable_signup=false and [auth.email].enable_signup=false), the CLI incorrectly disables the entire email/phone authentication providers instead of just preventing self-signups.
This causes:
-
422 email_provider_disablederrors when attempting to use OTP/magic links - Users unable to accept invites in invite-only flows
- Confusing behavior where config semantics don't match expectations
Root Cause
Lines 487 and 502 in internal/start/start.go map:
-
utils.Config.Auth.Email.EnableSignup→GOTRUE_EXTERNAL_EMAIL_ENABLED -
utils.Config.Auth.Sms.EnableSignup→GOTRUE_EXTERNAL_PHONE_ENABLED
This conflates two distinct concerns:
- Provider existence (should the provider be available at all?)
- Signup control (can users self-signup via this provider?)
Solution
Set GOTRUE_EXTERNAL_EMAIL_ENABLED=true and GOTRUE_EXTERNAL_PHONE_ENABLED=true when auth is enabled, since:
- The outer
if utils.Config.Auth.Enabledcheck (line 460) already gates provider initialization - Email/SMS config structs have no
Enabledfield, onlyEnableSignup - Signup is controlled separately via
GOTRUE_DISABLE_SIGNUP(line 478)
This fixes the inconsistency:
- Email/phone providers (Supabase's built-in authentication) should be enabled when auth is configured
-
EnableSignupshould only control whether users can self-register, not whether the provider exists - OAuth providers (Google/GitHub/etc.) use a separate
provider.Enabledfield for this reason - The Docker Compose fix (supabase/supabase#40575) introduces separate ENABLE_EMAIL_PROVIDER and ENABLE_PHONE_PROVIDER variables following the same pattern
Testing
Before:
[auth]
enable_signup = false
[auth.email]
enable_signup = false
After: Same config now works - invites accepted ✅, OTP works ✅, self-signup blocked ✅
Fixes supabase/supabase# Companion PR: supabase/supabase#40575 (Docker Compose fix)
Pull Request Test Coverage Report for Build 19531912999
Details
- 0 of 0 changed or added relevant lines in 0 files are covered.
- 5 unchanged lines in 1 file lost coverage.
- Overall coverage decreased (-0.03%) to 55.082%
| Files with Coverage Reduction | New Missed Lines | % |
|---|---|---|
| internal/gen/keys/keys.go | 5 | 12.9% |
| <!-- | Total: | 5 |
| Totals | |
|---|---|
| Change from base Build 19526850899: | -0.03% |
| Covered Lines: | 6530 |
| Relevant Lines: | 11855 |
💛 - Coveralls
Unfortunately your change makes [auth.email] enable_signup = false completely useless as the email provider will always be enabled.
When using invite-only authentication ([auth].enable_signup=false and [auth.email].enable_signup=false), the CLI incorrectly disables the entire email/phone authentication providers instead of just preventing self-signups.
To achieve what you described, you want to use the following config instead.
[auth]
enable_signup = false
[auth.email]
enable_signup = true
You are correct! My apologies for the confusion.
However, I think the current comment could be clearer since this setting does more than just control signups. What if we changed:
[auth.email]
# Allow/disallow new user signups via email to your project.
enable_signup = true
To something like:
[auth.email]
# Controls whether the email authentication provider is enabled (GOTRUE_EXTERNAL_EMAIL_ENABLED).
#
# false = Email provider completely disabled (no login, invites, OTP, or signup)
# true = Email provider enabled (login, invites, OTP work; signup requires [auth].enable_signup=true)
#
# Common configurations:
# Invite-only: [auth].enable_signup=false, [auth.email].enable_signup=true
# Open signups: [auth].enable_signup=true, [auth.email].enable_signup=true
# No email auth: [auth.email].enable_signup=false (regardless of [auth].enable_signup)
enable_signup = true
This would help prevent others from encountering the same confusion I did. Happy to update both my PRs to just improve the documentation if that would be helpful!
@sweatybridge Updated the issue and both PR's, hope this is more helpful ☺️