Secure agentic workflows
Enterprise
Appropriate Vault Enterprise license or HCP Vault Dedicated cluster required.
Use Vault Enterprise and your ID provider to implement zero trust principles with narrowly scoped agent credentials. Accept JWTs for autonomous agent access to perform authorized operations on Vault.
Before you start
You must have a Vault Enterprise or HCP Vault Dedicated server deployed.
You must configure a supported identity or OAuth provider:
You must have admin permissions on Vault. You need a Vault token with sufficient ACL policies attached to configure and modify your Vault deployment.
Step 1: Create an OAuth resource server profile
Create an OAuth resource server configuration file called
verify-oauth.jsonusing the environment variables you saved during provider setup:$ cat > verify-oauth.json << EOF { "issuer_id": "${ISSUER}", "use_jwks": true, "user_claim": "sub", "supported_algorithms": ["RS256"], "jwks_uri": "${JWKS_URI}", "optional_authorization_details": true } EOFCreate an OAuth resource server profile using the JSON file. Vault returns the stored profile, so you can check it for correctness without a separate read:
$ vault write sys/config/oauth-resource-server/verify @verify-oauth.json WARNING! The following warnings were returned from Vault: * algorithm "RS256" is functional but consider using PS256 (RSA-PSS) for better security * profile supports only one algorithm family - consider supporting multiple families for flexibility Key Value --- ----- actor_claim act.sub audiences [https://localhost:8200/v1] clock_skew_leeway 0 config_id de81dc66-e00d-23c6-7dfc-9cdbc5aaf97e enabled true issuer_id https://mydomain.verify.ibm.com/oauth2 jwks_uri https://mydomain.verify.ibm.com/oauth2/jwks jwt_type access_token local false mount_accessor oauth-resource-server_root_de81dc66-e00d-23c6-7dfc-9cdbc5aaf97e no_default_policy false optional_authorization_details true profile_name verify supported_algorithms [RS256] unique_id_claim jti use_jwks true user_claim subRun
vault read sys/config/oauth-resource-server/verifyto read the profile again later.
Step 2: Create an agent policy
Create a policy to encompass all the possible operations the agent might perform.
Create a policy configuration file called
agent-policy.hcl. For example, to restrict access on thekvplugin:$ cat > agent-policy.hcl << EOF # Allow KV2 read and list path "secret-v2/data/shared-secret/*" { capabilities = ["read", "list"] } path "secret-v2/metadata/shared-secret/*" { capabilities = ["list"] } EOFWrite the agent policy to Vault:
$ vault policy write agent-kv agent-policy.hcl Success! Uploaded policy: agent-kv
Step 3: Map your external identity to a Vault entity
Create a Vault entity for the external user.
Create a new entity for the AI agent user:
$ vault write identity/entity name="ai-agent" external_id="${ACTOR_EXT_ID}" policies="agent-kv" Key Value --- ----- aliases <nil> id ef897bd9-0060-1fa4-68ba-65ae5b0747ec name ai-agentSave the ID created for the AI agent entity to an environment variable:
$ export AGENT_CANONICAL_ID="ef897bd9-0060-1fa4-68ba-65ae5b0747ec"
Step 4: Create entity aliases
Create an alias for the newly created Vault entity.
Normally, creating an entity alias requires a mount_accessor value. If you
provide both an external ID and an issuer that matches your OAuth resource
server profile, Vault synthesizes the correct mount accessor for you when you
create aliases for agentic IAM.
Instead of associating the generated alias with an auth mount, the alias points to the issuer that grants access for the alias. Vault uses the following format for the mount accessor synthesis:
oauth-resource-server + _ + <namespace ID> + _ + <server profile config ID>
For example, a mount accessor in the root namespace would be:
oauth-resource-server_root_de81dc66-e00d-23c6-7dfc-9cdbc5aaf97e
You do not have to assemble the mount accessor yourself. Create, read, and
list responses from the OAuth resource server profile endpoints return the
assembled accessor in the mount_accessor field. Refer to
Mount accessor
for details.
With Vault 2.2.0 or later, you can also name the profile directly. Set
profile_name to the name you gave the profile, or config_id to the ID Vault
assigned it, and Vault resolves the profile and derives both the mount accessor
and the issuer:
$ vault write identity/entity-alias \
name="<alias_name>" \
canonical_id="<entity_canonical_id>" \
profile_name="<server_profile_name>" \
external_id="<external_id>"
The steps that follow use issuer and external_id. Refer to
Reference an OAuth resource server profile
for the rules that apply when you name the profile instead.
Create an entity alias for the AI agent entity:
$ vault write identity/entity-alias \ name="jwt-binding-actor" \ canonical_id="${AGENT_CANONICAL_ID}" \ issuer="${ISSUER}" \ external_id="${ACTOR_EXT_ID}" Key Value --- ----- canonical_id ef897bd9-0060-1fa4-68ba-65ae5b0747ec id e929f437-f655-45c0-03e7-eb6212dba58dSave the alias ID to an environment variable. Do not use the canonical ID:
$ export ALIAS_ID="e929f437-f655-45c0-03e7-eb6212dba58d"
Step 5: Register the agent with Vault
Create an entry in the Vault agent registry using the entity canonical ID:
$ vault write agent-registry/register \
display_name="<ai_agent>-iam" \
entity_id="${AGENT_CANONICAL_ID}"
For example:
$ vault write agent-registry/register \
display_name="claude-iam" \
entity_id="${AGENT_CANONICAL_ID}"
Key Value
--- -----
display_name claude-iam
id ef897bd9-0060-1fa4-68ba-65ae5b0747ec
Step 6: Validate the token flow
Use the new agent alias to mint and validate token creation in Vault.
Use
oauth2cto request an agent token from Verify and save it to an environment variable:$ export AGENT_TOKEN=$(oauth2c https://<tenant name>.verify.ibm.com/oauth2 \ --pkce \ --client-id $IBM_VERIFY_CLIENT_ID \ --client-secret $IBM_VERIFY_CLIENT_SECRET \ --response-types code \ --response-mode query \ --grant-type authorization_code \ --auth-method client_secret_basic --no-browser | jq -r '.access_token')Use the minted token with
vault token lookupto verify your configuration. Vault validates the token against the OAuth resource server config profile, resolves the entity alias, and returns the default policy:$ VAULT_TOKEN=${AGENT_TOKEN} vault token lookup
Step 7: Validate Vault operations
You can use KV version 2 operations with the minted tokens to validate the agent policies.
Enable a KV version 2 secrets engine at the path
secret-v2.$ vault secrets enable -path=secret-v2 kv-v2 Success! Enabled the kv-v2 secrets engine at: secret-v2/ Create a policy to perform KV operations and link it to the subject entity.Write a secret to the
kvplugin as yourself:$ vault kv put -mount=secret-v2 shared-secret/test \ secret_author="I am a human"Try to use the minted token to write a
kvsecret:$ VAULT_TOKEN=${AGENT_TOKEN} vault kv put -mount=secret-v2 shared-secret/test \ secret_author="I am an agent" Error writing data to secret-v2/data/shared-secret/test: Error making API request. URL: PUT http://127.0.0.1:8200/v1/secret-v2/data/shared-secret/test Code: 403. Errors: * 1 error occurred: * permission deniedThe write fails because the agent's entity policy does not allow writes to
kv.Use the minted token to read the
kvsecret:$ VAULT_TOKEN=${AGENT_TOKEN} vault kv get -mount=secret-v2 shared-secret/test ========== Secret Path ========== secret-v2/data/shared-secret/test ======= Metadata ======= Key Value --- ----- created_time 2026-10-23T21:31:15.574427Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ======== Data ======== Key Value --- ----- secret_author I am a human