Summary and recommendation
Vault's HTTP API uses a capability-based policy model rather than OAuth scopes. Every token must carry explicit policy grants for each path it touches, using capabilities: `create`, `read`, `update`, `delete`, `list`, `sudo`, and `deny`. There are no implicit permissions.
Authentication is token-based: callers obtain a client token via an auth method login endpoint (e.g., `POST /v1/auth/userpass/login/{username}`) and pass it as the `X-Vault-Token` header on all subsequent requests. For service-to-service automation, create a dedicated token with scoped policies via `POST /v1/auth/token/create`.
The userpass auth method and the Identity engine are distinct subsystems. A userpass user does not automatically have an Identity entity - Vault creates and links one on first login via an entity-alias.
For a complete identity graph, explicitly create the entity, retrieve the userpass mount accessor from `GET /v1/sys/auth`, and link the alias via `POST /v1/identity/entity-alias`. This is the foundation for consolidating a user's access across multiple auth methods into a single auditable identity.
API quick reference
| Has user API | Yes |
| Auth method | Vault Token (X-Vault-Token header); tokens obtained via login endpoints for each auth method (userpass, LDAP, OIDC, etc.) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: Vault Token (X-Vault-Token header); tokens obtained via login endpoints for each auth method (userpass, LDAP, OIDC, etc.)
Setup steps
- Enable an auth method: POST /v1/sys/auth/
with type (e.g., 'userpass') - Obtain a Vault token by calling the auth method's login endpoint (e.g., POST /v1/auth/userpass/login/
) - Include the returned client_token in subsequent requests as the X-Vault-Token header
- For automated/service use, create a token with appropriate policies via POST /v1/auth/token/create
- Assign policies to tokens or entities to control access to user-management paths
Required scopes
| Scope | Description | Required for |
|---|---|---|
| create on auth/ |
Policy capability to create users in a given auth method | Create user (userpass) |
| read on auth/ |
Policy capability to read user details | Read/list users |
| update on auth/ |
Policy capability to update user credentials or metadata | Update user |
| delete on auth/ |
Policy capability to delete a user | Delete user |
| list on auth/ |
Policy capability to list all users under an auth method | List users |
| create/update on identity/entity | Policy capability to manage Identity engine entities | Create/update identity entities |
| sudo on sys/auth | Required to enable or disable auth methods | Auth method management |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| username | string | Username for the userpass auth method | required | immutable (path param) | Used as the path segment in the URL |
| password | string | Plaintext password for userpass auth | required | optional | Never returned in GET responses |
| policies | array[string] | List of Vault policy names assigned to the user token on login | optional | optional | Comma-separated string or JSON array |
| token_ttl | string/duration | TTL for tokens issued on login (e.g., '1h') | optional | optional | Overrides mount default TTL |
| token_max_ttl | string/duration | Maximum TTL for tokens issued on login | optional | optional | |
| token_bound_cidrs | array[string] | CIDR blocks that restrict token use | optional | optional | |
| token_num_uses | integer | Number of uses allowed for the issued token | optional | optional | 0 = unlimited |
| token_type | string | Type of token to issue: 'default', 'batch', or 'service' | optional | optional | |
| id | string (UUID) | Canonical ID of an Identity entity | auto-generated | immutable | Identity engine only; not present in userpass objects |
| name | string | Human-readable name for an Identity entity | optional | optional | Identity engine entity field |
| metadata | map[string]string | Arbitrary key-value metadata attached to an entity or alias | optional | optional | Identity engine entity field |
| disabled | boolean | Whether the entity is disabled (login blocked) | optional | optional | Identity engine entity field; defaults to false |
| aliases | array[object] | Auth method aliases linked to this entity | n/a | managed separately via /identity/entity-alias | Read-only in entity response |
| group_ids | array[string] | IDs of groups the entity belongs to | n/a | managed via group membership endpoints | Read-only in entity response |
| creation_time | string (RFC3339) | Timestamp when the entity was created | auto-set | immutable | Identity engine entity field |
| last_update_time | string (RFC3339) | Timestamp of last entity modification | auto-set | auto-updated | Identity engine entity field |
Core endpoints
Create or update userpass user
- Method: POST
- URL:
/v1/auth/userpass/users/{username} - Watch out for: Returns 204 on success with no body. Same endpoint is used for both create and update.
Request example
POST /v1/auth/userpass/users/alice
X-Vault-Token: <token>
{
"password": "s3cr3t",
"policies": "default,dev-policy",
"token_ttl": "1h"
}
Response example
HTTP 204 No Content
Read userpass user
- Method: GET
- URL:
/v1/auth/userpass/users/{username} - Watch out for: Password is never returned in the response.
Request example
GET /v1/auth/userpass/users/alice
X-Vault-Token: <token>
Response example
{
"data": {
"policies": ["default","dev-policy"],
"token_ttl": 3600,
"token_max_ttl": 0
}
}
List userpass users
- Method: GET
- URL:
/v1/auth/userpass/users?list=true - Watch out for: Use the LIST HTTP method or append ?list=true. Returns only usernames, not full user objects.
Request example
LIST /v1/auth/userpass/users
X-Vault-Token: <token>
Response example
{
"data": {
"keys": ["alice", "bob", "carol"]
}
}
Delete userpass user
- Method: DELETE
- URL:
/v1/auth/userpass/users/{username} - Watch out for: Does not automatically revoke existing tokens issued to that user.
Request example
DELETE /v1/auth/userpass/users/alice
X-Vault-Token: <token>
Response example
HTTP 204 No Content
Update userpass password
- Method: POST
- URL:
/v1/auth/userpass/update-password/{username} - Watch out for: Users can call this endpoint against their own username with a valid token; admins can call it for any user.
Request example
POST /v1/auth/userpass/update-password/alice
X-Vault-Token: <token>
{
"password": "newP@ssw0rd"
}
Response example
HTTP 204 No Content
Create Identity entity
- Method: POST
- URL:
/v1/identity/entity - Watch out for: Entity name must be unique within the namespace. Entities are separate from auth method users and must be linked via entity-alias.
Request example
POST /v1/identity/entity
X-Vault-Token: <token>
{
"name": "alice",
"metadata": {"department": "engineering"},
"policies": ["dev-policy"]
}
Response example
{
"data": {
"id": "7d2e3179-f69b-450c-7179-ac8ee8bd8ca9",
"name": "alice"
}
}
List Identity entities
- Method: GET
- URL:
/v1/identity/entity/name?list=true - Watch out for: Can also list by ID via /v1/identity/entity/id?list=true. Returns names/IDs only, not full objects.
Request example
LIST /v1/identity/entity/name
X-Vault-Token: <token>
Response example
{
"data": {
"keys": ["alice", "bob"]
}
}
Disable/enable Identity entity
- Method: POST
- URL:
/v1/identity/entity/id/{id} - Watch out for: Disabling an entity blocks all logins for that entity across all linked auth method aliases, but does not revoke existing tokens.
Request example
POST /v1/identity/entity/id/7d2e3179-...
X-Vault-Token: <token>
{
"disabled": true
}
Response example
{
"data": {
"id": "7d2e3179-...",
"disabled": true
}
}
Rate limits, pagination, and events
- Rate limits: Vault does not impose built-in HTTP rate limits by default. Rate limiting can be configured via the 'request_limiter' stanza (Vault Enterprise 1.16+) or via a reverse proxy in front of Vault.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: HCP Vault may enforce cluster-level throughput limits. Self-managed Vault relies on operator-configured limits or upstream proxy rate limiting.
- Pagination method: token
- Default page size: 0
- Max page size: 0
- Pagination pointer: list=true (LIST HTTP method or ?list=true query param returns all keys; no page size param - full key list is returned)
| Plan | Limit | Concurrent |
|---|---|---|
| OSS / Community | No built-in rate limit | 0 |
| Enterprise | Configurable via request_limiter stanza (per-mount or global) | 0 |
| HCP Vault Dedicated | Cluster-level limits apply; consult HCP documentation | 0 |
- Webhooks available: No
- Webhook notes: Vault does not provide native outbound webhooks for user-management events.
- Alternative event strategy: Use Vault Audit Devices (file, syslog, socket) to stream all API request/response logs. Audit log entries can be forwarded to a SIEM or event pipeline (e.g., Splunk, Elastic) to trigger downstream actions on user events.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- Vault does not implement a SCIM 2.0 endpoint natively in any edition.
- User provisioning is handled via auth method APIs (userpass, LDAP, OIDC) or Identity engine APIs.
- Enterprise SAML auth method (v1.15.0+) supports IdP-driven SSO but not SCIM provisioning.
- Automated provisioning workflows must use the Vault HTTP API or Terraform provider (hashicorp/vault).
Common scenarios
Three workflows cover the majority of programmatic user management needs:
Provision a developer: Enable userpass (
POST /v1/sys/auth/userpass), create the user with a policy and TTL (POST /v1/auth/userpass/users/{username}), then optionally build the identity graph by creating an entity and linking the alias. Retrieve the mount accessor fromGET /v1/sys/auth- it is required for alias creation and is not guessable.Offboard a user: Look up the entity ID via
GET /v1/identity/entity/name/{name}, setdisabled: trueviaPOST /v1/identity/entity/id/{id}to block new logins across all linked auth methods, then explicitly revoke each active token by accessor viaPOST /v1/auth/token/revoke-accessor. Disabling the entity alone does not terminate existing sessions.Bulk audit:
LIST /v1/auth/userpass/usersreturns usernames only. Fetching full policy and TTL details requires a separateGETper user - there is no batch read endpoint. For large deployments this is an N+1 request pattern; design your audit pipeline accordingly.
Provision a new developer user with scoped access
- Ensure userpass auth method is enabled: POST /v1/sys/auth/userpass {"type":"userpass"}
- Create the user with a policy: POST /v1/auth/userpass/users/alice {"password":"...","policies":"dev-policy","token_ttl":"8h"}
- Optionally create an Identity entity for richer metadata: POST /v1/identity/entity {"name":"alice","metadata":{"team":"backend"}}
- Link the userpass alias to the entity: POST /v1/identity/entity-alias {"name":"alice","canonical_id":"
","mount_accessor":" "} - Verify by reading the user: GET /v1/auth/userpass/users/alice
Watch out for: The mount accessor for the userpass mount is required when creating entity-aliases. Retrieve it via GET /v1/sys/auth and find the accessor field for the userpass mount.
Disable a user across all auth methods (offboarding)
- Look up the user's Identity entity ID: GET /v1/identity/entity/name/alice
- Disable the entity to block all future logins: POST /v1/identity/entity/id/
{"disabled":true} - List and revoke all active tokens for the entity using the accessor: POST /v1/auth/token/revoke-accessor {"accessor":"
"} - Optionally delete the userpass user: DELETE /v1/auth/userpass/users/alice
- Confirm no active tokens remain by checking audit logs or token lookup
Watch out for: Disabling the entity blocks new logins but does not invalidate existing tokens. Explicit token revocation is required for immediate access termination.
Bulk list and audit all userpass users
- List all usernames: LIST /v1/auth/userpass/users (returns keys array)
- Iterate over each username and fetch details: GET /v1/auth/userpass/users/
- Cross-reference with Identity entities: LIST /v1/identity/entity/name to find entities without linked aliases
- Check token policies and TTLs in each user's data response for compliance review
Watch out for: The LIST endpoint returns only usernames, not full objects. A separate GET per user is required to retrieve policies and token settings. For large user counts, this is N+1 requests with no batch endpoint available.
Why building this yourself is a trap
The most dangerous assumption is that deleting a userpass user revokes their access. It does not. DELETE /v1/auth/userpass/users/{username} removes the credential record but leaves all previously issued tokens valid until their TTL expires or they are explicitly revoked.
Immediate access termination requires a separate token revocation step using the accessor.
A second common trap: the list capability is distinct from read in Vault policy. A token with only read on auth/userpass/users/* cannot enumerate users. List operations require an explicit list capability grant on the path, and omitting it produces a 403 with no descriptive error about the missing capability.
For Enterprise deployments using namespaces, all API paths are namespace-scoped. Omitting the X-Vault-Namespace header when targeting a non-root namespace will silently operate against the root namespace, potentially creating or reading resources in the wrong scope. Vault does not return a warning - the request succeeds against the wrong target.
Rate limiting is not built into Vault OSS; configure the request_limiter stanza (Enterprise 1.16+) or place a rate-limiting proxy upstream before exposing the API to automated workflows.
Automate HashiCorp Vault workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.