Introduction
Some use cases require permissions to be assigned using nested Groups in Vault, this article explains how this can be accomplished. The example is based on KVv2 secrets, however any valid path within Vault can be used instead
Scenario
This scenario consists out of two hierarchical Vault namespaces, for example root and us-east-org, a Vault Authentication method which has been enabled within the Vault root namespace and the usage of external groups. For this example the Vault LDAP Authentication method is used, and group memberships are being managed from an external LDAP directory. A reason for implementing such scenario would be that despite the fact that the Authentication method and Vault ACL policy reside in the Vault namespace, there should be an option to add / manage additional permissions within the Vault namespace.
When the Vault namespace are not hierarchical, the /sys/config/group-policy-application endpoint can be used to configure the mode of policy application for identity groups in Vault. This setting dictates the behavior across all groups in all namespaces in Vault.
Vault allows you to add entities and groups from any namespace into an identity group. However, historically, any policies attached to that group would only apply when the Vault token authorizing a request was created in the same namespace as that group, or a descendent namespace. This endpoint allows relaxing that restriction: when the mode is set to the default, within_namespace_hierarchy, the historical behaviour is maintained, but when set to any, group policies apply to all members of a group, regardless of what namespace the request token came from.
Example Steps
Listing namespaces in the root namespace:
vault namespace listKeys ---- us-east-org/
Authentication Methods in the root namespace:
vault auth listPath Type Accessor Description Version ---- ---- -------- ----------- ------- ldap/ ldap auth_ldap_db9ddb53 n/a n/a token/ token auth_token_b7bd7c53 token based credentials n/a
Authentication using the LDAP method which resides in the root namespace:
vault login -method=ldap username=gerard Password (will be hidden):
Token lookup in the root namespace:
vault token lookup hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********MAQKey Value --- ----- accessor xStNRQX00Cdsteaho12CQJo7 creation_time 1762245109 creation_ttl 768h display_name ldap-gerard entity_id 135ad3e7-37ca-950e-1766-ed7ca09b0416 expire_time 2025-12-06T08:31:49.697782443Z explicit_max_ttl 0s external_namespace_policies map[] id hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********MAQ identity_policies [sales-read-only] issue_time 2025-11-04T08:31:49.697787621Z meta map[username:gerard] num_uses 0 orphan true path auth/ldap/login/gerard policies [default] renewable true type service ttl 766h55m32s
Groups can be listed using the Identity secrets engine (API)
The relevant entity which resides in the root namespace (only):
vault read -format=json /identity/entity/id/135ad3e7-37ca-950e-1766-ed7ca09b0416{
"request_id": "24e9bc99-0ad8-0065-0c82-5d29113e57ce",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": {
"aliases": [
{
"canonical_id": "135ad3e7-37ca-950e-1766-ed7ca09b0416",
"creation_time": "2025-06-18T16:21:26.385774479Z",
"custom_metadata": null,
"id": "cadfcc4a-b6b2-a2f5-75d0-09fe22b13ff4",
"last_update_time": "2025-11-03T14:53:24.9199643Z",
"local": false,
"merged_from_canonical_ids": null,
"metadata": {
"effectiveUsername": "Gerard",
"name": "gerard",
"rawUsername": "gerard"
},
"mount_accessor": "auth_ldap_db9ddb53",
"mount_path": "auth/ldap/",
"mount_type": "ldap",
"name": "Gerard"
}
],
"creation_time": "2025-06-18T16:21:26.385766796Z",
"direct_group_ids": [
"231c0d47-e313-93e7-5751-afdecc622708"
],
"disabled": false,
"group_ids": [
"231c0d47-e313-93e7-5751-afdecc622708",
"5ae3f6c4-f98c-1b19-379b-b5e32481046c"
],
"id": "135ad3e7-37ca-950e-1766-ed7ca09b0416",
"inherited_group_ids": [
"5ae3f6c4-f98c-1b19-379b-b5e32481046c"
],
"last_update_time": "2025-06-18T16:21:26.385766796Z",
"merged_entity_ids": null,
"metadata": null,
"mfa_secrets": {},
"name": "entity_addb206d",
"namespace_id": "root",
"policies": []
},
"warnings": null,
"mount_type": "identity"
}The following is of relevance:
direct_group_ids: 231c0d47-e313-93e7-5751-afdecc622708inherited_group_ids: 5ae3f6c4-f98c-1b19-379b-b5e32481046c
Groups can be listed using the Identity secrets engine (API), direct_group_ids represent direct group memberships in or outside the Vault namespace in which the entity resides. inherited_group_ids are nested groups which can reside in or outside the same Vault namespace as the entity.
External group which resides in the root namespace:
vault read -format=json identity/group/id/231c0d47-e313-93e7-5751-afdecc622708{
"request_id": "9051a04d-5619-ec70-4289-a0813eb27747",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": {
"alias": {
"canonical_id": "231c0d47-e313-93e7-5751-afdecc622708",
"creation_time": "2025-05-30T14:59:35.418597979Z",
"id": "d59d60ee-a660-a7a1-f5a9-bf3ed1634424",
"last_update_time": "2025-11-04T09:05:10.763077607Z",
"merged_from_canonical_ids": null,
"metadata": null,
"mount_accessor": "auth_ldap_db9ddb53",
"mount_path": "auth/ldap/",
"mount_type": "ldap",
"name": "Group5"
},
"creation_time": "2025-05-30T14:59:25.633393475Z",
"id": "231c0d47-e313-93e7-5751-afdecc622708",
"last_update_time": "2025-11-04T09:05:10.763071354Z",
"member_entity_ids": [
"135ad3e7-37ca-950e-1766-ed7ca09b0416"
],
"member_group_ids": null,
"metadata": null,
"modify_index": 20,
"name": "admin-group",
"namespace_id": "root",
"parent_group_ids": [
"1c7a060e-455e-f27f-7b57-b2cd02b18d32"
],
"policies": [
"sales-read-only"
],
"type": "external"
},
"warnings": null,
"mount_type": "identity"
}
Please note that this group is an external group called admin-group which is mapped to an external group called group5 which resides in the ldap directory. Please observe the assigned policy called sales-read-only.
The relevant ACL policy in the root namespace:
vault policy read sales-read-only
path "us-east-org/kv-marketing/data/sales" {
capabilities = ["read"]
}
In the namespace us-east-org the following has been created:
- KVv2 Secrets Engine
- ACL Policy
- Identity Group
The KVv2 Secrets Engine contains 2 keys:
VAULT_NAMESPACE=us-east-org vault kv list kv-marketingKeys
----
campaign
sales
The relevant ACL policy in the us-east-org namespace:
VAULT_NAMESPACE=us-east-org vault policy read marketing-read-onlypath "kv-marketing/data/campaign" {
capabilities = ["read"]
}
The internal group in the us-east-org namespace:
VAULT_NAMESPACE=us-east-org vault read -format=json identity/group/id/5ae3f6c4-f98c-1b19-379b-b5e32481046c{
"request_id": "d71b0450-5fbc-2b72-75ef-34a7fb518645",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": {
"alias": {},
"creation_time": "2025-11-04T07:30:55.073590355Z",
"id": "5ae3f6c4-f98c-1b19-379b-b5e32481046c",
"last_update_time": "2025-11-04T09:56:07.411561042Z",
"member_entity_ids": null,
"member_group_ids": [
"231c0d47-e313-93e7-5751-afdecc622708"
],
"metadata": {},
"modify_index": 11,
"name": "campaign-admin",
"namespace_id": "5S9nM",
"parent_group_ids": null,
"policies": [
"marketing-read-only"
],
"type": "internal"
},
"warnings": null,
"mount_type": "ns_identity"
}
Please note: "member_group_ids": ["231c0d47-e313-93e7-5751-afdecc622708"]231c0d47-e313-93e7-5751-afdecc622708 is the id of the "admin-group" which resides in the root namespace.
Reading the campaign secret in the us-east-org namespace, please note that that the ACL policy which resides in the us-east-orgnamespace is used:
VAULT_NAMESPACE=us-east-org VAULT_TOKEN=hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********MAQ vault kv get kv-marketing/campaign======= Secret Path ======= kv-marketing/data/campaign ======= Metadata ======= Key Value --- ----- created_time 2025-11-04T07:30:38.666229001Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ======= Data ======= Key Value --- ----- end_date March 31, 2023 prize Certification voucher quantity 100 start_date March 1, 2023
Reading the sales secret in the us-east-org namespace, please note that that the ACL policy which resides in the root namespace is used:
VAULT_NAMESPACE=us-east-org VAULT_TOKEN=hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********MAQ vault kv get kv-marketing/sales===== Secret Path ===== kv-marketing/data/sales ======= Metadata ======= Key Value --- ----- created_time 2025-11-04T09:04:35.903201401Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ======= Data ======= Key Value --- ----- end_date March 31, 2023 prize Certification voucher quantity 100 start_date March 1, 2023
After removing group member id for the admin-group which resides in the root namespace from the group campaign-admin which resides in the us-east-org namespace :
VAULT_NAMESPACE=us-east-org vault read -format=json identity/group/id/5ae3f6c4-f98c-1b19-379b-b5e32481046c{
"request_id": "fabce11d-5555-4ddd-761c-726517ae0f80",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": {
"alias": {},
"creation_time": "2025-11-04T07:30:55.073590355Z",
"id": "5ae3f6c4-f98c-1b19-379b-b5e32481046c",
"last_update_time": "2025-11-04T10:25:50.745974076Z",
"member_entity_ids": null,
"member_group_ids": null,
"metadata": {},
"modify_index": 12,
"name": "campaign-admin",
"namespace_id": "5S9nM",
"parent_group_ids": null,
"policies": [
"marketing-read-only"
],
"type": "internal"
},
"warnings": null,
"mount_type": "ns_identity"
}
Reading the sales secret in the us-east-org namespace, which fails because the nested group member id for the admin-group which resides in the root namespace has been removed from the group campaign-admin which resides in the us-east-org namespace:
VAULT_NAMESPACE=us-east-org VAULT_TOKEN=hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********MAQ vault kv get kv-marketing/campaignError reading kv-marketing/data/campaign: Error making API request. Namespace: us-east-org/ URL: GET http://127.0.0.1:8200/v1/kv-marketing/data/campaign Code: 403. Errors: * 1 error occurred: * permission denied
Reading the campaign secret in the us-east-org namespace, please note that that the ACL policy which resides in the us-east-org namespace is used:
VAULT_NAMESPACE=us-east-org VAULT_TOKEN=hvs.CAESIFPGlnUcOa2_-0Ssv719YGvK_cereHO4D5DB6DFQe-SUGiMKHGh2cy5GM3RCbU5aaEpQVDlQalE3U095UFF********yMAQ vault kv get kv-marketing/sales===== Secret Path ===== kv-marketing/data/sales ======= Metadata ======= Key Value --- ----- created_time 2025-11-04T09:04:35.903201401Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ======= Data ======= Key Value --- ----- end_date March 31, 2023 prize Certification voucher quantity 100 start_date March 1, 2023
Additional Information
Vault Documentation Implement identity entities and group
Vault API Documentation: /sys/config/group-policy-application
-
Vault API documentation Identity secrets engine (API)