Vault credential brokering quickstart
This tutorial provides an example of an integration with Vault to broker secrets to Boundary clients.
Background
Boundary integrates with Vault to broker Vault secrets to Boundary clients. Secrets are brokered using the command line or desktop clients to use Boundary sessions.
This feature enables Boundary as a credential broker for infrastructure targets by binding credentials with user sessions, and surfacing those credentials during session initialization.
This tutorial sets up development versions of Vault and Boundary, and then walks through the process of creating Boundary credentials stores and credential libraries for brokering of Vault secrets.
Tutorial Contents
- Deploy a demo database
- Setup Vault
- Setup Boundary
- Broker credentials for the database via Boundary
Prerequisites
A Boundary binary greater than 0.12 in your
PATH
This tutorial assumes that you are able to launch Boundary in dev mode.
A Vault binary greater than 1.7.0 in your
PATH
Docker is installed
A psql binary greater than 13.0 in your
PATH
Installing the Boundary Desktop App provides an optional workflow at the end of this tutorial. The 1.2.0 version or above is required for Vault support.
This tutorial assumes prior foundational knowledge of using Vault, including running a development server and managing policies, roles and tokens.
If you are new to using Vault, consider completing the Getting Started with Vault quick start tutorials before integrating Vault with Boundary.
Tutorial Scenario
Connecting to a networked service often requires credentials for authentication and authorization. For example, a financial analyst might require access to their company's sales database to create a monthly report. When the analyst wants to create the report, they will (hopefully) need database credentials which their reporting tool can use to connect to the sales database and run the report.
In this example, the analyst only needs credentials to the sales database once a month and only for a limited amount of time. If connection to the sales database was through Boundary, the credentials could be generated at the beginning of the session, returned to the analyst, and then revoked when the session is terminated.
This tutorial provides an example of enabling the analyst scenario by setting up a Vault integration with Boundary, and introduces the Boundary resources used for managing credentials.
Get setup
Three pieces must be setup for this tutorial:
- A demo postgres database target
- A Vault server with policies allowing connections from Boundary
- Boundary credential resources for managing credential lifecycle
The learn-boundary-vault-quickstart repository contains the lab environment for this tutorial.
Open a terminal and navigate to a working directory, such as the home directory. Clone down the sample repository containing the starter configuration files.
Navigate into the learn-boundary-vault-quickstart directory and list its contents.
The repository contains the following files:
- analyst.sql.hcl: Vault role for generating credentials for the analyst database
- boundary-controller-policy.hcl: Vault policy for the Boundary controller that enables token management
- dba.sql.hcl: Vault role for the database analyst credential generation
- northwind-database-policy.hcl: Vault policy for the demo database admin
- northwind-database.sql: Demo database tables
- northwind-roles.sql: Demo database roles and permissions
Setup PostgreSQL Northwind demo database
Start by deploying the northwind postgres database container target. This will be the target that Boundary brokers credentials for via Vault.
Export the database name and URL as environment variables.
Now launch the postgres container with Docker, passing the postgres password, database name, and URL port mapping as options.
Check that the container is running.
Next, seed the database tables.
Lastly, apply the database roles and permissions.
This information will be queried at the end of the tutorial after the credentials are successfully brokered via Vault.
Setup Vault
Vault needs to be configured to generate secrets for the database target. To set up Vault you need to:
- Start Vault
- Set up a Boundary controller policy
- Enable the database secrets engine
- Configure the postgres database plugin
- Create a database admin role to generate credentials
- Create an analyst role to generate credentials
Run Vault in dev mode
Export the Vault address and set the token to the default admin user groot
.
Now start Vault in dev mode, passing in the VAULT_TOKEN
variable.
Leave the Vault server running in this terminal, and open a new session to continue setting up Vault.
Note
Ensure that you navigate back into the
learn-boundary-vault-quickstart
directory where the sample code is located
before proceeding.
Create the boundary-controller policy
Boundary needs to lookup, renew, and revoke tokens and leases in order to broker credentials properly.
Examine the boundary-controller-policy.hcl
policy file, which assigns the
following:
- read
auth/token/lookup-self
- update
auth/token/renew-self
- update
auth/token/revoke-self
- update
sys/leases/renew
- update
sys/leases/revoke
- update
sys/capabilities-self
In the new shell session, export the Vault address and token environment variables again.
Create the boundary-controller
policy.
Configure the database secrets engine
Next, the database secrets engine must be enabled and configured with the postgresql plugin. Then a database admin (DBA) role and analyst role are created to enable credential generation.
Enable the database secrets engine.
Configure Vault with the postgres-database-plugin, connection information and allowed roles of dba and analyst:
Create the DBA role that creates credentials with
dba.sql.hcl
:Request the DBA credentials from Vault to confirm.
Create the analyst role that creates credentials with
analyst.sql.hcl
:Request the analyst credentials from Vault to confirm.
Create northwind-database policy
A policy needs to be created that grants read access for both the DBA and analyst roles.
Examine the northwind-database-policy.hcl
policy file, which assigns the
following:
- read
database/creds/analyst
- read
database/creds/dba
Create Vault token for Boundary
Lastly, a Vault token is needed to access the Boundary credential store that will be configured when setting up Boundary.
It's very important that the token is:
- periodic
- orphan
- renewable
Boundary may not be able to broker credentials unless the Vault token has these properties.
Create the token with the boundary-controller
and northwind-database
policies.
Example output:
Note
Copy and store the generated token for setting up Boundary later
on. In this example the token value is s.B2X1XMd0Y78yHoUcEV4zNTQ1
.
Setup Boundary
Start Boundary in dev mode.
Leave Boundary running in this terminal session, and open a new one to continue the tutorial.
Authenticate to Boundary as the admin user.
Configure database target
Two targets need to be created in Boundary's default project scope, one for the DBA and another for the analyst. The default host set will then be assigned to both targets.
Create a target for the DBA
Example output:
Export the DBA target ID as an environment variable. In this example, the target ID is
ttcp_2A3gcglw61
.Create a target for analyst
Example output:
Export the analyst target ID as an environment variable. In this example, the target ID is
ttcp_1r9XGCXdwE
.Add the default host set to both targets. Ensure you supply the target IDs copied previously.
Add host set to the DBA target:
Add host set to the analyst target:
Test connection to the sample database
Verify that Boundary can connect to the database target directly, without having a credential brokered from Vault. This is to ensure the target container is accessible to Boundary before attempting to broker credentials via Vault.
Authenticate to Boundary as the admin user.
Execute boundary connect postgres
to verify the connection to the analyst
target. When prompted, enter the password secret
to connect.
Note
If you followed the Admin Console workflow and did not export the
ANALYST_TARGET_ID
environment variable, supply it directly instead. In this
example the analyst target ID is ttcp_1r9XGCXdwE
.
After successfully testing the connection, terminate the session by executing
\q
.
If unable to connect to the target, revisit the section on deploying the demo database at the beginning of the tutorial, and ensure the instance was configured properly.
Credential stores
A credential store belongs to a scope and must support the principle of least privilege by providing mechanisms to limit the credentials it can access to the minimum necessary for the scope it is in.
A credential store:
- is a Boundary resource
- belongs to one and only one scope
- owns zero or more credentials
- owns zero or more credential libraries
- is deleted when the scope it belongs to is deleted
In this example the credential store is created to manage HashiCorp Vault secrets. Configuring a Vault credential store requires:
- A Vault token with appropriate permissions to allow Boundary to access Vault secrets
- One or more credential libraries and credentials that specify the paths where Boundary should access Vault credentials
Create vault credential store
Create a credential store resource in the default project scope. Supply the token created when setting up Vault.
Example output:
Export the credential store ID as an environment variable. In this example, the
target ID is csvlt_ytzGHsfp3r
.
Credential libraries
A credential library provides credentials for sessions. All credentials returned by a library must be equivalent from an access control perspective. A credential library is responsible for managing the lifecycle of the credentials it returns. For dynamic secrets, this includes creation, renewal, and revocation. For rotating credentials, this includes check-out, check-in, and rotation of secrets. The system retrieves credentials from a library for a session and notifies the library when the session has been terminated. A credential library belongs to a single credential store.
Vault credential libraries are the Boundary resource that maps to Vault secrets engines. A single credential store may have multiple types of credential libraries. For example, Vault credential store might include separate credential libraries corresponding to each of the Vault secret engine backends.
A credential library:
- is a Boundary resource
- belongs to one and only one credential store
- can be associated with zero or more targets
- can contain zero or more credentials
- is deleted when the credential store it belongs to is deleted
Create credential libraries
While there is only a single database target, two separate credential libraries should be created for the DBA and analyst roles within the credential store.
The DBA credential library is responsible for brokering credentials at the
database/creds/dba
vault path, while the analyst credential library brokers
credentials at database/creds/analyst
. Using two credential libraries allows
for separation of privileges, and enables distinct lifecycle management for the
different database roles.
Create a credential library for DBA credentials. Supply the credential store ID from above.
Example output:
Export the DBA credential library ID. In this example the DBA credential library ID is
clvlt_G20RCg2y2x
.Create a credential library for analyst credentials. Supply the credential store ID from above.
Example output:
Export the analyst credential library ID. In this example the analyst credential library ID is
clvlt_5A8xDDWpIm
.
Credentials and targets
A credential is a data structure containing one or more secrets that binds an identity to a set of permissions or capabilities. Static credential and dynamic credential are two additional base types derived from the credential base type.
A credential:
- may be a Boundary resource
- belongs to one and only one credential store
- can be associated with zero or more targets directly if it is a resource
- can be associated with zero or more libraries directly if it is a resource
- is deleted when the credential store or credential library it belongs to is deleted
A target can have multiple credentials or credential libraries associated with it:
- one for the connection from a user to a worker (ingress)
- one for the connection from a worker to an endpoint (egress)
- multiple for application credentials (like username and password)
Application credentials are returned to the user from the controller. Ingress and egress credentials are only given to a worker from a controller, and users never have direct access to them.
Add credential libraries to targets
With the credential libraries created, assign them to the appropriate targets. You will need the target ID and credential library ID for the respective targets.
Add a credential library to the DBA target. Ensure that you provide the correct target ID and credential library ID associated with the DBA.
Example output:
Add a credential library to the analyst target. Ensure that you provide the correct target ID and credential library ID associated with the analyst.
Example output:
Broker credentials via Vault
With their respective credential libraries assigned added to the targets, sessions can be authorized using credentials brokered by Vault.
Use Boundary to connect to the northwind demo database
A session can be authorized directly using the boundary targets
authorize-session
command.
Authorize a session to the analyst target, supplying its target ID.
Note
If you followed the Admin Console workflow and did not export the
ANALYST_TARGET_ID
environment variable, supply it directly instead. In this
example the analyst target ID is ttcp_1r9XGCXdwE
.
Notice the Credentials:
section of the output, which displays the base64 credentials.
If desired, jq
can be used to parse the output and display the decoded credentials.
The decoded_credentials
key displays the credentials without the base64
encryption.
Next, establish a connection to the analyst target using the boundary connect
postgres
command. This will automatically pass the brokered credentials for the
target and establish a psql session to the northwind database.
A psql connection to the northwind database should open. Query the available schema.
When finished, run \q
to close the connection.
Check the controller spool in the terminal where boundary dev
was executed.
Notice the session authorization, connection, and termination logs. Connections can also be monitored using the Admin Console or the Boundary Desktop app in the Sessions tab in the Generated project scope.
Connect using the Desktop App
Credentials can also be brokered using the Boundary Desktop App.
Launch the Desktop app and authenticate to dev mode at http://127.0.0.1:9200
using the credentials admin
and password
.
Navigate to the Targets view, locate the Northwind Analyst Database target and click Connect.
The credentials can be copied directly from this view. Depending on the target type other credentials may be available, such as the certificate and private key. The Desktop App's connect interface can be used instead of generating the credentials on the command-line.
The password, username and raw API output can also be displayed within the UI.
Cleanup and teardown
Locate the terminal session used to start the
boundary dev
command, and executectrl+c
to stop Boundary.Locate the terminal session used to start the
vault server
command, and executectrl+c
to stop Vault.Unset the environment variables used in any active terminal windows for this tutorial.
Destroy the northwind postgres container created for the tutorial.
Check your work with a quick docker ps
and ensure there are no more postgres
containers from the tutorial leftover. If unexpected containers still exist,
execute docker rm -f <CONTAINER_ID>
against each to remove them.