Search code examples
hashicorp-vaultvault

Policy to allow user to view secrets at 1 sub-tree but not others in hashicorp vault


I have a secrets engine in vault called "root" with 3 subtrees of "apps", "ops" & "test". I'm trying to create an ACL policy that will allow specific users to only see a certain subtree. I have a sample policy set for "apps" users to only see their subtree:

path = "root/*" {
  capabilities = ["list"]
}
path = "root/data/apps*" {
  capabilities = ["list", "read"]
}
path = "root/metadata/apps*" {
  capabilities = ["list", "read"]
}
path = "root/data/ops*" {
  capabilities = []
}
path = "root/metadata/ops*" {
  capabilities = []
}
path = "root/data/test*" {
  capabilities = []
}
path = "root/metadata/test*" {
  capabilities = []
}

As a note, root is a KV2 engine and we are currently running vault version 1.12.2

The above works as intended, as I can view/read all secrets in the "apps" subtree - my only concern is that I can still view secrets in the "ops" & "test" subtrees. Based on the policy above, I get the following window below for the other 2 subtrees:
vault_view_secret

I know this is a result of the first item in the policy that allows view all for everything under root, however this window still gives the pretext of being able to see secrets in the other subtrees (if you know the path) though you still get an access denied, even if the submitted path is correct. I don't remember seeing this window in older versions of vault (I think i did the same test in 1.8.3) and am wondering if this is something new that we have to deal with it or if there is a proper policy setting that will not access to the other subtrees.

FYI - if i remove the "list" setting at the root, then even when navigating to the "apps" subtree it gives me the same window. If the explicit entries for the other subtrees are removed, then I can navigate those trees but get access denied to read them (still not desired)...

Long story short, just want to know if I can give access to the "apps" subtree and essentially hide the other 2 subtrees. Thanks in advance for the help.


Solution

  • Yes you can accomplish this with explicit denies, and by removing the list permission for all paths at root:

    path = "root/data/apps*" {
      capabilities = ["list", "read"]
    }
    path = "root/metadata/apps*" {
      capabilities = ["list", "read"]
    }
    path = "root/data/ops*" {
      capabilities = ["deny"]
    }
    path = "root/metadata/ops*" {
      capabilities = ["deny"]
    }
    path = "root/data/test*" {
      capabilities = ["deny"]
    }
    path = "root/metadata/test*" {
      capabilities = ["deny"]
    }
    

    You can additionally use the wildcard operator as the list element in the policy:

    path = "root/data/apps*" {
      capabilities = ["list", "read"]
    }
    path = "root/metadata/apps*" {
      capabilities = ["list", "read"]
    }
    path = "root/*/ops*" {
      capabilities = ["deny"]
    }
    path = "root/*/test*" {
      capabilities = ["deny"]
    }
    

    Default permission is also deny, and therefore they can be omitted entirely to the same effect:

    path = "root/data/apps*" {
      capabilities = ["list", "read"]
    }
    path = "root/metadata/apps*" {
      capabilities = ["list", "read"]
    }
    

    As the primary concern here is viewing secret paths available from the root mount path in the Vault UI, this will remove that capability in the UI while still preserving the desired capabilities.