Skip to content

refactor: encode auth external url explicitly#5092

Open
jgoux wants to merge 2 commits intodevelopfrom
refactor--encode-auth-external-url-explicitly
Open

refactor: encode auth external url explicitly#5092
jgoux wants to merge 2 commits intodevelopfrom
refactor--encode-auth-external-url-explicitly

Conversation

@jgoux
Copy link
Copy Markdown
Contributor

@jgoux jgoux commented Apr 16, 2026

Summary

This PR simplifies how the CLI wires Supabase Auth / GoTrue URLs in local development so the values we pass match what upstream supabase/auth actually expects.

Before this change, the CLI passed the bare API external URL as API_EXTERNAL_URL, then separately prebuilt auth-specific URLs in several places by appending /auth/v1, /verify, and /callback. Upstream Auth already knows how to derive those paths from its external URL, so this created duplicated logic in the CLI and made the setup easier to misconfigure.

This PR introduces a single canonical auth external URL, uses it consistently for GoTrue, and stops precomputing auth callback / mailer URLs that Auth can derive on its own.

What changed

1. Added auth.external_url

A new optional config field was added:

[auth]
external_url = ""

Its purpose is to represent the public URL that Auth serves on, including the /auth/v1 prefix in the local stack.

Behavior:

  • If auth.external_url is unset, it now defaults to api.external_url + "/auth/v1".
  • If auth.external_url is explicitly set, that value is preserved as-is.
  • auth.jwt_issuer still remains a separate explicit override and is preserved as-is when set.

2. GoTrue now receives the auth-scoped external URL

The CLI now passes:

  • API_EXTERNAL_URL=<auth external url>
  • GOTRUE_JWT_ISSUER=<auth.jwt_issuer>

instead of using the bare API external URL for API_EXTERNAL_URL.

This matches upstream supabase/auth behavior more closely, where:

  • API_EXTERNAL_URL is the public base URL GoTrue thinks it lives at
  • OAuth callbacks are derived as API_EXTERNAL_URL + "/callback"
  • mailer links are derived from API_EXTERNAL_URL plus configured relative paths
  • SAML metadata / ACS / SLO URLs also use API_EXTERNAL_URL

This change was applied both to the long-running GoTrue container and the auth migration job so the behavior stays consistent.

3. Stopped prebuilding mailer URLs in the CLI

The CLI no longer sends fully-qualified mailer paths like:

  • <jwt_issuer>/verify

Instead, it now sends the relative values GoTrue expects:

  • /verify

for:

  • GOTRUE_MAILER_URLPATHS_INVITE
  • GOTRUE_MAILER_URLPATHS_CONFIRMATION
  • GOTRUE_MAILER_URLPATHS_RECOVERY
  • GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE

This lets Auth resolve them against its own external URL instead of the CLI building those URLs itself.

4. Provider redirect overrides are now opt-in only

For built-in external providers, the CLI used to always send GOTRUE_EXTERNAL_<PROVIDER>_REDIRECT_URI, defaulting it to <jwt_issuer>/callback when redirect_uri was empty.

Now:

  • if [auth.external.<provider>].redirect_uri is explicitly set, the CLI passes it through unchanged
  • if it is empty, the CLI omits that env var entirely and lets GoTrue derive the callback from API_EXTERNAL_URL

This keeps explicit user overrides working while removing duplicated default callback logic from the CLI.

5. Updated docs/comments

  • Added auth.external_url to the generated config template
  • Updated the jwt_issuer comment to reflect the new defaulting behavior
  • Clarified the redirect_uri comment for providers
  • Updated Kong template comments to describe the current routing more accurately:
    • external /auth/v1/*
    • internal GoTrue root paths like /verify, /callback, /authorize

Why this helps

This reduces duplicated URL construction logic in the CLI and aligns the local stack with upstream Auth’s contract.

Benefits:

  • fewer places in the CLI manually append /auth/v1, /verify, and /callback
  • less risk of accidental double-appends like /auth/v1/auth/v1
  • clearer separation between:
    • the public Auth base URL (auth.external_url)
    • the token issuer (auth.jwt_issuer)
    • optional explicit provider callback overrides (redirect_uri)
  • behavior that is closer to how upstream supabase/auth is designed to work

Compatibility / behavior notes

This PR preserves existing explicit overrides:

  • auth.jwt_issuer is still authoritative when set
  • [auth.external.<provider>].redirect_uri is still authoritative when set
  • provider url overrides are unchanged

This PR does not remove Kong path stripping. That remains necessary because upstream Auth still serves routes at root paths like /verify, /callback, and /authorize, rather than under a configurable base path such as /auth/v1.

@jgoux jgoux requested a review from a team as a code owner April 16, 2026 09:49
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 16, 2026

Coverage Report for CI Build 24723674117

Coverage decreased (-0.02%) to 63.667%

Details

  • Coverage decreased (-0.02%) from the base build.
  • Patch coverage: 4 uncovered changes across 1 file (87 of 91 lines covered, 95.6%).
  • 5 coverage regressions across 1 file.

Uncovered Changes

File Changed Covered %
internal/start/start.go 90 86 95.56%

Coverage Regressions

5 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
internal/utils/git.go 5 57.14%

Coverage Stats

Coverage Status
Relevant Lines: 15501
Covered Lines: 9869
Line Coverage: 63.67%
Coverage Strength: 7.01 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants