HashiCorp Vault — Identity Engine

2 minute read

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