Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds OIDC namespace_in_state option #140

Merged
merged 7 commits into from
Oct 29, 2020
Merged

Conversation

tvoran
Copy link
Member

@tvoran tvoran commented Oct 19, 2020

Overview

Add an option to the OIDC config to pass namespace in the state parameter instead of as a separate query parameter. With this setting the allowed redirect URL in Vault and on the provider side should not contain a namespace query parameter. This means only one redirect URL entry needs to be maintained on the provider side for all vault namespaces that will be authenticating against it.

To test this, I've been doing something like this along with the vault PR hashicorp/vault#10171:

  • yarn start in the vault/ui directory to start the UI in live-reloading/dev mode
  • ./scripts/local_dev.sh in this vault-plugin-auth-jwt repo, with a vault enterprise binary in your path
  • visit the UI at http://localhost:4200/

Design of Change

A config option in the OIDC config

Related Issues/Pull Requests

Contributor Checklist

❯ make test TESTARGS="-count=1" 
VAULT_ACC=1 go test -tags='vault-plugin-auth-jwt' $(go list ./... | grep -v /vendor/) -v -count=1 -timeout 10m
=== RUN   TestGetClaim
--- PASS: TestGetClaim (0.00s)
=== RUN   TestExtractMetadata
--- PASS: TestExtractMetadata (0.00s)
=== RUN   TestValidateAudience
--- PASS: TestValidateAudience (0.00s)
=== RUN   TestValidateBoundClaims
--- PASS: TestValidateBoundClaims (0.00s)
=== RUN   Test_normalizeList
--- PASS: Test_normalizeList (0.00s)
=== RUN   TestParseHelp
=== RUN   TestParseHelp/#00
=== RUN   TestParseHelp/#01
=== RUN   TestParseHelp/#02
=== RUN   TestParseHelp/#03
=== RUN   TestParseHelp/#04
=== RUN   TestParseHelp/#05
--- PASS: TestParseHelp (0.00s)
    --- PASS: TestParseHelp/#00 (0.00s)
    --- PASS: TestParseHelp/#01 (0.00s)
    --- PASS: TestParseHelp/#02 (0.00s)
    --- PASS: TestParseHelp/#03 (0.00s)
    --- PASS: TestParseHelp/#04 (0.00s)
    --- PASS: TestParseHelp/#05 (0.00s)
=== RUN   TestConfig_JWT_Read
--- PASS: TestConfig_JWT_Read (0.00s)
=== RUN   TestConfig_JWT_Write
--- PASS: TestConfig_JWT_Write (0.00s)
=== RUN   TestConfig_JWKS_Update
--- PASS: TestConfig_JWKS_Update (0.00s)
=== RUN   TestConfig_JWKS_Update_Invalid
--- PASS: TestConfig_JWKS_Update_Invalid (0.00s)
=== RUN   TestConfig_ResponseMode
--- PASS: TestConfig_ResponseMode (0.00s)
=== RUN   TestConfig_OIDC_Write
--- PASS: TestConfig_OIDC_Write (0.31s)
=== RUN   TestConfig_OIDC_Write_ProviderConfig
=== RUN   TestConfig_OIDC_Write_ProviderConfig/valid_provider_config
=== RUN   TestConfig_OIDC_Write_ProviderConfig/unknown_provider_in_provider_config
=== RUN   TestConfig_OIDC_Write_ProviderConfig/provider_config_missing_provider
=== RUN   TestConfig_OIDC_Write_ProviderConfig/provider_config_not_set
--- PASS: TestConfig_OIDC_Write_ProviderConfig (0.11s)
    --- PASS: TestConfig_OIDC_Write_ProviderConfig/valid_provider_config (0.03s)
    --- PASS: TestConfig_OIDC_Write_ProviderConfig/unknown_provider_in_provider_config (0.03s)
    --- PASS: TestConfig_OIDC_Write_ProviderConfig/provider_config_missing_provider (0.03s)
    --- PASS: TestConfig_OIDC_Write_ProviderConfig/provider_config_not_set (0.02s)
