HashiCorp Vault — Identity Engine
Vault’s Identity engine provides a unified identity across all auth methods — so the same person authenticating via LDAP, OIDC, or GitHub is recognized as one entity.
Why Identity?
Without Identity:
Alice logs in via LDAP → gets policies A, B
Alice logs in via OIDC → gets policies C, D
Vault sees these as different identities
With Identity:
Alice logs in via LDAP → entity "alice" → policies A, B, C, D
Alice logs in via OIDC → same entity "alice" → policies A, B, C, D
Vault recognizes Alice across auth methods
Core Concepts
| Concept | Description |
|---|---|
| Entity | Represents a single user or application |
| Alias | Links an entity to an auth method account |
| Group | Collection of entities |
| Internal Group | Manually managed group (add entities directly) |
| External Group | Synced from external source (LDAP, OIDC groups) |
Entity Management
# Create an entity
vault write identity/entity name="alice" \
policies="global-reader" \
metadata=team="engineering" \
metadata=department="backend"
# Read entity
vault read identity/entity/name/alice
# List entities
vault list identity/entity/name
# Update entity
vault write identity/entity/name/alice \
policies="global-reader,dev-access"
Create Aliases
Link an entity to auth method accounts:
# Get the auth method accessor
LDAP_ACCESSOR=$(vault auth list -format=json | jq -r '."ldap/".accessor')
OIDC_ACCESSOR=$(vault auth list -format=json | jq -r '."oidc/".accessor')
# Get entity ID
ENTITY_ID=$(vault read -field=id identity/entity/name/alice)
# Create LDAP alias
vault write identity/entity-alias \
name="alice@example.com" \
canonical_id="$ENTITY_ID" \
mount_accessor="$LDAP_ACCESSOR"
# Create OIDC alias
vault write identity/entity-alias \
name="alice@example.com" \
canonical_id="$ENTITY_ID" \
mount_accessor="$OIDC_ACCESSOR"
Now Alice gets the same entity (and policies) regardless of which auth method she uses.
Groups
Internal Groups
# Create an internal group
vault write identity/group name="engineering" \
policies="engineering-secrets" \
member_entity_ids="$ALICE_ID,$BOB_ID,$CAROL_ID" \
metadata=team="engineering"
# Add members later
vault write identity/group/name/engineering \
member_entity_ids="$ALICE_ID,$BOB_ID,$CAROL_ID,$DAVE_ID"
External Groups
# Create external group (synced with LDAP/OIDC groups)
vault write identity/group name="ldap-engineering" \
type="external" \
policies="engineering-secrets"
# Create group alias (maps external group name)
GROUP_ID=$(vault read -field=id identity/group/name/ldap-engineering)
vault write identity/group-alias \
name="cn=engineering,ou=groups,dc=example,dc=com" \
mount_accessor="$LDAP_ACCESSOR" \
canonical_id="$GROUP_ID"
When a user logs in via LDAP and belongs to the engineering LDAP group, they automatically get the engineering-secrets policy.
Identity in Policies
# Templated policy using identity
path "secret/data/{{identity.entity.name}}/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# Group-based path
path "secret/data/teams/{{identity.groups.names.engineering.name}}/*" {
capabilities = ["read", "list"]
}
Identity Tokens (OIDC Provider)
Vault can act as an OIDC provider, issuing identity tokens:
# Create an OIDC key
vault write identity/oidc/key/my-key \
rotation_period=24h \
verification_ttl=24h
# Create an OIDC role
vault write identity/oidc/role/my-role \
key="my-key" \
ttl=1h
# Read a user's OIDC token
vault read identity/oidc/token/my-role
Quick Reference
| Command | Description |
|---|---|
vault write identity/entity name=NAME |
Create entity |
vault write identity/entity-alias ... |
Create alias |
vault write identity/group name=NAME |
Create group |
vault write identity/group-alias ... |
Map external group |
vault list identity/entity/name |
List entities |
vault read identity/entity/name/NAME |
Read entity |
Next: Transform Engine