diff --git a/cmd/lakefs/cmd/run.go b/cmd/lakefs/cmd/run.go index 76d8a118d74..66427d0d484 100644 --- a/cmd/lakefs/cmd/run.go +++ b/cmd/lakefs/cmd/run.go @@ -249,12 +249,15 @@ var runCmd = &cobra.Command{ if err != nil { logger.WithError(err).Fatal("Failed to initialize OIDC provider") } + scopes := []string{oidc.ScopeOpenID, "profile"} + + scopes = append(scopes, oidcConfig.AdditionalScopeClaims...) oauthConfig = &oauth2.Config{ ClientID: oidcConfig.ClientID, ClientSecret: oidcConfig.ClientSecret, RedirectURL: strings.TrimSuffix(oidcConfig.CallbackBaseURL, "/") + api.BaseURL + "/oidc/callback", Endpoint: oidcProvider.Endpoint(), - Scopes: []string{oidc.ScopeOpenID, "profile"}, + Scopes: scopes, } } apiHandler := api.Serve( diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index cc8be24bbea..84418c9deb3 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -96,10 +96,11 @@ This reference uses `.` to denote the nesting of values. * `auth.oidc.url` `(string : )` - The base URL of your OIDC compatible identity provider. * `auth.oidc.callback_base_url` `(string : )` - The scheme, host and port of your lakeFS installation. After authenticating, your identity provider will redirect you to a URL under this base. * `auth.oidc.default_initial_groups` `(string[] : [])` - By default, OIDC users will be assigned to these groups -* `auth.oidc.initial_groups_claim_name` `(string[] : [])` - Use this claim from the ID token to provide the initial group for new users. +* `auth.oidc.initial_groups_claim_name` `(string[] : [])` - Use this claim from the ID token to provide the initial group for new users. This will take priority if `auth.oidc.default_initial_groups` is also set. * `auth.oidc.friendly_name_claim_name` `(string[] : )` - If specified, the value from the claim with this name will be used as the user's display name. * `auth.oidc.authorize_endpoint_query_parameters` `(map[string]string : )` - Add these parameters when calling the provider's `/authorize` endpoint * `auth.oidc.validate_id_token_claims` `(map[string]string : )` - When a user tries to access lakeFS, validate that the ID token contains these claims with the corresponding values. +* `auth.oidc.additional_scope_claims` `(string[]: [])` - Add these additional scopes/claims to the OIDC user token. `openid` and `profile` are provided already. * `blockstore.type` `(one of ["local", "s3", "gs", "azure", "mem"] : required)`. Block adapter to use. This controls where the underlying data will be stored * `blockstore.default_namespace_prefix` `(string : )` - Use this to help your users choose a storage namespace for their repositories. If specified, the storage namespace will be filled with this default value as a prefix when creating a repository from the UI. diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 4d09edc5f67..4c182243116 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -180,6 +180,18 @@ func verifyAWSConfig(t *testing.T, c *config.Config) { } } +func verifyOIDCConfig(t *testing.T, c *config.Config) { + oidcConfig := c.GetAuthOIDCConfiguration() + + if !oidcConfig.Enabled { + t.Fatal("expected oidc to be enabled") + } + + if diffs := deep.Equal(oidcConfig.AdditionalScopeClaims, []string{"upn", "email"}); diffs != nil { + t.Fatalf("expected additional scopes upn and email, diffs %s", diffs) + } +} + func TestConfig_AWSConfig(t *testing.T) { t.Run("use secret_access_key configuration", func(t *testing.T) { c, err := newConfigFromFile("testdata/aws_credentials.yaml") @@ -192,3 +204,11 @@ func TestConfig_AWSConfig(t *testing.T) { verifyAWSConfig(t, c) }) } + +func TestConfig_OIDCConfig(t *testing.T) { + t.Run("use oidc configuration", func(t *testing.T) { + c, err := newConfigFromFile("testdata/valid_oidc_config.yaml") + testutil.Must(t, err) + verifyOIDCConfig(t, c) + }) +} diff --git a/pkg/config/template.go b/pkg/config/template.go index efd650b8929..2fe928856a3 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -22,6 +22,7 @@ type OIDC struct { DefaultInitialGroups []string `mapstructure:"default_initial_groups"` InitialGroupsClaimName string `mapstructure:"initial_groups_claim_name"` FriendlyNameClaimName string `mapstructure:"friendly_name_claim_name"` + AdditionalScopeClaims []string `mapstructure:"additional_scope_claims"` } // LDAP holds configuration for authenticating on an LDAP server. diff --git a/pkg/config/testdata/valid_oidc_config.yaml b/pkg/config/testdata/valid_oidc_config.yaml new file mode 100644 index 00000000000..12f2bbfe245 --- /dev/null +++ b/pkg/config/testdata/valid_oidc_config.yaml @@ -0,0 +1,44 @@ +--- +logging: + format: text + level: NONE + output: "-" + +database: + postgres: + connection_string: test:///dev/null + max_open_connections: 12 + max_idle_connections: 13 + connection_max_lifetime: 2s + +auth: + encrypt: + secret_key: "required in config" + oidc: + enabled: true + client_id: test-client + client_secret: client-client + callback_base_url: https://localhost:8000 + url: https://www.fake-oidc-provider.com + default_initial_groups: ["Admins"] + is_default_login: true + friendly_name_claim_name: email + additional_scope_claims: + - upn + - email + + +blockstore: + type: local + local: + path: /tmp + +gateways: + s3: + domain_name: + - s3.example.com + - gs3.example.com + - gcp.example.net + region: us-east-1 + +listen_address: "0.0.0.0:8005"