=== RUN   TestLogin_JWT
--- PASS: TestLogin_JWT (0.02s)
=== RUN   TestLogin_Leeways
--- PASS: TestLogin_Leeways (0.17s)
=== RUN   TestLogin_OIDC
2020-10-26T14:21:59.920-0700 [WARN]  unable to locate /org/primary in claims: /org/primary at part 0: couldn't find key "org"
--- PASS: TestLogin_OIDC (0.30s)
=== RUN   TestLogin_NestedGroups
--- PASS: TestLogin_NestedGroups (0.00s)
=== RUN   TestLogin_OIDC_StringGroupClaim
2020-10-26T14:22:00.079-0700 [WARN]  unable to locate /org/primary in claims: /org/primary at part 0: couldn't find key "org"
--- PASS: TestLogin_OIDC_StringGroupClaim (0.16s)
=== RUN   TestLogin_JWKS_Concurrent
--- PASS: TestLogin_JWKS_Concurrent (0.25s)
=== RUN   TestOIDC_AuthURL
=== RUN   TestOIDC_AuthURL/normal_case
=== PAUSE TestOIDC_AuthURL/normal_case
=== RUN   TestOIDC_AuthURL/missing_role
=== PAUSE TestOIDC_AuthURL/missing_role
=== RUN   TestOIDC_AuthURL/valid_redirect_uri
=== PAUSE TestOIDC_AuthURL/valid_redirect_uri
=== RUN   TestOIDC_AuthURL/invalid_redirect_uri
=== PAUSE TestOIDC_AuthURL/invalid_redirect_uri
=== CONT  TestOIDC_AuthURL/normal_case
=== CONT  TestOIDC_AuthURL/valid_redirect_uri
=== CONT  TestOIDC_AuthURL/invalid_redirect_uri
=== CONT  TestOIDC_AuthURL/missing_role
2020-10-26T14:22:00.355-0700 [WARN]  unauthorized redirect_uri: redirect_uri=http://bitc0in-4-less.cx
--- PASS: TestOIDC_AuthURL (0.02s)
    --- PASS: TestOIDC_AuthURL/invalid_redirect_uri (0.00s)
    --- PASS: TestOIDC_AuthURL/valid_redirect_uri (0.02s)
    --- PASS: TestOIDC_AuthURL/missing_role (0.02s)
    --- PASS: TestOIDC_AuthURL/normal_case (0.02s)
