Tokens are the core method for authenticate and validate Vault clients;therefore, nearly all requests to Vault must be accompanied by a token. Vaultclients authenticate with Vault using a configured auth method (Okta,Kubernetes, etc.). Upon successful authentication, Vault generates a tokenmanaged by the token backend and returns it to the client.
The token auth method is built-in and is at the coreof client authentication. A client can authenticate with Vault through the tokenauth method. For example, a Vault admin logs in with Vault via token auth methodusing the initial roottoken(or admin token if you are running HCP Vault Dedicated) so that the admin can configureother auth methods.
Note It is generally considered a best practice not to persist root tokens. Use theroot token only for just enoughinitial setup. Once you enabled an auth method with appropriate policiesallowing Vault admins to log in and perform operational tasks, the admins shoulduse the auth method to authenticate instead of using the root token.
Token types
There are two types of Vault tokens: service token and batch token.Vault persists the service tokens in its storage backend. You can renew aservice token or revoke it as necessary. On the other hand, Vault does notpersist the batch tokens. Batch tokens are encrypted binary large objects(blobs) that carry enough information to perform Vault actions. Therefore, batchtokens are extremely lightweight and scalable; however, they lack most of theflexibility and features of service tokens.
In addition, there is a recoverytoken which is aspecial token used when Vault is running in recovery mode. To learn more, readthe Operate Vault in Recovery Mode tutorial.
Token prefix
Tokens have a prefix that indicates their type. As of Vault1.10, the token format has changed. The following table lists the prefix differences.
Token Type | Vault 1.9.x or earlier | Vault 1.10 and later |
---|---|---|
Service tokens | s. | hvs. |
Batch tokens | b. | hvb. |
Recovery tokens | r. | hvr. |
When you upgrade your existing Vault cluster to Vault 1.10 or later, the tokensgenerated prior to Vault 1.10 will still work if they have not expired.
This tutorial focuses on the service tokens. Read the batchtokens tutorial to learn the usage of batchtokens.
Service token lifecycle
Every non-root token has a time-to-live (TTL). When a token expires, Vaultautomatically revokes it. If you create a new token, the token you used tocreate the token becomes the parent token. Once the parent token expires, so doall its children regardless of their own TTLs.
Suppose a hierarchy exists with respective TTL as follows:
hvs.b519c6aa... (1h) |___ hvs.6a2cf3e7... (4h) |___ hvs.1d3fd4b2... (2h) |___ hvs.794b6f2f... (3h)
In this scenario, the token hvs.1d3fd4b2..
will expire in two hours. Althoughits child token (hvs.794b6f2f...
) has TTL of three hours, Vault will revokethe child token when its parent expires.
When the top-level token (hvs.b519c6aa...
) expires, Vault will revoke alltokens under the tree (hvs.6a2cf3e7...
, hvs.1d3fd4b2...
, andhvs.794b6f2f...
) regardless of their TTL.
TTL and max TTL
If the token is renewable, you can use vault token renew
command to extend thetoken's TTL before it expires. You can repeatedly renew a token until it reachesits maximum TTL.
For example, if a token's TTL is 30 minutes and the maximum TTL is 24 hours, youcan renew the token before reaching the 30 minutes. You can renew the tokenmultiple times if you are using it. However, once the token reaches the 24 hoursof its first creation, you can no longer renew the token.
Important If you do not explicitly set the token's TTL or maximum TTL,it takes the system max TTL which is 32 days by default. (You can change thesystem default in the Vault server configuration file.) This means that Vaultstores the token in its storage backend for 32 days even if you are not usingit.
This tutorial explores the lifecycle of service tokens.
- Token with use limit: Tokens that are only goodto invoke a specific number of operations.
- Periodic service tokens: Tokens that can berenewed indefinitely.
- Short-lived tokens: Tokens that are valid for ashort time to avoid keeping unused tokens.
- Orphan tokens: Tokens that are root of their own tokentree.
- Token role: Create a role which defines a set of policiesand token lifecycle specification.
- Renew service tokens: Renew a token's TTL beforeit expires.
- Revoke service tokens: Revoke a token before itsexpiration.
- Apply token types: Configure an auth method so thatit generates a token with specified lifecycle.
Prerequisites
To perform the tasks described in this tutorial, you need to have a Vaultenvironment.
- Vault binary installed
- jq installed
Launch Terminal
This tutorial includes a free interactive command-line lab that lets you follow along on actual cloud infrastructure.
Note If you do not have access to an HCP Vault Dedicated cluster, visit the Create a Vault Cluster on HCP tutorial.
Launch the HCP Portal and login.
Click Vault in the left navigation pane.
In the Vault clusters pane, click vault-cluster.
Under Cluster URLs, click Public Cluster URL.
In a terminal, set the
VAULT_ADDR
environment variable to the copiedaddress.$ export VAULT_ADDR=<Public_Cluster_URL>
Return to the Overview page and click Generate token.
Within a few moments, a new token will be generated.
Copy the Admin Token.
Return to the terminal and set the
VAULT_TOKEN
environment variable.$ export VAULT_TOKEN=<token>
Set the
VAULT_NAMESPACE
environment variable toadmin
.$ export VAULT_NAMESPACE=admin
The
admin
namespace is the top-level namespace automatically created by HCPVault. All CLI operations default to use the namespace defined in thisenvironment variable.The Vault server is ready.
Tokens with use limit
In addition to TTL and max TTL, you can set the number of uses for tokens. Thetokens with a use limit expire at the end of their last use regardless of theirremaining TTLs. On the same note, use limit tokens expire at the end of theirTTLs regardless of their remaining uses.
To create tokens with a use limit, set the number of uses when youcreate them.
To view optional parameters to create tokens, run the command with
-help
flag.$ vault token create -helpUsage: vault token create [options] Creates a new token that can be used for authentication. This token will be created as a child of the currently authenticated token. The generated token will inherit all policies and permissions of the currently authenticated token unless you explicitly define a subset list policies to assign to the token. A ttl can also be associated with the token. If a ttl is not associated with the token, then it cannot be renewed. If a ttl is associated with the token, it will expire after that amount of time unless it is renewed. Metadata associated with the token (specified with "-metadata") is written to the audit log when the token is used. If a role is specified, the role may override parameters specified here.
There are a number of parameters you can set.
Create a token with a TTL of 1 hour and a use limit of 2. Attach the
default
policy.$ vault token create -ttl=1h -use-limit=2 -policy=defaultKey Value--- -----token hvs.CAESIJRM-T1q5lEjIWux1Tjx-VGqAYJdd4FZtbp1wpD5Ym9pGh4KHGh2cy5TSjRndGoxaU44NzNscm5MSlRLQXZ0ZGgtoken_accessor GMAlk9ZNLGOCuTrOEIAooJG3token_duration 1htoken_renewable truetoken_policies ["default"]identity_policies []policies ["default"]
Verification
Store the generated token in an environment variable,
USE_LIMIT_TOKEN
.Example:
$ export USE_LIMIT_TOKEN="hvs.CAESIJRM-T1q5lEjIWux1Tjx-VGqAYJdd4FZtbp1wpD5Ym9pGh4KHGh2cy5TSjRndGoxaU44NzNscm5MSlRLQXZ0ZGg"
Set the
VAULT_TOKEN
value to the token you just generated, and invoke anyCLI command.$ VAULT_TOKEN=$USE_LIMIT_TOKEN vault token lookup
Example output:
Key Value--- -----accessor GMAlk9ZNLGOCuTrOEIAooJG3creation_time 1646691009creation_ttl 1hdisplay_name tokenentity_id n/aexpire_time 2022-03-07T15:10:09.115115-08:00explicit_max_ttl 0sid hvs.CAESIJRM-T1q5lEjIWux1Tjx-VGqAYJdd4FZtbp1wpD5Ym9pGh4KHGh2cy5TSjRndGoxaU44NzNscm5MSlRLQXZ0ZGgissue_time 2022-03-07T14:10:09.115118-08:00meta <nil>num_uses 1orphan falsepath auth/token/createpolicies [default]renewable truettl 58m14stype service
Notice that the
num_uses
is now1
.Run another CLI command using the token.
$ VAULT_TOKEN=$USE_LIMIT_TOKEN vault write cubbyhole/token value=1234567890Success! Data written to: cubbyhole/token
Try to read the value now using the same token.
$ VAULT_TOKEN=$USE_LIMIT_TOKEN vault read cubbyhole/tokenError reading cubbyhole/token: Error making API request.URL: GET http://127.0.0.1:8200/v1/cubbyhole/tokenCode: 403. Errors:permission denied
The first command read the token's properties and then wrote a value to thecubbyhole secrets engine. This exhausted the use limit of 2 for this token.Therefore, the attempt to read the secret from the cubbyhole failed.
Note This section uses jq toprocess the JSON output for readability.
Use the auth/token/create
endpoint to create a new token. There are a numberof optionalparametersthat you can pass in the request payload.
Create a token with a TTL of 1 hour and a use limit of 2. Attach the
default
policy.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{ "policies": ["default"], "num_uses":2, "ttl": "1h" }' \ $VAULT_ADDR/v1/auth/token/create | jq .auth
Example output:
{ "client_token": "hvs.CAESIPIOVjQ6lhiR56z3smc7zqiEY-U9adR_KvqZrXco-q3PGh4KHGh2cy5FY1BwbEtnR09mVTJ3bkNGbkJodlFLUXk", "accessor": "4YCOmVUZLdPkAhmWFEAydQG0", "policies": [ "default" ], "token_policies": [ "default" ], "metadata": null, "lease_duration": 3600, "renewable": true, "entity_id": "", "token_type": "service", "orphan": false, "mfa_requirement": null, "num_uses": 2}
Store the generated token value in an environment variable,
USE_LIMIT_TOKEN
. Replacethe token in the example below with the token you generated.Example:
$ export USE_LIMIT_TOKEN="hvs.CAESIPIOVjQ6lhiR56z3smc7zqiEY-U9adR_KvqZrXco-q3PGh4KHGh2cy5FY1BwbEtnR09mVTJ3bkNGbkJodlFLUXk"
Verification
Set the
X-Vault-Token
value to the token you generated with use limit.$ curl --header "X-Vault-Token: $USE_LIMIT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/auth/token/lookup-self | jq .data
Example output:
{ ...snip... "num_uses": 1, "orphan": false, "path": "auth/token/create", "policies": [ "default" ], "renewable": true, "ttl": 2987, "type": "service"}
Notice that the
num_uses
is now1
.Create some data in the
cubbyhole
secrets engine.$ curl --header "X-Vault-Token: $USE_LIMIT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{ "value": "1234567890" }' \ $VAULT_ADDR/v1/cubbyhole/token
Try to make another API call.
$ curl --header "X-Vault-Token: $USE_LIMIT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/cubbyhole/token | jq
Output:
{ "errors": [ "permission denied" ]}
The first command read the token's properties and then wrote a value to thecubbyhole secrets engine. This exhausted the use limit of 2 for this token, andVault automatically revoked the token regardless of its TTL. Therefore, theattempt to read the secret from the cubbyhole failed.
Root or sudo users have the ability to generate periodic tokens.Periodic tokens have a TTL (validity period), but no max TTL; therefore,they may live for an infinite duration of time so long as they are renewedwithin their TTL. This is useful for long-running services that cannot handleregenerating a token.
Note When you set period
, it becomes the token renewal period (TTL).When a period and an explicit max TTL were both set on a token, it behaves as aperiodic token. However, once the explicit max TTL is reached, the token will berevoked. Refer to the renew service tokens to learnmore about the period and the maximum TTL.
Create a token with 24 hours period.
$ vault token create -policy="default" -period=24hKey Value--- -----token hvs.CAESIIG_PILmULFYOsEyWHxkZ2mF2a8VPKNLE8eHqd4autYGGh4KHGh2cy5aeTY0NFNSaUp3ZnpWbDF1RUNjUkNTZEgtoken_accessor kfhjoayUCHo1yjdbT0YWvlJ1token_duration 24htoken_renewable truetoken_policies ["default"]identity_policies []policies ["default"]
Generate a periodic token again and store the token value in a
periodic_token.txt
file.$ vault token create -policy="default" -period=24h -format=json \ | jq -r ".auth.client_token" > periodic_token.txt
Display the generated token's metadata.
$ vault token lookup $(cat periodic_token.txt)
Example output:
Key Value--- -----accessor kfhjoayUCHo1yjdbT0YWvlJ1creation_time 1646692678creation_ttl 24hdisplay_name tokenentity_id n/aexpire_time 2022-03-08T14:37:58.619594-08:00explicit_max_ttl 0sid hvs.CAESIIG_PILmULFYOsEyWHxkZ2mF2a8VPKNLE8eHqd4autYGGh4KHGh2cy5aeTY0NFNSaUp3ZnpWbDF1RUNjUkNTZEgissue_time 2022-03-07T14:37:58.619605-08:00meta <nil>num_uses 0orphan falsepath auth/token/createperiod 24hpolicies [default]renewable truettl 23h58m20stype service
You can renew the generated token indefinitely for as long as it does notexpire. If you do not renew, the token expires after 24 hours.
Token Renewal
Jump to the Renew service tokenssection to learn how to renew the generated token.
Create a token with 24 hours period, and store the generated token value in a
periodic_token.txt
file.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{"policies": "default", "period": "24h"}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > periodic_token.txt
Pass the returned token value (
periodic_token.txt
) in theX-Vault-Token
header to see the token properties.$ curl --header "X-Vault-Token: $(cat periodic_token.txt)" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/auth/token/lookup-self | jq .data
Example output:
{ ...snip... "period": 86400, "policies": [ "default" ], "renewable": true, "ttl": 86186, "type": "service"}
You can renew the generated token indefinitely for as long as it does notexpire. If you do not renew, the token expires after 24 hours.
Token Renewal
Jump to the Renew service tokenssection to learn how to renew the generated token.
Short-lived tokens
Create a new service token with a TTL of 60 seconds which means that the tokengets automatically revoked after 60 seconds.
Create a token with a TTL of 60 seconds, and store the generated token value ina
short-lived_token.txt
file.$ vault token create -ttl=60s -format=json \ | jq -r ".auth.client_token" > short-lived_token.txt
Lookup the generated token's metadata.
$ vault token lookup $(cat short-lived_token.txt)
Example output:
Key Value--- -----accessor 2jiF5migalnLOmlMkeFNhMClcreation_time 1646694149creation_ttl 1mdisplay_name tokenentity_id n/aexpire_time 2022-03-07T15:03:29.91061-08:00explicit_max_ttl 0sid hvs.Dq0oT4q4QrUiBagHlYCaPoWnissue_time 2022-03-07T15:02:29.910614-08:00meta <nil>num_uses 0orphan falsepath auth/token/createpolicies [root]renewable truettl 38stype service
NOTE: The
vault token lookup
command returns the token's properties.In this example, it shows that this token has 38 more seconds before it expires.When you execute a Vault command using the new token immediately following itscreation, it should work. Wait for 60 seconds and try again. It returns
Code: 403. Errors:
which indicates a forbidden API call due to expiredtoken usage.
Create a token with a TTL of 60 seconds, and store the generated token value ina
short-lived_token.txt
file.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{"ttl": "60"}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > short-lived_token.txt
Pass the returned token value (
short-lived_token.txt
) in theX-Vault-Token
header to see the token properties.$ curl --header "X-Vault-Token: $(cat short-lived_token.txt)" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/auth/token/lookup-self | jq .data
Example output:
{ ...snip... "creation_ttl": 60, ...snip... "renewable": true, "ttl": 29, "type": "service"}
In this example, it shows that this token has 29 more seconds beforeit expires.
Wait for the token's TTL to expire, and run the command again.
$ curl --header "X-Vault-Token: $(cat short-lived_token.txt)" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/auth/token/lookup-self | jq .data
It returns
null
since there is no data returned.
Orphan tokens are not children of their parent; therefore, orphan tokens donot expire when their parent does.
Orphan tokens still expire when their own max TTL is reached.
Root privilege A user must use a root token or token with sudocapability on the auth/token/create
endpoint to generate an orphan token viaCLI.
Generate an orphan token, and store the generated token value in a
orphan_token.txt
file.$ vault token create -orphan -format=json \ | jq -r ".auth.client_token" > orphan_token.txt
Lookup the generated token's metadata.
$ vault token lookup $(cat orphan_token.txt)
Example output:
Key Value--- -----accessor KiN7wpFjSaAJQWWnoz2lwo0gcreation_time 1646695005creation_ttl 0sdisplay_name tokenentity_id n/aexpire_time <nil>explicit_max_ttl 0sid hvs.YUteYoajMNxJ3u4u8I3znXLeissue_time 2022-03-07T15:16:45.704173-08:00meta <nil>num_uses 0orphan truepath auth/token/createpolicies [root]renewable falsettl 0stype service
To create an orphan token, use the auth/token/create-orphan
endpoint.
Generate an orphan token, and store the generated token value in a
orphan_token.txt
file.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ $VAULT_ADDR/v1/auth/token/create-orphan | jq -r ".auth.client_token" > orphan_token.txt
Alternatively, you can create an orphan token using the
auth/token/create
endpoint withno-parent
parameter set to true.Example:
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{ "no_parent": true }' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > orphan_token.txt
Note
The
auth/token/create
endpoint requires root token orsudo capability to create an orphan token whileauth/token/create-orphan
endpoint does not.Pass the returned token value (
client_token
) in theX-Vault-Token
header tosee the token properties.$ curl --header "X-Vault-Token: $(cat orphan_token.txt)" \ --header "X-vault-Namespace: $VAULT_NAMESPACE" \ $VAULT_ADDR/v1/auth/token/lookup-self | jq .data.orphan
This returns boolean
true
.
Validation The revoke service tokens sectiontests the lifecycle of orphan tokens.
Token role
Instead of passing a number of parameters, you can create a role with a set ofparameter values set.
Create a token role named
zabbix
.$ vault write auth/token/roles/zabbix \ allowed_policies="policy1, policy2, policy3" \ orphan=true \ period=8h
Create a token for
zabbix
role.$ vault token create -role=zabbix
Example output:
Key Value--- -----token hvs.CAESINGbJtl4chQaJ2fH0ftOsYwr5IGTimfAubxs_Fjxz_OSGh4KHGh2cy5GSjQzaVU5bjFTR1ZoaVhnSmVlSUZFbDEtoken_accessor vqKXT2A8SUltDgTD0vUPCDcztoken_duration 8htoken_renewable truetoken_policies ["default" "policy1" "policy2" "policy3"]identity_policies []policies ["default" "policy1" "policy2" "policy3"]
The generated token is valid for 8 hours and it is renewable, and multiplepolicies are attached.
Create an API request payload specifying the token parameters.
$ tee payload.json <<-EOF{ "allowed_policies": [ "default", "policy1", "policy2", "policy3" ], "period": "8h", "orphan": true}EOF
Create a token role named
zabbix
.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data @payload.json \ $VAULT_ADDR/v1/auth/token/roles/zabbix
Generate a token for role,
zabbix
.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ $VAULT_ADDR/v1/auth/token/create/zabbix | jq .auth
Example output:
{ "client_token": "hvs.CAESIN_VQ8FalMHydoGfHzo8urpd98w1-gQ6_rOVkp14SsMtGh4KHGh2cy5iYkU3dmdLNmZreUcxNE1udDVtVDd1WFA", "accessor": "dhN4WU8yEx3RcvULYE2rWf4J", "policies": [ "default", "policy1", "policy2", "policy3" ], "token_policies": [ "default", "policy1", "policy2", "policy3" ], "metadata": null, "lease_duration": 28800, "renewable": true, "entity_id": "", "token_type": "service", "orphan": true, "mfa_requirement": null, "num_uses": 0}
The generated token is valid for 8 hours (28800 seconds) and it is renewable,and multiple policies are attached.
You can renew the service token's TTL as long as it has not expired.
Create a token and save its value in a file,
test_token.txt
.$ vault token create -ttl=45 -explicit-max-ttl=120 -policy=default -format=json \ | jq -r ".auth.client_token" > test_token.txt
The generated token has a TTL of 45 seconds, and max TTL of 2 minutes (120seconds).
Renew the token's TTL before the token expires.
$ vault token renew $(cat test_token.txt)
Example output:
Key Value--- -----token hvs.CAESIJhnPJRhqeKian6_ZOcyFW362xgUG9wGkC2f2YYDlxFoGh4KHGh2cy5lN0FGUEF6a0R6d2RmenRNVTNtSnJOQmstoken_accessor Pd0QJMV6NcRz3ZFZOecOQqIhtoken_duration 45stoken_renewable truetoken_policies ["default"]identity_policies []policies ["default"]
Renew and extend the token's TTL to 60 seconds.
$ vault token renew -increment=60 $(cat test_token.txt)
Example output:
Key Value--- -----token hvs.CAESIJhnPJRhqeKian6_ZOcyFW362xgUG9wGkC2f2YYDlxFoGh4KHGh2cy5lN0FGUEF6a0R6d2RmenRNVTNtSnJOQmstoken_accessor Pd0QJMV6NcRz3ZFZOecOQqIhtoken_duration 1mtoken_renewable truetoken_policies ["default"]identity_policies []policies ["default"]
Notice that the token TTL (
token_duration
) is now 1 minute instead of 45seconds.
Create a token and save its value in a file,
test_token.txt
.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data '{"ttl": "45", "explicit_max_ttl": "120", "policies": "default"}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > test_token.txt
The generated token has a TTL of 45 seconds, and max TTL of 2 minutes (120seconds).
Create the request payload.
$ tee renew_payload.json <<-EOF{ "token": "$(cat test_token.txt)"}EOF
Renew the token's TTL before the token expires.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data @renew_payload.json \ $VAULT_ADDR/v1/auth/token/renew | jq .auth
Example output:
{ ...snip... "lease_duration": 45, "renewable": true, "entity_id": "", "token_type": "service", "orphan": false}
Update the request payload.
$ tee renew_payload.json <<-EOF{ "token": "$(cat test_token.txt)", "increment": "60"}EOF
Renew and extend the token's TTL to 60 seconds.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_NAMESPACE" \ --request POST \ --data @renew_payload.json \ $VAULT_ADDR/v1/auth/token/renew | jq .auth
Example output:
{ ...snip... "lease_duration": 60, "renewable": true, "entity_id": "", "token_type": "service", "orphan": false}
Notice that the token TTL (
lease_duration
) is now 60 seconds instead of 45seconds.
Because the explicit max TTL is set to 2 minutes, you will not be able to renewthe token after 2 minutes.
As time passes, Vault returns a message such as TTL of "26s" exceeded the effective max_ttl of "10s"; TTL value is capped accordingly
to indicate thatthe token TTL cannot exceed 2 minutes from its creation time. Eventually, thetoken expires and Vault automatically revokes it. Once the token expires, therenew command returns token not found
message.
Revoke service tokens
If a user or machine needs a temporal access to Vault, you can set a short TTLor a number of uses to a service token so the token is automatically revoked atthe end of its life. But if any suspicious activity was detected, Vault hasbuilt-in support for revocation of service tokens before reaching its TTL.
You can revoke service tokens using the vault token revoke
command or theauth/token/revoke
API endpoint.
In this section, you are going to create tokens with the following hierarchy andinspect the token lifecycle.
parent_token (1 minute) |___ child_token (3 minutes) |___ orphan_token (3 minutes)
Create a
test
policy.$ vault policy write test -<<EOFpath "auth/token/create" { capabilities = ["create", "read", "update", "delete", "list", "sudo"]}EOF
If you are not familiar with policies, complete thepolicies tutorial.
Create a token and save its value in a file,
parent_token.txt
.$ vault token create -ttl=60 -policy=test -format=json \ | jq -r ".auth.client_token" > parent_token.txt
The generated token has a TTL of 1 minute (60 seconds).
Create a token using the parent token and save its value in a file,
child_token.txt
.$ VAULT_TOKEN=$(cat parent_token.txt) \ vault token create -ttl=180 -policy=default -format=json \ | jq -r ".auth.client_token" > child_token.txt
The generated token has a TTL of 3 minute (180 seconds) while its parenttoken's TTL is 1 minute.
Create an orphan token using the parent token and save its value in a file,
orphan_token.txt
.$ VAULT_TOKEN=$(cat parent_token.txt) \ vault token create -orphan -ttl=180 -policy=default -format=json \ | jq -r ".auth.client_token" > orphan_token.txt
The generated token is an orphan token with a TTL of 3 minute (180 seconds).
Revoke the parent token.
$ vault token revoke $(cat parent_token.txt)Success! Revoked token (if it existed)
Verify that the token no longer exists by looking it up.
$ vault token lookup $(cat parent_token.txt)
Vault returns an error message.
Error looking up token: Error making API request.URL: POST http://127.0.0.1:8200/v1/auth/token/lookupCode: 403. Errors:* bad token
Look up the child token.
$ vault token lookup $(cat child_token.txt)
Vault returns the
bad token
error because Vault revoked the child tokenalong with its parent token.Look up the orphan token.
$ vault token lookup $(cat orphan_token.txt)
Because each orphan token is the root of its own token tree, it exists untilit expires. Therefore, the command displays the detail information about theorphan token.
Tip
Instead of revoking using a token value, revoke tokens with a tokenaccessorusing the
-accessor
flag.
Create a request payload with
test
policy.$ tee policy_payload.json <<EOF{ "policy": "path \"auth/token/create\" {\n capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\", \"sudo\"]\n}"}EOF
Create a
test
policy.$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request PUT \ --data @policy_payload.json \ $VAULT_ADDR/v1/sys/policies/acl/test
If you are not familiar with policies, complete thepolicies tutorial.
Create a token and save its value in a file,
parent_token.txt
.$ curl -s --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data '{"ttl": "60", "policies": "test"}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > parent_token.txt
The generated token has a TTL of 1 minute (60 seconds).
Create a token using the parent token value stored in the
parent_token.txt
file and save its value in a file,child_token.txt
.$ curl -s --header "X-Vault-Token: $(cat parent_token.txt)" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data '{"ttl": "180", "policies": "default"}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > child_token.txt
The generated token has a TTL of 3 minutes (180 seconds).
Create an orphan token using the parent token (
parent_token.txt
) and saveits value in a file,orphan_token.txt
.$ curl -s --header "X-Vault-Token: $(cat parent_token.txt)" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data '{"ttl": "180", "policies": "default", "no_parent": true}' \ $VAULT_ADDR/v1/auth/token/create | jq -r ".auth.client_token" > orphan_token.txt
The generated token has a TTL of 3 minutes (180 seconds).
Create the request payload.
$ tee revoke_payload.json <<-EOF{ "token": "$(cat parent_token.txt)"}EOF
Revoke the generated service token.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data @revoke_payload.json \ $VAULT_ADDR/v1/auth/token/revoke
Verify that the token no longer exists by tring to look it up.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data @revoke_payload.json \ $VAULT_ADDR/v1/auth/token/lookup | jq
Example Output:
{ "errors": ["bad token"]}
Create the request payload.
$ tee payload.json <<-EOF{ "token": "$(cat child_token.txt)"}EOF
Look up the child token.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data @payload.json \ $VAULT_ADDR/v1/auth/token/lookup | jq
Vault returns the
bad token
error because Vault revoked the child tokenalong with its parent token.Create the request payload.
$ tee payload.json <<-EOF{ "token": "$(cat orphan_token.txt)"}EOF
Look up the orphan token.
$ curl --header "X-Vault-Token: $VAULT_TOKEN" \ --header "X-Vault-Namespace: $VAULT_TOKEN" | --request POST \ --data @payload.json \ $VAULT_ADDR/v1/auth/token/lookup | jq
Because each orphan token is the root of its own token tree, it exists untilit expires. Therefore, the command displays the detail information about theorphan token.
Tip
Instead of revoking a token using its value, you can revoke tokens with atoken accessor bypassing the
accessor
parameter in the request payload.
You learned how you can set the token's lifecycle. The next step is to applythis to generate tokens for your applications. Vault clients first authenticatewith Vault using an authmethod to acquire a token.There are auth methods aimed to authenticate applications or machines. Once itsidentity was verified, Vault server will return a token with appropriatepolicies attached.
Use the AppRole auth method to demonstrate this.
Enable the
approle
auth method.$ vault auth enable approleSuccess! Enabled approle auth method at: approle/
Create a role for your app specifying that the generated token type isperiodic and expires after 24 hours if not renewed.
$ vault write auth/approle/role/jenkins policies="jenkins" period="24h"Success! Data written to: auth/approle/role/jenkins
This example defines a role named, "jenkins". The tokens generated for thisrole will be a periodic token with
jenkins
policy attached.
Verification
Note If you are not familiar with the AppRole auth method, read theAppRole Pull Authentication tutorial.
Retrieve the RoleID for the
jenkins
role and save it in a file,role_id.txt
.$ vault read -format=json auth/approle/role/jenkins/role-id \ | jq -r ".data.role_id" > role_id.txt
Generate a SecretID for the
jenkins
role and save it in a file,secret_id.txt
.$ vault write -f -format=json auth/approle/role/jenkins/secret-id \ | jq -r ".data.secret_id" > secret_id.txt
Authenticate with Vault using the generated
role_id
andsecret_id
.$ vault write auth/approle/login role_id=$(cat role_id.txt) \ secret_id=$(cat secret_id.txt)
Example output:
Key Value--- -----token hvs.CAESINkhQovozcMjgFICYH4JrRfr9wIVIoYMzPirvFRuKjigGh4KHGh2cy43TVhCaTY3c3dvNXliNjNnN1NPNWVyZjktoken_accessor RaASz9meQMF1bO1h3plDqt18token_duration 24htoken_renewable truetoken_policies ["default" "jenkins"]identity_policies []policies ["default" "jenkins"]token_meta_role_name jenkins
View the token details.
$ vault token lookup <returned_token>
Example:
$ vault token lookup hvs.CAESINkhQovozcMjgFICYH4JrRfr9wIVIoYMzPirvFRuKjigGh4KHGh2cy43TVhCaTY3c3dvNXliNjNnN1NPNWVyZjkKey Value--- -----accessor RaASz9meQMF1bO1h3plDqt18creation_time 1646696969creation_ttl 24hdisplay_name approleentity_id 99eb72ff-9c0f-986e-0197-ceee17848a78expire_time 2022-03-08T15:49:29.196039-08:00explicit_max_ttl 0sid hvs.CAESINkhQovozcMjgFICYH4JrRfr9wIVIoYMzPirvFRuKjigGh4KHGh2cy43TVhCaTY3c3dvNXliNjNnN1NPNWVyZjkissue_time 2022-03-07T15:49:29.196043-08:00meta map[role_name:jenkins]num_uses 0orphan truepath auth/approle/loginperiod 24hpolicies [default jenkins]renewable truettl 23h58m31stype service
The output shows the
period
of 24 hours, and thejenkins
policy isattached.
Clean up
If you wish to clean up your environment after completing the tutorial, followthe steps in this section.
Unset the
VAULT_TOKEN
environment variable.$ unset VAULT_TOKEN
Unset the
VAULT_ADDR
environment variable.$ unset VAULT_ADDR
Delete the files used to test tokens.
$ rm *_token.txt role_id.txt secret_id.txt payload.json renew_payload.json
If you are running Vault locally in
-dev
mode, you can stop the Vault devserver by pressing Ctrl+C where the server is running. Or, execute thefollowing command.$ pgrep -f vault | xargs kill
This tutorial walked through the lifecycle of service tokens. You learned how togenerate a token using the vault token create
command or the/auth/token/create
endpoint. Then, you learned how to apply the desired tokenlifecycle when you configure an auth method in the Apply tokentype section.
Integrating your application to read or write secrets to Vault may require:
- Authenticate with Vault using an auth method
- Maintain the token
- Renew or revoke the token if necessary
Vault Agent can help to simplify the introduction of Vault to your applications.The App Integration tutorials introducedifferent approaches.
But first, go through the Batch tokens tutorialto understand the difference between the service tokens and batch tokens so thatyou can decide which token type is best suited for your use case.
Reference materials
- Tokens documentation
- Token Auth Method (API)