diff --git a/idp/dex/provider.go b/idp/dex/provider.go index fae682959..6a4fe7873 100644 --- a/idp/dex/provider.go +++ b/idp/dex/provider.go @@ -792,11 +792,12 @@ func (p *Provider) resolveRedirectURI(redirectURI string) string { // buildOIDCConnectorConfig creates config for OIDC-based connectors func buildOIDCConnectorConfig(cfg *ConnectorConfig, redirectURI string) ([]byte, error) { oidcConfig := map[string]interface{}{ - "issuer": cfg.Issuer, - "clientID": cfg.ClientID, - "clientSecret": cfg.ClientSecret, - "redirectURI": redirectURI, - "scopes": []string{"openid", "profile", "email"}, + "issuer": cfg.Issuer, + "clientID": cfg.ClientID, + "clientSecret": cfg.ClientSecret, + "redirectURI": redirectURI, + "scopes": []string{"openid", "profile", "email"}, + "insecureEnableGroups": true, } switch cfg.Type { case "zitadel": @@ -806,6 +807,9 @@ func buildOIDCConnectorConfig(cfg *ConnectorConfig, redirectURI string) ([]byte, oidcConfig["claimMapping"] = map[string]string{"email": "preferred_username"} case "okta": oidcConfig["insecureSkipEmailVerified"] = true + oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"} + case "pocketid": + oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"} } return encodeConnectorConfig(oidcConfig) } diff --git a/infrastructure_files/getting-started.sh b/infrastructure_files/getting-started.sh index b693f807e..5a9488fad 100755 --- a/infrastructure_files/getting-started.sh +++ b/infrastructure_files/getting-started.sh @@ -270,7 +270,7 @@ AUTH_CLIENT_ID=netbird-dashboard AUTH_CLIENT_SECRET= AUTH_AUTHORITY=$NETBIRD_HTTP_PROTOCOL://$NETBIRD_DOMAIN/oauth2 USE_AUTH0=false -AUTH_SUPPORTED_SCOPES=openid profile email offline_access +AUTH_SUPPORTED_SCOPES=openid profile email groups AUTH_REDIRECT_URI=/nb-auth AUTH_SILENT_REDIRECT_URI=/nb-silent-auth # SSL diff --git a/management/cmd/management.go b/management/cmd/management.go index 9dbd4a6d4..7da04074b 100644 --- a/management/cmd/management.go +++ b/management/cmd/management.go @@ -143,7 +143,7 @@ func loadMgmtConfig(ctx context.Context, mgmtConfigPath string) (*nbconfig.Confi applyCommandLineOverrides(loadedConfig) // Apply EmbeddedIdP config to HttpConfig if embedded IdP is enabled - err := applyEmbeddedIdPConfig(loadedConfig) + err := applyEmbeddedIdPConfig(ctx, loadedConfig) if err != nil { return nil, err } @@ -177,7 +177,7 @@ func applyCommandLineOverrides(cfg *nbconfig.Config) { // applyEmbeddedIdPConfig populates HttpConfig and EmbeddedIdP storage from config when embedded IdP is enabled. // This allows users to only specify EmbeddedIdP config without duplicating values in HttpConfig. -func applyEmbeddedIdPConfig(cfg *nbconfig.Config) error { +func applyEmbeddedIdPConfig(ctx context.Context, cfg *nbconfig.Config) error { if cfg.EmbeddedIdP == nil || !cfg.EmbeddedIdP.Enabled { return nil } @@ -193,11 +193,6 @@ func applyEmbeddedIdPConfig(cfg *nbconfig.Config) error { // Set LocalAddress for embedded IdP if enabled, used for internal JWT validation cfg.EmbeddedIdP.LocalAddress = fmt.Sprintf("localhost:%d", mgmtPort) - // Ensure HttpConfig exists - if cfg.HttpConfig == nil { - cfg.HttpConfig = &nbconfig.HttpServerConfig{} - } - // Set storage defaults based on Datadir if cfg.EmbeddedIdP.Storage.Type == "" { cfg.EmbeddedIdP.Storage.Type = "sqlite3" @@ -208,40 +203,22 @@ func applyEmbeddedIdPConfig(cfg *nbconfig.Config) error { issuer := cfg.EmbeddedIdP.Issuer - // Set AuthIssuer from EmbeddedIdP issuer - if cfg.HttpConfig.AuthIssuer == "" { - cfg.HttpConfig.AuthIssuer = issuer + if cfg.HttpConfig != nil { + log.WithContext(ctx).Warnf("overriding HttpConfig with EmbeddedIdP config. " + + "HttpConfig is ignored when EmbeddedIdP is enabled. Please remove HttpConfig section from the config file") + } else { + // Ensure HttpConfig exists. We need it for backwards compatibility with the old config format. + cfg.HttpConfig = &nbconfig.HttpServerConfig{} } - // Set AuthAudience to the dashboard client ID - if cfg.HttpConfig.AuthAudience == "" { - cfg.HttpConfig.AuthAudience = "netbird-dashboard" - } - - // Set CLIAuthAudience to the client app client ID - if cfg.HttpConfig.CLIAuthAudience == "" { - cfg.HttpConfig.CLIAuthAudience = "netbird-cli" - } - - // Set AuthUserIDClaim to "sub" (standard OIDC claim) - if cfg.HttpConfig.AuthUserIDClaim == "" { - cfg.HttpConfig.AuthUserIDClaim = "sub" - } - - // Set AuthKeysLocation to the JWKS endpoint - if cfg.HttpConfig.AuthKeysLocation == "" { - cfg.HttpConfig.AuthKeysLocation = issuer + "/keys" - } - - // Set OIDCConfigEndpoint to the discovery endpoint - if cfg.HttpConfig.OIDCConfigEndpoint == "" { - cfg.HttpConfig.OIDCConfigEndpoint = issuer + "/.well-known/openid-configuration" - } - - // Copy SignKeyRefreshEnabled from EmbeddedIdP config - if cfg.EmbeddedIdP.SignKeyRefreshEnabled { - cfg.HttpConfig.IdpSignKeyRefreshEnabled = true - } + // Set HttpConfig values from EmbeddedIdP + cfg.HttpConfig.AuthIssuer = issuer + cfg.HttpConfig.AuthAudience = "netbird-dashboard" + cfg.HttpConfig.CLIAuthAudience = "netbird-cli" + cfg.HttpConfig.AuthUserIDClaim = "sub" + cfg.HttpConfig.AuthKeysLocation = issuer + "/keys" + cfg.HttpConfig.OIDCConfigEndpoint = issuer + "/.well-known/openid-configuration" + cfg.HttpConfig.IdpSignKeyRefreshEnabled = true return nil } @@ -249,7 +226,12 @@ func applyEmbeddedIdPConfig(cfg *nbconfig.Config) error { // applyOIDCConfig fetches and applies OIDC configuration if endpoint is specified func applyOIDCConfig(ctx context.Context, cfg *nbconfig.Config) error { oidcEndpoint := cfg.HttpConfig.OIDCConfigEndpoint - if oidcEndpoint == "" || cfg.EmbeddedIdP != nil { + if oidcEndpoint == "" { + return nil + } + + if cfg.EmbeddedIdP != nil && cfg.EmbeddedIdP.Enabled { + // skip OIDC config fetching if EmbeddedIdP is enabled as it is unnecessary given it is embedded return nil } diff --git a/management/server/idp/embedded.go b/management/server/idp/embedded.go index 7b8e5033c..0e46b506e 100644 --- a/management/server/idp/embedded.go +++ b/management/server/idp/embedded.go @@ -20,7 +20,7 @@ const ( staticClientCLI = "netbird-cli" defaultCLIRedirectURL1 = "http://localhost:53000/" defaultCLIRedirectURL2 = "http://localhost:54000/" - defaultScopes = "openid profile email offline_access" + defaultScopes = "openid profile email" defaultUserIDClaim = "sub" )