The Boundary secrets engine creates Boundary Workers, and additionally, generates user and account credentials dynamically based on configured permissions and scopes. This means that services that need to access a Boundary scope no longer need to hardcode credentials and Boundary workers can be ephemeral.
With every service accessing Boundary with unique credentials, auditing is much easier in threat modelled scenarios.
Vault makes use both of its own internal revocation system to delete Boundary users and accounts when generating Boundary credentials to ensure that users and accounts become invalid within a reasonable time of the lease expiring.
Additionally, Vault can remove workers that it has created, thereby removing the controller led auth token
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.
- Enable secrets engine:
vault secrets enable boundary
By default, the secrets engine will mount at the name of the engine. To enable the secrets engine at a different path, use the -path argument.
- Configure the credentials that Vault uses to communicate with Boundary to generate credentials:
vault write boundary/config \
addr=http://localhost:9200 \
login_name=admin \
password=password \
auth_method_id=ampw_1234567890
It is important that the Vault user have the permissions to manage users and accounts at all scope levels.
- Configure a role that maps a name in Vault to a Boundary scope and roles:
vault write boundary/role/my-role \
ttl=180 \
max_ttl=360 \
auth_method_id=ampw_1234567890 \
boundary_roles=r_cwRmglckUr \
role_type=user \
scope_id=global
By writing to the roles/my-role path we are defining the my-role role. This role will be created by evaluating the given auth_method_id
, boundary_roles
, scope_id
, ttl
and max_ttl
statements. Credentials generated against this role will be created at the specified scope, using the specified auth method, and will have the specified boundary roles assigned for the duration of the ttl specified. You can read more about Boundary's Identity and Access Management domain.
After the secrets engine is configured and a user/machine has a Vault token with the proper permission, it can generate credentials.
- Generate a new credential by reading from the /creds endpoint with the name of the role:
vault read boundary/creds/my-role
Configuring a worker role is slightly different to a user role. The example below shows a worker role being configured:
vault write boundary/role/worker \
ttl=180 \
max_ttl=360 \
role_type=worker \
scope_id=global
A worker can then be generated using the following command:
vault read boundary/creds/worker worker_name="local worker"
An optional description can be added to the worker using the description
parameter.
vault read boundary/creds/worker worker_name="local worker" description="Local worker for testing purposes"
- Enable secrets engine
Sample request
curl \
-X POST \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/sys/mounts
Sample payload
{
"type": "boundary"
}
- Configure the credentials that Vault uses to communicate with Boundary to generate credentials:
Sample request
curl \
-X POST \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/boundary/config
Sample payload
{
"addr": "http://localhost:9200",
"login_name": "vault-admin",
"password": "...",
"auth_method_id": "ampw_1234567890"
}
- Configure a role that maps a name in Vault to a Boundary scope and roles:
Sample request
curl \
-X POST \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/boundary/role/my-role
Sample payload
{
"ttl": 180,
"max_ttl": 360,
"auth_method_id": "ampw_1234567890",
"credential_type": "userpass",
"boundary_roles": "r_cbvEFZbN1S,r_r8mxdp7zOp",
"role_type": "user",
"scope_id": "global"
}
- Generate a new credential by reading from the /creds endpoint with the name of the role:
Sample request
curl \
-X GET \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/boundary/creds/my-role
Sample response
{
"request_id": "ed281bc6-182d-a15e-d700-8c2e64897010",
"lease_id": "boundary/creds/my-role/pH9CfQcAmE9va6CwQKOEPBsx",
"renewable": true,
"lease_duration": 180,
"data": {
"account_id": "acctpw_Haufl3nWxH",
"auth_method_id": "ampw_1234567890",
"boundary_roles": "r_CSuslu0w1X,r_S0OqRsecY6",
"login_name": "vault-role-my-role-fudjntgy",
"password": "2QW7U03mXr614895",
"user_id": "u_sKom7Pxa1v"
},
"wrap_info": null,
"warnings": null,
"auth": null
}
- Enable secrets engine:
resource "vault_mount" "boundary" {
path = "boundary"
type = "boundary"
description = "This is the boundary secrets engine"
}
- Configure the credentials that Vault uses to communicate with Boundary to generate credentials:
resource "vault_generic_endpoint" "boundary_config" {
depends_on = [
vault_mount.boundary
]
path = "boundary/config"
ignore_absent_fields = true
data_json = <<EOT
{
"addr": "http://localhost:9200",
"login_name": "vault-admin",
"password": "...",
"auth_method_id": "ampw_1234567890"
}
EOT
}
- Configure a role that maps a name in Vault to a Boundary scope and roles:
resource "vault_generic_endpoint" "boundary_role" {
depends_on = [
vault_mount.boundary
]
path = "boundary/role/my-role"
ignore_absent_fields = true
data_json = <<EOT
{
"ttl": 180,
"max_ttl": 360,
"auth_method_id": "ampw_1234567890",
"credential_type": "userpass",
"boundary_roles": "r_cbvEFZbN1S,r_r8mxdp7zOp",
"role_type": "user"
"scope_id": "global"
}
EOT
}
- Generate a new credential by reading from the /creds endpoint with the name of the role:
data "vault_generic_secret" "boundary_creds" {
path = "boundary/creds/my-role"
}
output "creds" {
value = data.vault_generic_secret.boundary_creds.data
sensitive = true
}
- Read the output from Terraform's state file:
terraform output creds
Example response:
tomap({
"account_id" = "acctpw_nNaPX7PYzl"
"auth_method_id" = "ampw_1234567890"
"boundary_roles" = "r_U2t8YBalKE,r_5hKAwk9Rs9"
"login_name" = "vault-role-my-role-tewohlyv"
"password" = "4Le8z639725g0f1G"
"user_id" = "u_TxJs1IabfY"
})
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, without WARRANTIES or conditions of any kind, either express or implied.
See the License for the specific language governing permissions and limitations under the License.