diff --git a/hscontrol/oidc.go b/hscontrol/oidc.go index 7f1e3fae5..b80683407 100644 --- a/hscontrol/oidc.go +++ b/hscontrol/oidc.go @@ -98,6 +98,12 @@ func NewAuthProviderOIDC( Scopes: cfg.Scope, } + // Some OIDC providers (e.g. GitHub Actions) omit authorization_endpoint + // from their discovery document. Allow users to override it explicitly. + if cfg.AuthorizationEndpoint != "" { + oauth2Config.Endpoint.AuthURL = cfg.AuthorizationEndpoint + } + authCache := expirable.NewLRU[string, AuthInfo]( authCacheMaxEntries, nil, diff --git a/hscontrol/types/config.go b/hscontrol/types/config.go index 6a6d59dcb..9887974da 100644 --- a/hscontrol/types/config.go +++ b/hscontrol/types/config.go @@ -229,6 +229,11 @@ type OIDCConfig struct { EmailVerifiedRequired bool UseExpiryFromToken bool PKCE PKCEConfig + // AuthorizationEndpoint allows overriding the authorization endpoint + // returned by the OIDC provider discovery document. This is required + // for providers (such as GitHub Actions OIDC) that do not include + // authorization_endpoint in their discovery metadata. + AuthorizationEndpoint string } type DERPConfig struct { @@ -1266,7 +1271,8 @@ func LoadServerConfig() (*Config, error) { AllowedUsers: viper.GetStringSlice("oidc.allowed_users"), AllowedGroups: viper.GetStringSlice("oidc.allowed_groups"), EmailVerifiedRequired: viper.GetBool("oidc.email_verified_required"), - UseExpiryFromToken: viper.GetBool("oidc.use_expiry_from_token"), + UseExpiryFromToken: viper.GetBool("oidc.use_expiry_from_token"), + AuthorizationEndpoint: viper.GetString("oidc.authorization_endpoint"), PKCE: PKCEConfig{ Enabled: viper.GetBool("oidc.pkce.enabled"), Method: viper.GetString("oidc.pkce.method"),