From 8164a1f1bfcd4865a948d58229cac67db779e87c Mon Sep 17 00:00:00 2001 From: Cemal Kilic Date: Thu, 30 Oct 2025 15:38:42 +0300 Subject: [PATCH 1/4] feat: add configurable JWT issuer for local auth development --- internal/start/start.go | 7 ++++++- pkg/config/auth.go | 1 + pkg/config/templates/config.toml | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/start/start.go b/internal/start/start.go index 22b8fa694..9f7ddc7d2 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -464,6 +464,11 @@ EOF formatMapForEnvConfig(utils.Config.Auth.Sms.TestOTP, &testOTP) } + jwtIssuer := utils.GetApiUrl("/auth/v1") + if utils.Config.Auth.JwtIssuer != "" { + jwtIssuer = utils.Config.Auth.JwtIssuer + } + env := []string{ "API_EXTERNAL_URL=" + utils.Config.Api.ExternalUrl, @@ -482,7 +487,7 @@ EOF "GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated", fmt.Sprintf("GOTRUE_JWT_EXP=%v", utils.Config.Auth.JwtExpiry), "GOTRUE_JWT_SECRET=" + utils.Config.Auth.JwtSecret.Value, - "GOTRUE_JWT_ISSUER=" + utils.GetApiUrl("/auth/v1"), + "GOTRUE_JWT_ISSUER=" + jwtIssuer, fmt.Sprintf("GOTRUE_EXTERNAL_EMAIL_ENABLED=%v", utils.Config.Auth.Email.EnableSignup), fmt.Sprintf("GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED=%v", utils.Config.Auth.Email.DoubleConfirmChanges), diff --git a/pkg/config/auth.go b/pkg/config/auth.go index 82fc0eef7..44edb4f50 100644 --- a/pkg/config/auth.go +++ b/pkg/config/auth.go @@ -152,6 +152,7 @@ type ( SiteUrl string `toml:"site_url"` AdditionalRedirectUrls []string `toml:"additional_redirect_urls"` JwtExpiry uint `toml:"jwt_expiry"` + JwtIssuer string `toml:"jwt_issuer"` EnableRefreshTokenRotation bool `toml:"enable_refresh_token_rotation"` RefreshTokenReuseInterval uint `toml:"refresh_token_reuse_interval"` EnableManualLinking bool `toml:"enable_manual_linking"` diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index ebdb83103..47d44d3c7 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -125,6 +125,8 @@ site_url = "http://127.0.0.1:3000" additional_redirect_urls = ["https://127.0.0.1:3000"] # How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). jwt_expiry = 3600 +# JWT issuer URL. If not set, defaults to the local API URL (http://127.0.0.1:/auth/v1). +# jwt_issuer = "" # Path to JWT signing key. DO NOT commit your signing keys file to git. # signing_keys_path = "./signing_keys.json" # If disabled, the refresh token will never expire. From 73a484e27e251d2e3c173b4ebddb5fc89081fdf3 Mon Sep 17 00:00:00 2001 From: Cemal Kilic Date: Mon, 3 Nov 2025 15:56:09 +0300 Subject: [PATCH 2/4] fix: set jwt_issuer default during config loading --- internal/start/start.go | 7 +------ pkg/config/config.go | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/internal/start/start.go b/internal/start/start.go index 9f7ddc7d2..c23e37b4f 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -464,11 +464,6 @@ EOF formatMapForEnvConfig(utils.Config.Auth.Sms.TestOTP, &testOTP) } - jwtIssuer := utils.GetApiUrl("/auth/v1") - if utils.Config.Auth.JwtIssuer != "" { - jwtIssuer = utils.Config.Auth.JwtIssuer - } - env := []string{ "API_EXTERNAL_URL=" + utils.Config.Api.ExternalUrl, @@ -487,7 +482,7 @@ EOF "GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated", fmt.Sprintf("GOTRUE_JWT_EXP=%v", utils.Config.Auth.JwtExpiry), "GOTRUE_JWT_SECRET=" + utils.Config.Auth.JwtSecret.Value, - "GOTRUE_JWT_ISSUER=" + jwtIssuer, + "GOTRUE_JWT_ISSUER=" + utils.Config.Auth.JwtIssuer, fmt.Sprintf("GOTRUE_EXTERNAL_EMAIL_ENABLED=%v", utils.Config.Auth.Email.EnableSignup), fmt.Sprintf("GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED=%v", utils.Config.Auth.Email.DoubleConfirmChanges), diff --git a/pkg/config/config.go b/pkg/config/config.go index 531bc3dea..e3ca3fc29 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -583,6 +583,10 @@ func (c *config) Load(path string, fsys fs.FS, overrides ...ConfigEditor) error } c.Api.ExternalUrl = apiUrl.String() } + // Set default JWT issuer if not configured + if len(c.Auth.JwtIssuer) == 0 { + c.Auth.JwtIssuer = c.Api.ExternalUrl + "/auth/v1" + } // Update image versions switch c.Db.MajorVersion { case 13: From de9af1d3e06f30041c822c704e684feab8ca5397 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 5 Nov 2025 16:19:12 +0800 Subject: [PATCH 3/4] chore: build verify url from jwt issuer --- internal/start/start.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/start/start.go b/internal/start/start.go index c23e37b4f..5ce3767d5 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -494,10 +494,10 @@ EOF fmt.Sprintf("GOTRUE_SMTP_MAX_FREQUENCY=%v", utils.Config.Auth.Email.MaxFrequency), - "GOTRUE_MAILER_URLPATHS_INVITE=" + utils.GetApiUrl("/auth/v1/verify"), - "GOTRUE_MAILER_URLPATHS_CONFIRMATION=" + utils.GetApiUrl("/auth/v1/verify"), - "GOTRUE_MAILER_URLPATHS_RECOVERY=" + utils.GetApiUrl("/auth/v1/verify"), - "GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=" + utils.GetApiUrl("/auth/v1/verify"), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_INVITE=%s/verify", utils.Config.Auth.JwtIssuer), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_CONFIRMATION=%s/verify", utils.Config.Auth.JwtIssuer), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_RECOVERY=%s/verify", utils.Config.Auth.JwtIssuer), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=%s/verify", utils.Config.Auth.JwtIssuer), "GOTRUE_RATE_LIMIT_EMAIL_SENT=360000", fmt.Sprintf("GOTRUE_EXTERNAL_PHONE_ENABLED=%v", utils.Config.Auth.Sms.EnableSignup), From 467b5f149076bf2da6ff96d50a99aaac399e354c Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 5 Nov 2025 16:24:02 +0800 Subject: [PATCH 4/4] chore: build redirect uri from issuer url --- internal/start/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/start/start.go b/internal/start/start.go index 5ce3767d5..2fadf7e0a 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -699,7 +699,7 @@ EOF redirectUri := config.RedirectUri if redirectUri == "" { - redirectUri = utils.GetApiUrl("/auth/v1/callback") + redirectUri = utils.Config.Auth.JwtIssuer + "/callback" } env = append(env, fmt.Sprintf("GOTRUE_EXTERNAL_%s_REDIRECT_URI=%s", strings.ToUpper(name), redirectUri))