Cross-Namespace Secret Sharing#
Cross-namespace secret sharing allows teams to securely share credentials, API keys, and certificates across different Vault namespaces while maintaining security isolation. This allows controlled collaboration between teams without compromising the principle of least privilege.
Key Principles#
- Sharing Team: Controls everything (policies, sharing groups, access permissions)
- Consuming Team: Only provides identities (external groups, internal groups, AppRoles)
- Teams set their namespace context once and can then access both local and cross-namespace secrets
- Teams access shared secrets using cross-namespace paths for API calls (e.g.,
devex/secrets/databases/shared/analytics
) - For CLI commands, you must use the
-namespace
flag to access the sharing team's namespace (e.g.,vault kv get -namespace=admin/devex secrets/path
)
Important Concepts#
Identity Types:
- External Groups: Found in admin namespace, represent team members via SAML
- Internal Groups: Created in team namespaces, used for organizing machine or human access
- Entities: Individual identities (AppRoles, users) that can be grouped
Team Roles:
- Sharing Team: Creates policies and internal groups to grant access
- Consuming Team: Creates approles and can request access by sharing entity or group IDs
Team Setup#
Most of these steps can also be performed via the Vault UI. The instructions below assume you have the vault
CLI installed and appropriate namespace access.
Note
This setup follows the official HashiCorp pattern where only the sharing team controls access policies. The consuming team provides identities (groups/entities) but cannot write cross-namespace policies.
Step 1: Both teams need to identify the consuming team's external group ID first.#
# Login to admin namespace
vault login -method=saml --namespace=admin
export VAULT_NAMESPACE="admin"
# List all external groups
vault list identity/group/name
# Get the consuming team's external group ID
vault read identity/group/name/secm_admin_users_external
_admin_users_external
groups, NOT _general_users_external
groups!
Step 2: Sharing Team Setup (Example: DEVEX sharing with SECM)#
export VAULT_NAMESPACE="admin/devex"
2.1 Create Sharing Policy#
Define what the consuming team can access:
vault policy write devex-sharing-policy - <<EOF
# Shared database credentials
path "secrets/databases/shared/*" {
capabilities = ["read", "list"]
}
EOF
2.2 Create Sharing Group#
vault write identity/group \
name="shared-with-secm" \
type="internal" \
policies="devex-sharing-policy"
2.3 Add Consuming Team's External Group#
Replace vault write identity/group/name/shared-with-secm \
member_group_ids="<secm_external_group_id>"
2.4 Create Shared Secrets#
vault kv put secrets/databases/shared/analytics \
username="analytics_user" \
password="secure_password_123"
Step 3: Consuming Team Access (Example: SECM consuming from DEVEX)#
export VAULT_NAMESPACE="admin/secm"
3.1 Test Human Access#
SECM team members can now access the shared secret:
vault kv get -namespace=admin/devex secrets/databases/shared/analytics
3.2 For Machine Access: Create Internal Group (Recommended)#
For applications that need access to shared secrets, create an internal group to manage machine identities:
# Create internal group for managing machine access
vault write identity/group \
name="secm-machines" \
type="internal"
3.3 Create AppRoles for Applications#
# Create AppRole for application
vault write auth/approle/role/analytics-app \
token_policies="default" \
secret_id_ttl="365d" \
# Get AppRole credentials
vault read auth/approle/role/analytics-app/role-id
vault write -f auth/approle/role/analytics-app/secret-id
3.4 Add AppRole Entity to Internal Group#
# First, authenticate the AppRole to create an entity
vault write auth/approle/login \
role_id="<role-id>" \
secret_id="<secret-id>"
# Find the AppRole entity ID
vault list identity/entity/id #see for the latest id(generally last one in the list)
# Verify you found the right entity by checking aliases
vault read identity/entity/id/<entity-id-here>
# Look for your AppRole name (e.g., "analytics-app") in the aliases section
# Add entity to internal group (replace with actual entity ID)
vault write identity/group/name/secm-machines \
member_entity_ids="<entity-id-here>"
3.5 Request Machine Access from Sharing Team#
Provide your internal group ID to the sharing team:
# Get your internal group ID
vault read identity/group/name/secm-machines
export VAULT_NAMESPACE="admin/devex"
# DEVEX team adds SECM's internal group
vault write identity/group/name/shared-with-secm \
member_group_ids="<secm_external_group_id>,<secm_machines_group_id>"
Common Use Cases#
1. Database Access Sharing#
DEVEX team shares database credentials with SECM team:
# DEVEX team creates and shares
vault kv put -namespace=admin/devex secrets/databases/shared/student-data \
username="student_reader" \
password="pass"
# SECM team accesses
vault kv get -namespace=admin/devex secrets/databases/shared/student-data