From 6ed95165d3db5c888d8a7afa1bdacafc66389047 Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Tue, 5 May 2026 13:04:14 +0200 Subject: [PATCH] feat(config): OIDC provider config skeleton (ADR-0028 Phase B.1 prep) (#64) Co-authored-by: Gabriel Radureau Co-committed-by: Gabriel Radureau --- pkg/config/config.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 453b155..185b5b2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -109,6 +109,7 @@ type AuthConfig struct { JWT JWTConfig `mapstructure:"jwt"` Email EmailConfig `mapstructure:"email"` MagicLink MagicLinkConfig `mapstructure:"magic_link"` + OIDC OIDCConfig `mapstructure:"oidc"` } // MagicLinkConfig holds passwordless-auth magic-link parameters (ADR-0028 Phase A). @@ -117,6 +118,19 @@ type MagicLinkConfig struct { BaseURL string `mapstructure:"base_url"` } +// OIDCConfig holds OpenID Connect provider configuration (ADR-0028 Phase B). +// Multiple providers are supported via a map keyed by provider name (e.g. "arcodange-sso", "google"). +type OIDCConfig struct { + Providers map[string]OIDCProvider `mapstructure:"providers"` +} + +// OIDCProvider describes a single OIDC provider's discovery + client config. +type OIDCProvider struct { + IssuerURL string `mapstructure:"issuer_url"` + ClientID string `mapstructure:"client_id"` + ClientSecret string `mapstructure:"client_secret"` +} + // EmailConfig holds outgoing email transport configuration. // Defaults match local Mailpit (cf. ADR-0029) so dev needs no extra setup. type EmailConfig struct { @@ -287,6 +301,10 @@ func LoadConfig() (*Config, error) { v.SetDefault("auth.magic_link.ttl", 15*time.Minute) v.SetDefault("auth.magic_link.base_url", "http://localhost:8080") + // OIDC defaults (ADR-0028 Phase B). Providers map is empty by default; + // configured per environment via config file or env vars. + v.SetDefault("auth.oidc.providers", map[string]interface{}{}) + // Check for custom config file path via environment variable if configFile := os.Getenv("DLC_CONFIG_FILE"); configFile != "" { v.SetConfigFile(configFile) @@ -343,6 +361,13 @@ func LoadConfig() (*Config, error) { // Magic-link environment variables (ADR-0028 Phase A). v.BindEnv("auth.magic_link.ttl", "DLC_AUTH_MAGIC_LINK_TTL") v.BindEnv("auth.magic_link.base_url", "DLC_AUTH_MAGIC_LINK_BASE_URL") + + // OIDC environment variables (ADR-0028 Phase B). One canonical "default" + // provider is bindable via env; additional providers must be defined in config.yaml. + v.BindEnv("auth.oidc.providers.default.issuer_url", "DLC_AUTH_OIDC_ISSUER_URL") + v.BindEnv("auth.oidc.providers.default.client_id", "DLC_AUTH_OIDC_CLIENT_ID") + v.BindEnv("auth.oidc.providers.default.client_secret", "DLC_AUTH_OIDC_CLIENT_SECRET") + v.BindEnv("telemetry.sampler.type", "DLC_TELEMETRY_SAMPLER_TYPE") v.BindEnv("telemetry.sampler.ratio", "DLC_TELEMETRY_SAMPLER_RATIO") @@ -494,6 +519,15 @@ func (c *Config) GetMagicLinkConfig() MagicLinkConfig { return out } +// GetOIDCProviders returns the configured OIDC providers, keyed by provider name. +// Empty map (not nil) is returned when no providers are configured. +func (c *Config) GetOIDCProviders() map[string]OIDCProvider { + if c.Auth.OIDC.Providers == nil { + return map[string]OIDCProvider{} + } + return c.Auth.OIDC.Providers +} + // GetJWTTTL returns the JWT TTL func (c *Config) GetJWTTTL() time.Duration { if c.Auth.JWT.TTL == 0 {