=== RUN   TestOIDC_AuthURL_namespace
=== RUN   TestOIDC_AuthURL_namespace/namespace_as_query_parameter
=== RUN   TestOIDC_AuthURL_namespace/namespace_as_query_parameter,_bad_allowed_redirect
2020-10-26T14:22:00.453-0700 [WARN]  unauthorized redirect_uri: redirect_uri=https://example.com?namespace=test
=== RUN   TestOIDC_AuthURL_namespace/namespace_in_state
=== RUN   TestOIDC_AuthURL_namespace/namespace_in_state,_bad_allowed_redirect
2020-10-26T14:22:00.523-0700 [WARN]  unauthorized redirect_uri: redirect_uri=https://example.com
=== RUN   TestOIDC_AuthURL_namespace/nested_namespace_in_state
=== RUN   TestOIDC_AuthURL_namespace/namespace_as_query_parameter,_no_namespaces
=== RUN   TestOIDC_AuthURL_namespace/namespace_in_state,_no_namespaces
--- PASS: TestOIDC_AuthURL_namespace (0.29s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_as_query_parameter (0.05s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_as_query_parameter,_bad_allowed_redirect (0.02s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_in_state (0.05s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_in_state,_bad_allowed_redirect (0.02s)
    --- PASS: TestOIDC_AuthURL_namespace/nested_namespace_in_state (0.05s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_as_query_parameter,_no_namespaces (0.05s)
    --- PASS: TestOIDC_AuthURL_namespace/namespace_in_state,_no_namespaces (0.05s)
=== RUN   TestOIDC_Callback
=== RUN   TestOIDC_Callback/successful_login
=== RUN   TestOIDC_Callback/failed_login_-_bad_nonce
=== RUN   TestOIDC_Callback/failed_login_-_bound_claim_mismatch
=== RUN   TestOIDC_Callback/missing_state
=== RUN   TestOIDC_Callback/unknown_state
=== RUN   TestOIDC_Callback/valid_state,_missing_code
=== RUN   TestOIDC_Callback/failed_code_exchange
=== RUN   TestOIDC_Callback/no_response_from_provider
=== RUN   TestOIDC_Callback/test_bad_address
=== RUN   TestOIDC_Callback/test_invalid_client_id
=== RUN   TestOIDC_Callback/client_nonce
--- PASS: TestOIDC_Callback (0.05s)
    --- PASS: TestOIDC_Callback/successful_login (0.01s)
    --- PASS: TestOIDC_Callback/failed_login_-_bad_nonce (0.00s)
    --- PASS: TestOIDC_Callback/failed_login_-_bound_claim_mismatch (0.00s)
    --- PASS: TestOIDC_Callback/missing_state (0.00s)
    --- PASS: TestOIDC_Callback/unknown_state (0.00s)
    --- PASS: TestOIDC_Callback/valid_state,_missing_code (0.00s)
    --- PASS: TestOIDC_Callback/failed_code_exchange (0.00s)
    --- PASS: TestOIDC_Callback/no_response_from_provider (0.00s)
    --- PASS: TestOIDC_Callback/test_bad_address (0.00s)
    --- PASS: TestOIDC_Callback/test_invalid_client_id (0.00s)
    --- PASS: TestOIDC_Callback/client_nonce (0.01s)
=== RUN   TestOIDC_ValidRedirect
--- PASS: TestOIDC_ValidRedirect (0.00s)
=== RUN   TestParseMount
--- PASS: TestParseMount (0.00s)
=== RUN   TestPath_Create
=== RUN   TestPath_Create/happy_path
=== RUN   TestPath_Create/no_user_claim
=== RUN   TestPath_Create/no_binding
=== RUN   TestPath_Create/has_bound_subject
=== RUN   TestPath_Create/has_audience
=== RUN   TestPath_Create/has_cidr
=== RUN   TestPath_Create/has_bound_claims
=== RUN   TestPath_Create/has_expiration,_not_before_custom_leeways
=== RUN   TestPath_Create/storing_zero_leeways
=== RUN   TestPath_Create/storing_negative_leeways
=== RUN   TestPath_Create/storing_an_invalid_bound_claim_type
=== RUN   TestPath_Create/role_with_invalid_glob_in_claim
=== RUN   TestPath_Create/role_with_invalid_glob_in_claim_array
--- PASS: TestPath_Create (0.00s)
    --- PASS: TestPath_Create/happy_path (0.00s)
    --- PASS: TestPath_Create/no_user_claim (0.00s)
    --- PASS: TestPath_Create/no_binding (0.00s)
    --- PASS: TestPath_Create/has_bound_subject (0.00s)
    --- PASS: TestPath_Create/has_audience (0.00s)
    --- PASS: TestPath_Create/has_cidr (0.00s)
    --- PASS: TestPath_Create/has_bound_claims (0.00s)
    --- PASS: TestPath_Create/has_expiration,_not_before_custom_leeways (0.00s)
    --- PASS: TestPath_Create/storing_zero_leeways (0.00s)
    --- PASS: TestPath_Create/storing_negative_leeways (0.00s)
    --- PASS: TestPath_Create/storing_an_invalid_bound_claim_type (0.00s)
    --- PASS: TestPath_Create/role_with_invalid_glob_in_claim (0.00s)
    --- PASS: TestPath_Create/role_with_invalid_glob_in_claim_array (0.00s)
=== RUN   TestPath_OIDCCreate
=== RUN   TestPath_OIDCCreate/both_explicit_and_default_role_type
=== RUN   TestPath_OIDCCreate/invalid_reserved_metadata_key_role
=== RUN   TestPath_OIDCCreate/invalid_duplicate_metadata_destination
=== RUN   TestPath_OIDCCreate/custom_expiration_leeway_and_not_before_leeway_values
--- PASS: TestPath_OIDCCreate (0.00s)
    --- PASS: TestPath_OIDCCreate/both_explicit_and_default_role_type (0.00s)
    --- PASS: TestPath_OIDCCreate/invalid_reserved_metadata_key_role (0.00s)
    --- PASS: TestPath_OIDCCreate/invalid_duplicate_metadata_destination (0.00s)
    --- PASS: TestPath_OIDCCreate/custom_expiration_leeway_and_not_before_leeway_values (0.00s)
=== RUN   TestPath_Read
--- PASS: TestPath_Read (0.00s)
=== RUN   TestPath_Delete
--- PASS: TestPath_Delete (0.00s)
=== RUN   TestLogin_fetchGroups
2020-10-26T14:22:00.728-0700 [DEBUG] found Azure Graph API endpoint for group membership: https://127.0.0.1:57319/getMemberObjects
2020-10-26T14:22:00.731-0700 [DEBUG] groups claim raw is [group1 group2]
--- PASS: TestLogin_fetchGroups (0.00s)
=== RUN   Test_getClaimSources
=== RUN   Test_getClaimSources/normal_case
=== RUN   Test_getClaimSources/no__claim_names
2020-10-26T14:22:00.731-0700 [WARN]  unable to locate /_claim_names/groups in claims: /_claim_names/groups at part 0: couldn't find key "_claim_names"
=== RUN   Test_getClaimSources/no__claim_sources
2020-10-26T14:22:00.731-0700 [WARN]  unable to locate /_claim_sources/src1/endpoint in claims: /_claim_sources/src1/endpoint at part 0: couldn't find key "_claim_sources"
--- PASS: Test_getClaimSources (0.00s)
    --- PASS: Test_getClaimSources/normal_case (0.00s)
    --- PASS: Test_getClaimSources/no__claim_names (0.00s)
    --- PASS: Test_getClaimSources/no__claim_sources (0.00s)
=== RUN   TestNewProviderConfig
=== RUN   TestNewProviderConfig/normal_case
=== RUN   TestNewProviderConfig/no_provider_config
=== RUN   TestNewProviderConfig/provider_field_not_present_in_provider_config
=== RUN   TestNewProviderConfig/unknown_provider
=== RUN   TestNewProviderConfig/provider_name_not_present_in_provider_config
=== RUN   TestNewProviderConfig/error_in_Initialize
--- PASS: TestNewProviderConfig (0.00s)
    --- PASS: TestNewProviderConfig/normal_case (0.00s)
    --- PASS: TestNewProviderConfig/no_provider_config (0.00s)
    --- PASS: TestNewProviderConfig/provider_field_not_present_in_provider_config (0.00s)
    --- PASS: TestNewProviderConfig/unknown_provider (0.00s)
    --- PASS: TestNewProviderConfig/provider_name_not_present_in_provider_config (0.00s)
    --- PASS: TestNewProviderConfig/error_in_Initialize (0.00s)
=== RUN   TestGSuiteProvider_FetchGroups
    provider_gsuite_test.go:27: skip: must set env var "GOOGLE_CREDENTIALS" to a valid service account key file path
--- SKIP: TestGSuiteProvider_FetchGroups (0.00s)
=== RUN   TestGSuiteProvider_FetchUserInfo
    provider_gsuite_test.go:27: skip: must set env var "GOOGLE_CREDENTIALS" to a valid service account key file path
--- SKIP: TestGSuiteProvider_FetchUserInfo (0.00s)
=== RUN   TestGSuiteProvider_search
=== RUN   TestGSuiteProvider_search/fetch_groups_for_user_that's_in_no_groups
=== RUN   TestGSuiteProvider_search/fetch_groups_for_group_that's_in_no_groups
=== RUN   TestGSuiteProvider_search/fetch_groups_for_user_with_default_recursion_max_depth_0
=== RUN   TestGSuiteProvider_search/fetch_groups_for_user_with_recursion_max_depth_1
=== RUN   TestGSuiteProvider_search/fetch_groups_for_user_with_recursion_max_depth_10
=== RUN   TestGSuiteProvider_search/fetch_groups_for_group_with_default_recursion_max_depth_0
=== RUN   TestGSuiteProvider_search/fetch_groups_for_group_with_recursion_max_depth_1
=== RUN   TestGSuiteProvider_search/fetch_groups_for_group_with_recursion_max_depth_10
--- PASS: TestGSuiteProvider_search (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_user_that's_in_no_groups (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_group_that's_in_no_groups (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_user_with_default_recursion_max_depth_0 (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_user_with_recursion_max_depth_1 (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_user_with_recursion_max_depth_10 (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_group_with_default_recursion_max_depth_0 (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_group_with_recursion_max_depth_1 (0.00s)
    --- PASS: TestGSuiteProvider_search/fetch_groups_for_group_with_recursion_max_depth_10 (0.00s)
=== RUN   TestGSuiteProvider_initialize
=== RUN   TestGSuiteProvider_initialize/invalid_config:_required_service_account_key_is_empty
=== RUN   TestGSuiteProvider_initialize/invalid_config:_required_admin_impersonate_email_is_empty
=== RUN   TestGSuiteProvider_initialize/invalid_config:_recurse_max_depth_negative_number
=== RUN   TestGSuiteProvider_initialize/valid_config:_all_options
=== RUN   TestGSuiteProvider_initialize/valid_config:_no_custom_schemas
=== RUN   TestGSuiteProvider_initialize/valid_config:_no_recurse_max_depth
=== RUN   TestGSuiteProvider_initialize/valid_config:_fetch_groups_and_user_info
--- PASS: TestGSuiteProvider_initialize (0.00s)
    --- PASS: TestGSuiteProvider_initialize/invalid_config:_required_service_account_key_is_empty (0.00s)
    --- PASS: TestGSuiteProvider_initialize/invalid_config:_required_admin_impersonate_email_is_empty (0.00s)
    --- PASS: TestGSuiteProvider_initialize/invalid_config:_recurse_max_depth_negative_number (0.00s)
    --- PASS: TestGSuiteProvider_initialize/valid_config:_all_options (0.00s)
    --- PASS: TestGSuiteProvider_initialize/valid_config:_no_custom_schemas (0.00s)
    --- PASS: TestGSuiteProvider_initialize/valid_config:_no_recurse_max_depth (0.00s)
    --- PASS: TestGSuiteProvider_initialize/valid_config:_fetch_groups_and_user_info (0.00s)
PASS
ok  	github.com/hashicorp/vault-plugin-auth-jwt	1.969s
?   	github.com/hashicorp/vault-plugin-auth-jwt/cmd/vault-plugin-auth-jwt	[no test files]
  • Backwards compatible

path_config.go Outdated
@@ -94,6 +94,11 @@ func pathConfig(b *jwtAuthBackend) *framework.Path {
},
},
},
"pass_namespace_in_state": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit you can probably drop "pass" and have it be namespace_in_state.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that's better. Changed in bbfa423.

return resp, nil
}
qParam := inputURI.Query()
namespace = qParam.Get("namespace")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we error here if it does contain a namespace (as opposed to ignoring/removing it)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in this block if namespace is a query parameter, it does need to be removed from the redirectURI, so it can be appended to state later on.

Though I did see that this was re-encoding the query parameters for redirectURI needlessly in the case where there are no namespaces to worry about. Updated in b021102.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for the explanation. Is the namespace always going to be passed as a query parameter regardless of NamespaceInState? How is the namespace determined if it's coming from a request header or request path?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as things stand today with the redirect_uri, I think the namespace is always passed as a query parameter, since that's how the UI sends it to this auth_url endpoint. (The cli login for OIDC doesn't need to set a namespace parameter since it just opens a local listener.)

I did a little testing with the UI, and I don't see any headers coming through in req.Headers in the auth_url endpoint handler. I think it would be possible to infer the namespace from the mountpoint, or add another field to the auth_url API payload. Maybe that would be a cleaner way to specify the namespace? I'm not sure what else that would gain us, unless there's another UI-like system we're trying to integrate with.

Checks whether there actually was a namespace query parameter before
removing it and re-encoding the remaining query parameters.
@tvoran tvoran requested a review from calvn October 22, 2020 22:28
@tvoran tvoran changed the title Adds OIDC pass_namespace_in_state option Adds OIDC namespace_in_state option Oct 26, 2020
@kalafut
Copy link
Contributor

kalafut commented Oct 27, 2020

Using state seems like the better option. Is there any reason users wouldn’t prefer this to be true, aside from backwards compatibility? If “no” then a default of false doesn’t seem right.

@calvn
Copy link
Contributor

calvn commented Oct 27, 2020

I think we landed on defaulting to false to give people the opportunity to enable this explicitly without breaking their setup right out of an update since they have to update their list of allowed callback URLs on the provider side as well. We can flip the default to true in a future release. @tvoran correct me if this assumption is wrong.

If we do want to enable this by default, we might want to rename it to disable_namespace_in_state and default to false.

@kalafut
Copy link
Contributor

kalafut commented Oct 27, 2020

I was think of something like:

  • add a version parameter so we can detect existing configs (1.6 will be upgrading from version 0 to 1 on load)
  • rename this option to “namespace_in_query” (default false)
  • upon config upgrade, detect “namespace=“ in redirect_uris and set the upgraded config’s “namespace_in_query” to true if present

I think this gives us the preferred default without breaking existing configs?

@tvoran
Copy link
Member Author

tvoran commented Oct 27, 2020

@calvn Yeah, your assumption matches my recollection.

@kalafut Namespace in state does seem more desirable, and a config version seems like it could make this a little more user friendly. Are there other plugins that follow this pattern? (Just curious if there's an example to follow.)

@kalafut
Copy link
Contributor

kalafut commented Oct 27, 2020

@tvoran There are quite a few examples of upgrades and versions in Vault, and a few in plugins I think. Simple vault example: https://github.com/hashicorp/vault/blob/86209a769a254dfaa0b21cf8b3412c1450b6609d/vault/expiration.go#L2016-L2018. Much more elaborate: https://github.com/hashicorp/vault/blob/0c9f8a377cf11f71fe0d6f5458f91706038762a8/builtin/credential/aws/path_role.go#L449

I was thinking about this more and searching for namespace= is probably too clever. Better would be just to say that existing roles will behave the way they always, full stop.

@calvn
Copy link
Contributor

calvn commented Oct 27, 2020

I think the concern lies partially on the out-of-band update that is required on the auth provider side to update the set of valid callback URLs. Since namespace_in_state is an entirely new field, I don't think we need to do the version checking dance if the default value is true (i.e. not the zero-value) if we do want to enable by default, as old configs will not have this field and default to false. But as mentioned before, this can be problematic if users have not updated things on the provider end before updating Vault (their logins might stop working all of the sudden).

@tvoran
Copy link
Member Author

tvoran commented Oct 27, 2020

I do like the idea of defaulting to namespace in state, since that encourages a simpler provider config. And you're right, @calvn, if we keep namespace_in_state but default it to true, then existing oidc config's will have it set to false, which would prevent breakage for existing configs.

If we want to go with Jim's idea of namespace_in_query and distinguish between new and old roles, then I think the versioning would need to be added to the role config, and likewise namespace_in_query would be an option on the role (instead of on the oidc config as namespace_in_state is now). Though if we're not going to be clever and detect namespace= in redirect_uri's, I'm not sure I see the benefit of this approach.

@kalafut
Copy link
Contributor

kalafut commented Oct 28, 2020

I agree that using namespace_in_state with a default of true should work too. My main goal is that people don’t have to continually set or think about this. It’s a very in-the-weeds parameter that is a bit unfortunate that we even have to expose.

Copy link
Contributor

@calvn calvn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small things, otherwise 👍

path_config.go Outdated
Type: framework.TypeBool,
Description: "Pass namespace in the OIDC state parameter instead of as a separate query parameter. With this setting, the allowed redirect URL(s) in Vault and on the provider side should not contain a namespace query parameter. This means only one redirect URL entry needs to be maintained on the provider side for all vault namespaces that will be authenticating against it. Defaults to true for new configs.",
DisplayAttrs: &framework.DisplayAttributes{
Name: "Namespace in OIDC state",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep the value in DisplayAttrs for UI purposes? I am not sure if Default and DisplayAttrs.Value is required to match.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'll add the DisplayAttrs value back in. Added in 58a9841.

From my brief testing without the DisplayAttrs value, it shows up on the config edit page as unchecked. And if the user doesn't click on the field, it isn't sent when the config is submitted, which ends up defaulting to true on the backend. But it looks odd to submit a config with that value unchecked, only to find that the backend defaulted to having it checked.

path_config.go Outdated
@@ -189,6 +197,22 @@ func (b *jwtAuthBackend) pathConfigWrite(ctx context.Context, req *logical.Reque
ProviderConfig: d.Get("provider_config").(map[string]interface{}),
}

// Check if the config already exists, to determine if this is a create or
// an update
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to add a note on why we're doing this vs having an existence check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding something in 58a9841.

@tvoran tvoran merged commit 9705f34 into master Oct 29, 2020
@tvoran tvoran deleted the VAULT-570/pass-namespace-in-state branch October 29, 2020 05:15
tvoran added a commit that referenced this pull request Oct 29, 2020
namespace_in_state defaults to true only on new config write
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants