HashiCorp Vault - Deny login access to Root namespace for non-Admin users

As part of our Azure AD app registration for Vault single sign-on using OIDC, we’ve created two Azure AD groups:

VaultAdmins : This group will have Admin access across all namespaces, including the Root
VaultUsers : This group will only have standard access on all designated child namespace(s).

We also have some dedicated Vault policies setup to define capabilities for the above two external groups. I must also mention that both groups are mapped to two internal (Vault) groups.

The requirement now is to completely deny OIDC login access to the Root namespace for all members of the non-Admin group (“VaultUsers”). The non-Admin group should only have the capability to log into the child namespace(s) to which they’ve been designated via group membership policy.

I have tried various things, including setting up the below single rule for non-Admin users on the Root namespace, but I’m still unable to achieve the desired result. Any suggestions? Do I need to add an extra rule to deny access to the Root namespace and if so, how?

rule  {
        path         = "sys/auth/oidc/*"
        capabilities = ["deny"]
        description  = "deny all non-Admin OIDC access on Root namespace"
      }

Not an answer – but hopefully this will save you some researched.

I have not found a way of preventing authentication from either LDAP or OIDC from non-grouped users. They can always authenticate but obviously don’t get any policies applied and therefore only get a blank screen after authenticating but I haven’t found a way of actually denying the auth – with or without namespaces.

Thanks @aram . That’s really good to know.
I thought it was perhaps just a case of me not being too familiar with how Vault policies/security work, but at least now I know mine’s not a unique scenario.

I should have mentioned, if you’re on enterprise, a simple login does not count towards your entity usage. An entity must do more than auth to count towards your limit. That was really what I was worried about and our account team checked and confirmed this is builtin.

Thanks for the excellent feedback @aram. We are indeed running on an enterprise license and somehow, there’s been the concern that if user has the capability to log into Root and also a child namespace, they will count as multiple licence counts.

Yes, if the user logs in to root and child namespaces, it will count as multiple clients against your licensed count - and each additional child namespace they log in to will count again!

Please note that whilst merely authenticating via an API or CLI might not count, if you’re logging in using the web UI, the requests made to show data in the UI immediately after logging in will count as the entity having done something.

Although it is not directly possible to require a certain group membership to complete an OIDC login, it is possible to require a certain claim in the JWT … and groups are communicated as claims … so ultimately you can.

You would want to set the bound_claims setting on the OIDC auth method role being used to {"groups": ["VaultAdmins"]} (assuming your groups claim is named groups that is).

We have had multiple talks with Hashicorp on this. The solution that we settled on was to auth to root then switch to your namespace to get your “namespace+group” policy. We verified the license use (or non-use) with them so we’re comfortable with this.

Hashicorp does improve the detection and reporting of entity licenses with each release so upgrade if you can to improve the count – as they are an expesive license. I saw at least 2 or 3 updates to the entity/license detection/reporting in 1.11 beta.

I, too, am at a company where we are rolling back from auth methods in child namespaces, in favour of moving all authentication to the root namespace.

Users authenticating to namespaces is really only suitable when you have completely separate business units that do not interact at all, and every user is associated with exactly 1 business unit.

If you have an environment where one business unit offers services to another - say a database operations team providing services to an application team - and both of them are logging into their own namespaces, then the database team will be unable to use Vault to provide login secrets to the application team.

Thanks for the suggestion @maxb.

Just to clarify, I’m provisioning my Vault SSO solution using Terraform. I have therefore tried to implement the change suggested (and other variations too), but can’t seem to achieve any success as the Vault UI throws the following error when trying to login as a member of the Azure AD VaultAdmins group:

image

Below is a snippet of my Terraform configuration. Is there something I’m not doing right?

    resource "vault_jwt_auth_backend" "root" {
      description = "OIDC single sign-on for the root namespace."
      oidc_discovery_url      = "https://login.microsoftonline.com/${var.tenant_id}/v2.0" 
      path                    = "oidc"
      type                    = "oidc"    
      oidc_client_id          = var.client_id
      oidc_client_secret      = var.client_secret
      default_role            = "azure"

      tune {
         max_lease_ttl      = "90000s"
         listing_visibility = "unauth"  
        }
        provider_config = {
          provider = "azure"
          fetch_groups = true
          fetch_user_info = true
          groups_recurse_max_depth = 1
        }
}  
  
    resource "vault_jwt_auth_backend_role" "azure" {
      role_name             = var.azure_role_name 
      backend               = vault_jwt_auth_backend.root.path
      user_claim            = "email"
      groups_claim          = "groups" 
      
      bound_claims          = { "groups": "VaultAdmins" }
      
      role_type             = "oidc"
      oidc_scopes           = var.oidc_scopes 
      allowed_redirect_uris = var.allowed_redirect_uris
      verbose_oidc_logging  = "true" 
  }

The config looks fine to me, but I’m unfamiliar with Azure as an OIDC provider.

In particular,

kind of suggests it’s doing something special and Azure-specific with groups.

Can you post the payload of an example JWT from Azure?

You can leave out the signature (third dot-separated part) to make it unusable for authentication, whilst still sharing the data needed.

@maxb could you kindly provide some guidance on how I can obtain the payload please? I tried logging into my Vault instance in the UI via oidc and at the same time, had my browser developer tools panel open to scoop any payload but not getting much joy.

The OIDC authorization code flow avoids JWT credentials ever touching the browser, for security reasons.

Turn on the verbose_oidc_logging feature as mentioned in the other topic you posted in (Where can I find the debug logs for OIDC? - #7 by Reggie126) and read it in the Vault logs.