Files
fab75ca036 feat: add multi-issuer support based on host header (#124)
* feat: add multi-issuer support based on host header

Dynamically select the OIDC issuer from the incoming X-Forwarded-Host
(or Host) header, validated against a configured list of trusted
issuers. This allows the auth service to serve multiple domains with
correct issuer URLs in discovery and token endpoints.

Adds --auth-issuers flag for specifying additional trusted issuer URLs.

* Debug

Signed-off-by: Sylvain Rabot <[email protected]>

* fix: use dynamic OIDC provider so discovery reads issuer from host

The previous approach overrode the issuer in context, but ZITADEL's
discovery handler calls config.IssuerFromRequest(r) which invokes the
stored IssuerFromRequest function directly, bypassing context. Switch
from op.NewOpenIDProvider (StaticIssuer) to op.NewDynamicOpenIDProvider
(IssuerFromHost) and rewrite r.Host in chi middleware so ZITADEL
constructs the correct issuer URL per-request.

---------

Signed-off-by: Sylvain Rabot <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-02 10:39:11 +01:00

35 lines
783 B
Go

package oidc
import (
"net/http"
"net/url"
)
// HostFromRequest returns the effective host, preferring X-Forwarded-Host over Host.
func HostFromRequest(r *http.Request) string {
if fwd := r.Header.Get("X-Forwarded-Host"); fwd != "" {
return fwd
}
return r.Host
}
// IssuerForHost returns the trusted issuer matching the given host, or the default.
func IssuerForHost(host, defaultIssuer string, trustedIssuers []string) string {
for _, issuer := range trustedIssuers {
u, err := url.Parse(issuer)
if err == nil && u.Host == host {
return issuer
}
}
return defaultIssuer
}
// HostFromIssuer extracts the host component from an issuer URL.
func HostFromIssuer(issuer string) string {
u, err := url.Parse(issuer)
if err != nil {
return ""
}
return u.Host
}