-
Notifications
You must be signed in to change notification settings - Fork 117
Update HCP Terraform Secrets Engine docs to clarify API token types, scope limitations, and usage examples #1268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,8 +22,7 @@ features that require them, if any. | |||||||||||||||||||||||||||||||||||||||||
| ## Quick start | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Most secrets engines must be configured in advance before they can perform their | ||||||||||||||||||||||||||||||||||||||||||
| functions. These steps are usually completed by an operator or configuration | ||||||||||||||||||||||||||||||||||||||||||
| management tool. | ||||||||||||||||||||||||||||||||||||||||||
| functions. An operator or configuration management tool usually completes these steps. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 1. Enable the HCP Terraform secrets engine: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -39,46 +38,68 @@ management tool. | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/config \ | ||||||||||||||||||||||||||||||||||||||||||
| token=Vhz7652ba4c-0f6e-8e75-5724-5e083d72cfe4 | ||||||||||||||||||||||||||||||||||||||||||
| token=<user | team | org token> | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/config | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Specify the `address` parameter when configuring Terraform Enterprise to | ||||||||||||||||||||||||||||||||||||||||||
| override the default `https://app.terraform.io`: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/config \ | ||||||||||||||||||||||||||||||||||||||||||
| address="https://tfe.example.com" \ | ||||||||||||||||||||||||||||||||||||||||||
| token=<user | team | org token> | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/config | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| See [HCP Terraform's documentation on API | ||||||||||||||||||||||||||||||||||||||||||
| tokens](/terraform/cloud-docs/users-teams-organizations/api-tokens) | ||||||||||||||||||||||||||||||||||||||||||
| to determine the appropriate API token for use with the secret engine. In | ||||||||||||||||||||||||||||||||||||||||||
| order to perform all operations, a User API token is recommended. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 3. Configure a role that maps a name in Vault to a HCP Terraform user. At | ||||||||||||||||||||||||||||||||||||||||||
| this time the HCP Terraform API does not allow dynamic user generation. As | ||||||||||||||||||||||||||||||||||||||||||
| a result this secret engine creates dynamic API tokens for an existing user, | ||||||||||||||||||||||||||||||||||||||||||
| and manages the lifecycle of that API token. You will need to know the User | ||||||||||||||||||||||||||||||||||||||||||
| ID in order to generate User API tokens for that user. You can use the | ||||||||||||||||||||||||||||||||||||||||||
| HCP Terraform [Account | ||||||||||||||||||||||||||||||||||||||||||
| API](/terraform/cloud-docs/api-docs/account) to find the | ||||||||||||||||||||||||||||||||||||||||||
| desired User ID. | ||||||||||||||||||||||||||||||||||||||||||
| to determine the appropriate API token for use with the secret engine. | ||||||||||||||||||||||||||||||||||||||||||
| Choose a token that matches your intended scope. See | ||||||||||||||||||||||||||||||||||||||||||
| [Organization, legacy team, team, and user roles](#organization-legacy-team-team-and-user-roles) | ||||||||||||||||||||||||||||||||||||||||||
| section for additional considerations. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| 3. Configure a role for an HCP Terraform Team | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Vault issues dynamic Team API tokens by mapping a role to an existing HCP Terraform | ||||||||||||||||||||||||||||||||||||||||||
| team. Vault manages these tokens’ lifecycle and automatically expires them according | ||||||||||||||||||||||||||||||||||||||||||
| to the role’s `ttl` and `max_ttl`. | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+64
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: avoid possessives, reserve capitalization for product names |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| You will need to know the Team ID in order to generate Team API tokens for that team. You | ||||||||||||||||||||||||||||||||||||||||||
| can use the HCP Terraform Teams API to find the desired Team ID. To find the Team ID, use the | ||||||||||||||||||||||||||||||||||||||||||
| [HCP Terraform Teams API](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/teams) | ||||||||||||||||||||||||||||||||||||||||||
| or navigate to the Teams section in the HCP Terraform UI. Similarly, to find a User ID, use the | ||||||||||||||||||||||||||||||||||||||||||
| [Account Details API](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/account#show-the-current-user) | ||||||||||||||||||||||||||||||||||||||||||
| or check your user profile in the UI. | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+73
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: write in active voice, reserve capitalization for product/endpoint names |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/my-role user_id=user-12345abcde credential_type=user | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/my-role | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/my-team-role \ | ||||||||||||||||||||||||||||||||||||||||||
| team_id=team-12345abcde \ | ||||||||||||||||||||||||||||||||||||||||||
| credential_type=team \ | ||||||||||||||||||||||||||||||||||||||||||
| description="CI/CD automation token" \ | ||||||||||||||||||||||||||||||||||||||||||
| ttl=300 \ | ||||||||||||||||||||||||||||||||||||||||||
| max_ttl=1800 | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/my-team-role | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ## Usage | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| After the secrets engine is configured and a user/machine has a Vault token with | ||||||||||||||||||||||||||||||||||||||||||
| the proper permission, it can generate credentials. | ||||||||||||||||||||||||||||||||||||||||||
| After the secrets engine is configured, a Vault token with the proper permissions can generate | ||||||||||||||||||||||||||||||||||||||||||
| short-lived Team API tokens. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Generate a new credential by reading from the `/creds` endpoint with the name | ||||||||||||||||||||||||||||||||||||||||||
| of the role: | ||||||||||||||||||||||||||||||||||||||||||
| Generate a new token by reading from the `/creds` endpoint with the role name: | ||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault read terraform/creds/my-role | ||||||||||||||||||||||||||||||||||||||||||
| $ vault read terraform/creds/my-team-role | ||||||||||||||||||||||||||||||||||||||||||
| Key Value | ||||||||||||||||||||||||||||||||||||||||||
| --- ----- | ||||||||||||||||||||||||||||||||||||||||||
| lease_id terraform/creds/my-user/A_LEASE_ID_PdvmJjACTtKrY2I | ||||||||||||||||||||||||||||||||||||||||||
| lease_duration 180s | ||||||||||||||||||||||||||||||||||||||||||
| lease_id terraform/creds/my-team-role/A_LEASE_ID_abc123 | ||||||||||||||||||||||||||||||||||||||||||
| lease_duration 300s | ||||||||||||||||||||||||||||||||||||||||||
| lease_renewable true | ||||||||||||||||||||||||||||||||||||||||||
| token TJFDSIFDSKFEKZX.FKFKA.akjlfdiouajlkdakadfiowe | ||||||||||||||||||||||||||||||||||||||||||
| token_id at-123acbdfask | ||||||||||||||||||||||||||||||||||||||||||
| token tftk.abcdef1234567890 | ||||||||||||||||||||||||||||||||||||||||||
| token_id at-456defghi789 | ||||||||||||||||||||||||||||||||||||||||||
| description CI/CD automation token(42) | ||||||||||||||||||||||||||||||||||||||||||
| expired_at 2025-11-08T21:30:00Z | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ## Organization, legacy team, team, and user roles | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -88,6 +109,13 @@ Teams, Legacy Team Tokens and Users. Each token type has distinct access levels | |||||||||||||||||||||||||||||||||||||||||
| and generation workflows. A given Vault role can manage any one of the | ||||||||||||||||||||||||||||||||||||||||||
| supported types at a time, however there are important differences to be aware of. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ~> **IMPORTANT:** When selecting an anchor credential for the Terraform Secrets | ||||||||||||||||||||||||||||||||||||||||||
| Engine, choose a token whose scope matches your intended use case. For example, a | ||||||||||||||||||||||||||||||||||||||||||
| user token can only manage that user’s own resources, while a team token can manage | ||||||||||||||||||||||||||||||||||||||||||
| team-level resources or other teams’ tokens if the appropriate permissions are granted. | ||||||||||||||||||||||||||||||||||||||||||
| Using a token that is too narrowly scoped may prevent Vault from issuing tokens for your | ||||||||||||||||||||||||||||||||||||||||||
| intended workflows. | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+112
to
+117
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: write in active voice, provide explicit guidance whenever possible, avoid unnecessary callouts (warnings, tips, etc.) |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ### Organization roles | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Generating a new Organization API token by reading the credentials in | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -103,7 +131,9 @@ Below is an example of creating a Vault role to manage an Organization | |||||||||||||||||||||||||||||||||||||||||
| API token and rotating the token: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/testing organization="${TF_ORGANIZATION}" credential_type=organization | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/testing \ | ||||||||||||||||||||||||||||||||||||||||||
| organization="${TF_ORGANIZATION}" \ | ||||||||||||||||||||||||||||||||||||||||||
| credential_type=organization | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/testing | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $ vault write -f terraform/rotate-role/testing | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -112,7 +142,7 @@ Success! Data written to: terraform/rotate-role/testing | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| The API token is retrieved by reading the credentials for the role: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault read terraform/creds/testing | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Key Value | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -125,24 +155,28 @@ token_id at-fqvtdTQ5kQWcjUfG | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ### User roles | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Traditionally, Vault secret engines create dynamic users and dynamic credentials | ||||||||||||||||||||||||||||||||||||||||||
| along with them. At the time of writing, the HCP Terraform API does not allow | ||||||||||||||||||||||||||||||||||||||||||
| for creating dynamic users. Instead, the HCP Terraform secret engine creates | ||||||||||||||||||||||||||||||||||||||||||
| dynamic User API tokens by configuring a Vault role to manage an existing | ||||||||||||||||||||||||||||||||||||||||||
| HCP Terraform user. The lifecycle of these tokens is managed by Vault and | ||||||||||||||||||||||||||||||||||||||||||
| will auto expire according to the configured TTL and max TTL of the Vault | ||||||||||||||||||||||||||||||||||||||||||
| role. | ||||||||||||||||||||||||||||||||||||||||||
| Traditionally, Vault secrets engines create dynamic users and credentials for those users. | ||||||||||||||||||||||||||||||||||||||||||
| At this time, the HCP Terraform API does not support creating dynamic users. Instead, the | ||||||||||||||||||||||||||||||||||||||||||
| HCP Terraform secrets engine issues dynamic User API tokens by configuring a Vault role to | ||||||||||||||||||||||||||||||||||||||||||
| manage an existing HCP Terraform user. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Vault manages the lifecycle of these tokens and automatically expires them based on the | ||||||||||||||||||||||||||||||||||||||||||
| role’s configured `ttl` and `max_ttl`. Keep in mind that User API tokens are scoped to the | ||||||||||||||||||||||||||||||||||||||||||
| individual user account — they cannot create or manage tokens for other users. If you need | ||||||||||||||||||||||||||||||||||||||||||
| Vault to issue tokens that operate across teams or support automation workflows, use a team | ||||||||||||||||||||||||||||||||||||||||||
| API token instead. | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+158
to
+167
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: avoid cross-sentence pronouns, avoid em dashes, avoid possessives |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Below is an example of creating a Vault role to manage manage User API tokens: | ||||||||||||||||||||||||||||||||||||||||||
| Below is an example of creating a Vault role to manage User API tokens: | ||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/user-testing user_id="${TF_USER_ID}" | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/user-testing \ | ||||||||||||||||||||||||||||||||||||||||||
| user_id="${TF_USER_ID}" | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/user-testing | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| The API token is retrieved by reading the credentials for the role: | ||||||||||||||||||||||||||||||||||||||||||
| Retrieve the API token by reading the credentials for the role: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault read terraform/creds/user-testing | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Key Value | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -160,18 +194,22 @@ The lifecycle of these tokens is managed by Vault and/or HCP Terraform. | |||||||||||||||||||||||||||||||||||||||||
| Generally, Vault aims to manage tokens in external APIs with revoke actions | ||||||||||||||||||||||||||||||||||||||||||
| taken according to `ttl` and `max_ttl` settings. In addition to that behavior, | ||||||||||||||||||||||||||||||||||||||||||
| using the `max_ttl` Vault will set an `ExpiredAt` date in HCP Terraform | ||||||||||||||||||||||||||||||||||||||||||
| which will ensure the token expires at the Max TTL time. This prevents | ||||||||||||||||||||||||||||||||||||||||||
| which will ensure the token expires at the `max_ttl` time. This prevents | ||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: write in active voice, avoid "this" as a pronoun |
||||||||||||||||||||||||||||||||||||||||||
| Team tokens living past their `max_ttl` if Vault is unable to revoke the token. | ||||||||||||||||||||||||||||||||||||||||||
| Omitting the `max_ttl` value will default to Vault's system `max_ttl`. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| In HCP Terraform, team tokens cannot have matching descriptions. In order to avoid | ||||||||||||||||||||||||||||||||||||||||||
| collisions, the secret engine generates a random string as a suffix to the description. It is | ||||||||||||||||||||||||||||||||||||||||||
| highly recommended you set an additional description. | ||||||||||||||||||||||||||||||||||||||||||
| collisions, the secret engine generates a random string as a suffix to the description. | ||||||||||||||||||||||||||||||||||||||||||
| It is highly recommended you set an additional description. | ||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Style correction: write in active voice |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Below is an example of creating a Vault role to manage manage Team API tokens: | ||||||||||||||||||||||||||||||||||||||||||
| Below is an example of creating a Vault role to manage Team API tokens: | ||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/team-testing team_id="${TF_TEAM_ID}" credential_type=team description="testing token" ttl=200 max_ttl=600 | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/team-testing \ | ||||||||||||||||||||||||||||||||||||||||||
| team_id="${TF_TEAM_ID}" \ | ||||||||||||||||||||||||||||||||||||||||||
| credential_type=team description="testing token" \ | ||||||||||||||||||||||||||||||||||||||||||
| ttl=200 \ | ||||||||||||||||||||||||||||||||||||||||||
| max_ttl=600 | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/team-testing | ||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -207,7 +245,9 @@ Below is an example of creating a Vault role to manage a Legacy Team API token a | |||||||||||||||||||||||||||||||||||||||||
| rotating the token: | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ```shell-session | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/legacy-team team_id="${TF_TEAM_ID}" credential_type=team_legacy | ||||||||||||||||||||||||||||||||||||||||||
| $ vault write terraform/role/legacy-team \ | ||||||||||||||||||||||||||||||||||||||||||
| team_id="${TF_TEAM_ID}" \ | ||||||||||||||||||||||||||||||||||||||||||
| credential_type=team_legacy | ||||||||||||||||||||||||||||||||||||||||||
| Success! Data written to: terraform/role/legacy-team | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $ vault write -f terraform/rotate-role/legacy-team | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.