vault icon indicating copy to clipboard operation
vault copied to clipboard

Ability to tolower() in ACL templating OR Ignore case with Okta auth method

Open AnthonyHerman opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe. We currently have a workflow where terraform will retrieve group membership from Azure AD and create custom user roles for a secrets backend in Vault. So the roles end up looking like database/static-roles/secret_role_mysamaccountname.

Users will then use the Okta auth method and using ACL Policy Path Templating will get access to their role. The policy for ex:

resource "vault_policy" "mypolicy" {
  name   = "mypolicy"
  policy = <<EOT
path "database/static-creds/secret_role_{{identity.entity.aliases.auth_okta_eexxxxxx.name}}" {
  capabilities = ["read", "list"]
}
EOT
}

The problem here is that Vault policies + routes are case sensitive whereas entities are sticky. If a user logs in the first time with an uppercase username the entity name is uppercase so the policy gives access to the path database/static-creds/secret_role_UPPERCASENAME. In this scenario the user cannot access their role and logging out and back in with a lowercase username does not work because the internal entity application logic is case insensitive so the existing entity will continue to be applied and silently haunt the user.

This requires us to manually intervene and delete the created entity and have the user log back in with a lowercase username which is not ideal.

Solution Either one of:

  1. An ability to tolower() in the policy templating so irregardless of entity casing the desired path will be allowed.
  2. An ability to toggle created entity case somehow at the Okta auth method.
  3. Generally ignore entity case.
  4. Others I may not be aware of.

AnthonyHerman avatar Feb 04 '22 16:02 AnthonyHerman

Another option might be to use the login returned by Okta as a "canonical username" so that Vault uses whatever case Okta uses when it creates the vault entity alias.

When the okta auth backend makes the authn request here (or once MFA is complete if not bypassed): https://github.com/hashicorp/vault/blob/0b12cdcfd17278d7cca25ec37ffacd96b8d5c6c7/builtin/credential/okta/backend.go#L121-L130

We can use this to get that login:

profile := *result.Embedded.User.Profile // map[string]interface{}
canonicalUsername := profile["login"].(string)

Okta docs links:

  • The embedded user object: https://developer.okta.com/docs/reference/api/authn/#user-object
  • The embedded user profile object: https://developer.okta.com/docs/reference/api/authn/#user-profile-object

One major benefit of this approach is that users can login with any of the variants that Okta accepts, including leaving off the email domain: [email protected], [email protected], [email protected], or just some.user. Merely lowercasing the user-provided username would still create duplicate entities for the shortand some.user.

One shortcoming with this approach is that when the Vault admin (or terraform in your case?) defines users in the okta auth backend, they must use the same case that Okta considers canonical.

But maybe, we could get the best of both approaches by lowercasing the login string:

profile := *result.Embedded.User.Profile // map[string]interface{}
canonicalUsername := strings.ToLower(profile["login"].(string))

On upgrade, we would need to migrate any existing okta auth method users (and their entity aliases) to the lowercase variant.

PS: I don't have time to actually test this right now, but I hacked together a possible way to make the username case-insensitive and use the login as canonical username. https://github.com/hashicorp/vault/compare/main...cognifloyd:vault:okta-case-insensitive Does that look like it would resolve this issue?

cognifloyd avatar Dec 16 '23 08:12 cognifloyd

#11063, would be a more general approach, what would also enable tolower() functionallity on policy side

peter-fe avatar Mar 05 '24 12:03 peter-fe