Prerequisites
Rclone Pre-flight Checklist (if applicable)
Bug Description
When Zerobyte runs behind an HTTPS reverse proxy that terminates TLS and forwards to the container over plain HTTP (typical Nginx / Nginx Proxy Manager setup), SSO/OIDC sign-in builds an OAuth redirect_uri with the http:// scheme even though:
BASE_URL is set to https://…
- The proxy sends
X-Forwarded-Proto: https (and X-Forwarded-Scheme: https)
TRUST_PROXY=true
Authentik (and most IdPs) only allow the HTTPS callback, so login fails with an invalid redirect URI.
Root cause appears to be better-auth config in app/server/lib/auth.ts:
baseURL.protocol is "auto"
advanced.trustedProxyHeaders is not set
Per better-auth docs, with protocol: "auto", X-Forwarded-Proto is only honored when advanced.trustedProxyHeaders: true. Otherwise the request URL scheme is used — which is http on the internal Docker network. TRUST_PROXY only affects X-Forwarded-For for rate limiting / IP handling; it does not enable trusted proxy headers for better-auth URL construction. BASE_URL is only used as a fallback, not for the live redirect_uri.
Steps to Reproduce
-
Deploy Zerobyte v0.43.0 with Docker Compose behind a reverse proxy that terminates TLS and proxies to http://zerobyte:4096.
-
Set env:
BASE_URL=https://zerobyte.example.com
TRUST_PROXY=true
TRUSTED_ORIGINS=https://zerobyte.example.com,https://auth.example.com
-
Ensure the proxy sets Host, X-Forwarded-For, and X-Forwarded-Proto: https (NPM/nginx stock config does this).
-
Configure an OIDC SSO provider (e.g. Authentik) with callback
https://zerobyte.example.com/api/auth/sso/callback/<providerId> only.
-
Start SSO sign-in, e.g.:
curl -s -X POST 'https://zerobyte.example.com/api/auth/sign-in/sso' \
-H 'Content-Type: application/json' \
-d '{"providerId":"<providerId>","callbackURL":"/"}'
-
Inspect the returned url → query param redirect_uri.
Expected Behavior
redirect_uri should use HTTPS, matching the public URL / BASE_URL scheme, e.g.:
redirect_uri=https://zerobyte.example.com/api/auth/sso/callback/<providerId>
One possible approach (happy to defer to maintainers): honor X-Forwarded-Proto when behind a reverse proxy (e.g. advanced.trustedProxyHeaders: true alongside TRUST_PROXY=true), or derive better-auth protocol from the scheme of BASE_URL instead of "auto".
Zerobyte version / commit
v0.43.0
Deployment Method
Docker Compose
Backup/Repository Context
N/A (SSO / auth only)
Logs / Error Messages
Response from POST /api/auth/sign-in/sso (sanitized; client_id / state / PKCE redacted):
{
"url": "https://auth.example.com/application/o/authorize/?response_type=code&client_id=REDACTED&state=REDACTED&scope=openid+email+profile&redirect_uri=http%3A%2F%2Fzerobyte.example.com%2Fapi%2Fauth%2Fsso%2Fcallback%2Fauthentik&code_challenge_method=S256&code_challenge=REDACTED",
"redirect": true
}
Decoded redirect_uri:
http://zerobyte.example.com/api/auth/sso/callback/authentik
Proxy headers on the same NPM stack (checked with a whoami-style upstream) include X-Forwarded-Proto: https. Sending that header explicitly to Zerobyte still produces http in redirect_uri.
Relevant config from upstream source:
baseURL: {
allowedHosts: config.allowedHosts,
protocol: "auto",
fallback: config.baseUrl,
},
advanced: {
cookiePrefix: "zerobyte",
useSecureCookies: config.isSecure,
// trustedProxyHeaders not set
ipAddress: { ... },
},
IdP error (Authentik): redirect URI mismatch, only the HTTPS callback is registered.
Prerequisites
Rclone Pre-flight Checklist (if applicable)
rclone listremotesandrclone lsd remote:on the host and they workBug Description
When Zerobyte runs behind an HTTPS reverse proxy that terminates TLS and forwards to the container over plain HTTP (typical Nginx / Nginx Proxy Manager setup), SSO/OIDC sign-in builds an OAuth
redirect_uriwith thehttp://scheme even though:BASE_URLis set tohttps://…X-Forwarded-Proto: https(andX-Forwarded-Scheme: https)TRUST_PROXY=trueAuthentik (and most IdPs) only allow the HTTPS callback, so login fails with an invalid redirect URI.
Root cause appears to be better-auth config in
app/server/lib/auth.ts:baseURL.protocolis"auto"advanced.trustedProxyHeadersis not setPer better-auth docs, with
protocol: "auto",X-Forwarded-Protois only honored whenadvanced.trustedProxyHeaders: true. Otherwise the request URL scheme is used — which ishttpon the internal Docker network.TRUST_PROXYonly affectsX-Forwarded-Forfor rate limiting / IP handling; it does not enable trusted proxy headers for better-auth URL construction.BASE_URLis only used as a fallback, not for the liveredirect_uri.Steps to Reproduce
Deploy Zerobyte
v0.43.0with Docker Compose behind a reverse proxy that terminates TLS and proxies tohttp://zerobyte:4096.Set env:
BASE_URL=https://zerobyte.example.comTRUST_PROXY=trueTRUSTED_ORIGINS=https://zerobyte.example.com,https://auth.example.comEnsure the proxy sets
Host,X-Forwarded-For, andX-Forwarded-Proto: https(NPM/nginx stock config does this).Configure an OIDC SSO provider (e.g. Authentik) with callback
https://zerobyte.example.com/api/auth/sso/callback/<providerId>only.Start SSO sign-in, e.g.:
Inspect the returned
url→ query paramredirect_uri.Expected Behavior
redirect_urishould use HTTPS, matching the public URL /BASE_URLscheme, e.g.:One possible approach (happy to defer to maintainers): honor
X-Forwarded-Protowhen behind a reverse proxy (e.g.advanced.trustedProxyHeaders: truealongsideTRUST_PROXY=true), or derive better-authprotocolfrom the scheme ofBASE_URLinstead of"auto".Zerobyte version / commit
v0.43.0
Deployment Method
Docker Compose
Backup/Repository Context
N/A (SSO / auth only)
Logs / Error Messages
Response from
POST /api/auth/sign-in/sso(sanitized;client_id/state/ PKCE redacted):{ "url": "https://auth.example.com/application/o/authorize/?response_type=code&client_id=REDACTED&state=REDACTED&scope=openid+email+profile&redirect_uri=http%3A%2F%2Fzerobyte.example.com%2Fapi%2Fauth%2Fsso%2Fcallback%2Fauthentik&code_challenge_method=S256&code_challenge=REDACTED", "redirect": true }Decoded
redirect_uri:Proxy headers on the same NPM stack (checked with a whoami-style upstream) include
X-Forwarded-Proto: https. Sending that header explicitly to Zerobyte still produceshttpinredirect_uri.Relevant config from upstream source:
IdP error (Authentik): redirect URI mismatch, only the HTTPS callback is registered.