In this episode we'll cover the Identity Engine: how Vault unifies the same identity from various auth methods through Entities and Aliases, and inherits policies through Groups. You'll understand the multi-auth pattern and organization-scale access management.

After covering authentication methods in episode 10 — token, userpass, AppRole, and OIDC — you may have noticed one subtle yet crucial problem: every time a user logs in through a different auth method, Vault treats them as a separate identity. The same user logging in via userpass in the morning and via OIDC in the afternoon gets two different tokens, two different policy sets, and two unconnected audit trails. In real organizations with Okta, GitHub, and LDAP all at once, this becomes a governance nightmare.
In this episode we'll cover the Identity Engine — Vault's answer to that problem. The Identity Engine introduces three concepts: Entity (the actual human/machine identity), Alias (how that identity appears in each auth method), and Group (collections of entities for policy inheritance). By understanding these three, you can design a unified access system: one person, many login methods, one set of access rights, and one audit trail.
Let's break them down one by one.
Imagine this scenario in your company:
budi@company.com → gets the dev-kv policy.budi with different policies.The result: policies aren't unified, audit logs can't fully answer "what did Budi do today?", and if Budi is fired, admins must revoke access in many places. The Identity Engine unifies all of this.
The core concepts:
| Concept | Analogy | Definition in Vault |
|---|---|---|
| Entity | The actual person or machine | A single identity that stores policies (entity policies) |
| Alias | Different ID cards for the same person | A mapping between auth method + user ID → one entity |
| Group | Team / department | A collection of entities that inherits policies to its members |
+--------------- Entity: Budi Dwi (ID: 1a2b3c) ---------------+
| entity policies: [dev-kv] |
| |
| +-------- Alias 1 --------+ +-------- Alias 2 ---------+ |
| | auth: oidc | | auth: userpass | |
| | name: budi@company.com | | name: budi | |
+---+-------------------------+---+--------------------------+Now, whether Budi logs in from Okta or userpass, Vault recognizes them as the same Entity. Policies attached to the entity apply to both, and the audit log records both under the same identity.
Usually, entities are created automatically by Vault the first time someone logs in through a particular auth method. But for full control, we can also create them manually. Let's look at both.
1. First login — Vault creates the entity + alias automatically
vault login -method=userpass username=budi password=S3cur3Pa55word!vault identity lookupKey Value
--- -----
aliases [map[canonical_id:71a7... custom_metadata:<nil> creation_time:... id:... last_update_time:... merged_from_canonical_ids:<nil> metadata:<nil> mount_accessor:auth_userpass_8f2... mount_path:auth/userpass/ mount_type:userpass name:budi]]
canonical_id 71a7e5b1-...
creation_time 2026-08-02T10:00:00.000Z
id 71a7e5b1-...
last_update_time 2026-08-02T10:00:00.000Z
local false
metadata <nil>
name 2be7c3d0-... # auto-generated from login
policies []Notice the aliases section: inside it there's mount_type: userpass and name: budi. This is the first Alias of Budi's Entity. The auto-generated Entity name (a random UUID) is usually renamed manually to be more human-friendly — we'll do that shortly.
2. Creating an entity manually (full control)
vault write -format=json identity/entity \
name="budi-dwi" \
metadata=team="backend-engineers"{
"data": {
"aliases": null,
"canonical_id": "71a7e5b1-...",
"creation_time": "2026-08-02T10:05:00.000Z",
"id": "71a7e5b1-...",
"last_update_time": "2026-08-02T10:05:00.000Z",
"name": "budi-dwi",
"policies": []
}
}3. Adding a userpass alias to this entity
vault write identity/alias \
name="budi" \
canonical_id="71a7e5b1-..." \
mount_accessor="auth_userpass_8f2..." # from vault auth list -format=jsonNow, when Budi logs in via userpass, Vault will find the alias budi on the auth_userpass_8f2... mount, map it to the budi-dwi Entity, and apply that entity's policies.
4. Adding an OIDC alias — unifying two login methods
The same step is done for an alias from the OIDC auth method:
vault write identity/alias \
name="budi@company.com" \
canonical_id="71a7e5b1-..." \
mount_accessor="auth_oidc_9d1..."Voilà — now Budi logging in via userpass or OIDC is one Entity. Any policy we attach to the budi-dwi entity applies across both login methods.
In episode 9 we learned about policies attached to tokens (token_policies). Now there's a new layer: entity policies (identity_policies). Both are combined when determining access rights — recall union semantics: capabilities are merged. But there's an important difference in how they're managed:
| Policy Type | Attached to | Managed by | Impact on new logins |
|---|---|---|---|
token_policies | Token (login result) | Role/auth method config | Policy determined at login time |
entity_policies | Entity (identity) | Identity engine admin | Applies to all of the entity's aliases |
group_policies | Group (entity collection) | Identity engine admin | Inherited by all group members |
vault token lookupKey Value
--- -----
accessor Z6Xb...
creation_time 1722747600
duration 768h
entity_id 71a7e5b1-...
expire_time 2026-09-02T10:00:00.000Z
id hvs.CAESILf...
identity_policies ["dev-kv"] # from entity
issue_time 2026-08-02T10:00:00.000Z
meta map[username:budi]
policies ["default" "dev-kv"] # combined
renewable true
token_policies ["default"] # from token/auth method
ttl 768hNotice the difference between identity_policies and token_policies in the output above. policies is the combination of both, and that's what's actually evaluated when a request comes in.
Important
The biggest advantage of entity policies: you change a user's access rights once on the entity, and the change immediately applies across all login methods — userpass, OIDC, LDAP — without touching each auth method's configuration.
Managing policies one by one for 500 employees won't scale. That's where Group comes in: a collection of entities that inherits policies to all its members. There are two types of groups in Vault:
1. Internal Groups — created manually by a Vault admin.
vault write identity/group \
name="backend-engineers" \
policies="dev-kv,ci-access"Key Value
--- -----
id e3f4a1b2-...
name backend-engineers
policies ["ci-access" "dev-kv"]
type internalThen add Budi's entity (and his colleagues') to the group:
vault write identity/group/id/e3f4a1b2-... \
member_entity_ids="71a7e5b1-...,9c8d7e6f-..."2. External Groups — created automatically when an auth method (LDAP/OIDC) sends a groups claim from the IdP.
vault write identity/group/name/okta-backend-engineers \
type="external" \
policies="dev-kv"vault read identity/group/name/okta-backend-engineersExternal groups work like this: when a user logs in via OIDC, the IdP includes a groups claim (e.g. backend-engineers from Okta). Vault automatically links the user's entity to the external group whose name matches that claim, and the group's policies are inherited.
Tip
The most common production combination: entities for personal identity, internal groups for Vault-managed team grouping, and external groups for grouping already managed by the IdP. The principle: don't duplicate team memberships that already exist in the IdP — let external groups sync them.
Because policies can come from tokens, entities, and groups at the same time, the question "why can this user access that path?" becomes crucial during audits. Vault provides tools to trace this:
vault identity lookup-entity -name budi-dwiKey Value
--- -----
aliases [map[mount_path:auth/userpass mount_type:userpass name:budi] map[mount_path:auth/oidc mount_type:oidc name:budi@company.com]]
id 71a7e5b1-...
name budi-dwi
policies [dev-kv]
merged_entity_ids []
metadata map[team:backend-engineers]
groups [map[name:backend-engineers policies:[ci-access dev-kv]]]This output answers many audit questions: Budi's entity has the dev-kv policy directly, and inherits ci-access + dev-kv from the backend-engineers group. Budi's total access rights = entity policies + group policies + login-time token policies combined.
With the command below, you can check whether a token has access rights to a specific path and their source:
vault token capabilities hvs.CAESILf... secret/data/appread listLet's weave all the concepts into one complete scenario. Your company has a backend team whose access must be consistent, whether they log in from Okta (OIDC) or from the staging lab (userpass).
1. Prepare both auth methods
vault auth enable userpass
vault auth enable oidc2. Create a shared policy
path "secret/data/staging/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/metadata/staging/*" {
capabilities = ["list"]
}vault policy write dev-kv policy/dev-kv.hcl3. Create an internal group with the policy
vault write identity/group/name=backend-engineers \
policies="dev-kv"4. Create the userpass user and entity
vault write auth/userpass/users/budi password="S3cur3Pa55word!"vault write identity/entity name="budi-dwi" metadata=team="backend-engineers"vault write identity/alias name="budi" \
canonical_id="<entity-id>" \
mount_accessor="<accessor-userpass>"vault write identity/alias name="budi@company.com" \
canonical_id="<entity-id>" \
mount_accessor="<accessor-oidc>"5. Add the entity to the group
vault write identity/group/id/<group-id> \
member_entity_ids="<entity-id>"Now, whether Budi logs in via userpass in the lab or via Okta in production, the result is the same: a token with policies: [default dev-kv] (from the backend-engineers group). One configuration, valid for all login paths, and recorded in one audit trail.
As the organization grows, you'll need ways to map all registered identities. Vault provides listing commands for all three levels:
vault list identity/entity
vault list identity/alias
vault list identity/groupKeys
----
budi-dwi
siti-amelia
backend-service-01It's important to understand that aliases and entities are different concepts:
| Question | Alias | Entity |
|---|---|---|
| "Where does Budi log in from?" | From userpass (name: budi) or OIDC (name: budi@company.com) | Not an alias's concern — this belongs to the entity |
| "Who is Budi really?" | Doesn't know; only knows method + identifier | Entity budi-dwi with metadata team: backend-engineers |
| "Which policies apply?" | Carries no policies | Carries entity policies + inherits group policies |
Many teams start by using entity metadata for operational needs, e.g. team, department, or cost-center. This metadata is readable in the audit log and useful for reporting, although it doesn't affect authorization — authorization is only affected by entity and group policies.
Note
Remember also that service accounts (machines) can have entities too. Applications logging in via AppRole automatically get their own entity. That way, you can apply the same pattern — group service accounts into groups, grant policies via the group — and revoke one machine's access centrally if needed.
| Mistake | Symptom | Solution |
|---|---|---|
| Giving policies directly to users in an auth method | Inconsistent policies across login methods | Move policies to entities/groups |
| Creating one userpass per person without an entity | Logging in from two methods = two different identities | Unify via alias + canonical_id |
| Attaching policies to external groups manually | Policies vanish when the group re-syncs from the IdP | Configure the mapping in the auth method config |
Not checking identity_policies during audits | Inherited access rights are overlooked | Always check the full vault token lookup |
| Duplicating group memberships that already exist in the IdP | Membership drift between Vault and the IdP | Use external groups |
| Merging the wrong entities (identity merge) | Two people joined into one access | Verify canonical_id before merging |
Warning
Beware of entity merge. Vault can merge two entities into one (a feature for duplicate cases), but it's permanent and could make two people share an identity if you target the wrong one. Always verify the canonical_id and metadata before merging.
In this episode we've covered the Identity Engine: Entity as the true human/machine identity, Alias as the identity mapping in each auth method, and Group (internal & external) as the mechanism to inherit policies to many entities at once. We also learned the difference between token policies, entity policies, and group policies, and how to combine them to create a unified multi-auth experience: one person, many login paths, one set of access rights.
The essence of this episode: don't let auth methods dictate your access-rights structure. The identity engine separates "who the user is" from "which door they came through," making governance far simpler and more scalable.
In episode 12, we'll cover the token and secret lifecycle: Lease, TTL, Renewal & Revocation — how every access in Vault has a time limit, how to extend it automatically, and how to revoke access instantly when a leak occurs. Keep your enthusiasm up!