HCP credential injection with private Vault
Boundary 0.10 adds support for credential management of SSH keys, starting with credential brokering. HCP Boundary and Boundary Enterprise introduced credential injection: the ability to inject SSH credentials into sessions, including through Vault. Boundary 0.11 adds support for private Vault access using a self-managed worker.
This tutorial will demonstrate SSH credential injection via private Vault for an SSH server configured using Docker. Learners may also bring their own target to use for this tutorial.
Tutorial overview
- Prerequisites
- Background
- Set up an SSH target
- Set up Vault
- Set up Boundary
- Inject credentials into sessions
Prerequisites
This tutorial assumes the learner has completed the HCP Boundary Getting Started tutorials. The learner should have a working Boundary cluster and org running on HCP.
Docker is installed (Note: Learners may also bring their own target, instead of using Docker)
A Boundary binary greater than 0.12.0 in your
PATH
A Vault binary greater than 1.7.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 greater is required for Vault support, and installing the latest version is recommended.
This tutorial assumes basic knowledge of using Vault, including running a development server and managing policies, roles, and tokens. If you are new to using Vault, complete the Getting Started with Vault quick start tutorials before integrating Vault with Boundary.
A self-managed HCP worker is required for integrating private Vault clusters with HCP Boundary. To learn more about setting up self-managed workers, refer to the Self-Managed Worker Registration with HCP Boundary tutorial.
This tutorial also extends the workflow for credential brokering via Vault. If new to this process, we recommend completing the Vault Credential Brokering Quickstart tutorial before moving forward.
Credential injection and private Vault background
Previously Boundary supported credential brokering, where Boundary controllers check out credentials from Vault and returns them back to users and clients. In this workflow, Boundary acts as a broker of the credential.
Brokering lacks the ability to hide credentials from clients. With HCP Boundary's credential injection feature, controllers instead return credentials to Boundary workers and create a session to a target where the user/client never has access to the credential. This workflow is called credential injection because the credential is injected into a worker’s session, instead of being passed back to the client.
Integrating private Vault with HCP Boundary requires a self-managed worker to be deployed in the same network as Vault. If a Vault credential store is defined with a worker filter, Boundary’s controller will know that Vault requests should be routed to workers matching that filter.
HCP Boundary can access private HCP Vault Dedicated clusters via a self-managed worker placed in a network peered with Vault Dedicated's HashiCorp Virtual Network (HVN).
For simplicity, this tutorial demonstrates integrating HCP Boundary with a private Vault cluster running locally in development mode with the HCP worker also running locally in a Docker container.
Set up an SSH target
This tutorial assumes the reader has installed Boundary 0.11.0 or above, and a Vault binary greater than 1.7.0.
First, set up a target which will be used to test the credential injection using Vault.
Note
Alternatively, you can bring your own target to test the credential injection. Credential injection is currently supported for user/pass and sshpass credentials. If bringing your own target, skip to the Set up Vault section.
Docker is used to deploy an openssh-server target for testing credential injection.
Create an ssh keypair that will be used to log in to the openssh container.
First, open a terminal session and create a new directory to store the keypair
in. This tutorial creates the openssh
directory at ~/boundary
, but you can
place this directory elsewhere if desired.
Next, create a new ssh keypair.
Press enter
twice when prompted for a passphrase, or supply one if desired.
The above command will create the keypair in the ~/boundary/openssh/
directory
at ~/boundary/openssh/openssh-key
and ~/boundary/openssh/openssh-key.pub
.
Update this path if you wish to store the key elsewhere. Note the path to the
keypair for later.
Ensure Docker is running, and then deploy the openssh container. Supply the
absolute path to the openssh/
directory created earlier after the --volume=
option, for example at /Users/myusername/boundary/openssh/
. This will mount
the folder within the docker container, making the public key file available at
/keys/
.
Note that the username for the openssh server is admin
, and the target is
available on your localhost at port 2222
(127.0.0.1:2222
).
Leave this container running for the duration of the tutorial.
Set up Vault
Open a new terminal session and run Vault in development mode.
Leave Vault running in dev mode and open a new terminal window.
Deploy a self-managed worker
An HCP worker deployed on the same network as Vault is required for integrating private Vault clusters with HCP Boundary. To learn more about setting up self-managed workers, refer to the Self-Managed Worker Registration with HCP Boundary tutorial.
Download the Boundary Enterprise binary
Download the Boundary Enterprise binary to the ~/boundary/
directory.
You can manually download the latest binary for your operating system by navigating to the Boundary releases page. The example below demonstrates downloading the binary using the command line.
Note
The binary version should match the version of the HCP control plane. Check the version of the control plane in the HCP Boundary portal, and download the appropriate version using wget. The example below installs the 0.13.0 version of the Boundary Enterprise binary.
Below is an example of downloading and unzipping the Boundary Enterprise binary on Ubuntu, MacOS, and Windows.
The following command downloads the Boundary Enterprise binary and unzips it to the current directory.
Once downloaded, verify the version of the boundary binary.
Ensure the Version Number matches the version of the HCP Boundary control plane. They should match in order to get the latest HCP Boundary features.
Write the worker config
Next, create a new file named hcp-worker.hcl
in the ~/boundary/
directory.
Open the file with a text editor, such as Vi.
Paste the following configuration into the worker config file:
1 2 3 4 5 6 7 8 9 101112131415
Update the cluster id in the hcp-worker.hcl
file:
The <cluster-id>
on line 3 can be determined from the UUID in the HCP
Boundary Cluster URL. For example, if your Cluster URL is:
https://c3a7a20a-f663-40f3-a8e3-1b2f69b36254.boundary.hashicorp.cloud
,
then the cluster id is c3a7a20a-f663-40f3-a8e3-1b2f69b36254
The auth_storage_path
should match the full path to the ~/boundary/worker1
directory, such as /home/myusername/boundary/worker1
.
Save this file.
Start the worker
With the worker config defined, start the worker server. Provide the full path
to the worker config file (such as /home/myusername/boundary/hcp-worker.hcl
).
1 2 3 4 5 6 7 8 9 101112131415161718
The worker will start and begin attempting to connect to the upstream Controller.
The worker also outputs its authorization request as the Worker Auth
Registration Request token. This will also be saved to a file,
auth_request_token
, defined by the auth_storage_path
in the worker config.
Note the Worker Auth Registration Request:
value. This value can also be
located in the ~/boundary/worker1/auth_request_token
directory. Copy this
value.
Register the worker with HCP
HCP workers can be registered using the Boundary CLI or Admin Console Web UI.
Authenticate to HCP Boundary as the admin user.
Log in to the HCP portal.
From the HCP Portal's Boundary page, click Open Admin UI - a new page will open.
Enter the admin username and password you created when you deployed the new instance and click Authenticate.
Once logged in, navigate to the Workers page.
Notice that only HCP workers are listed.
Click New.
Scroll down to the bottom of the New Worker page and paste the Worker Auth Registration Request key you copied earlier.
Click Register Worker.
Click Done and notice the new worker on the Workers page.
Define the controller policy
As described in the Vault Credential Brokering Quickstart tutorial, the following Vault policy must be defined for the Boundary controller to support credential brokering.
Export the required Vault environment variables to store the Vault address and token.
Now write the controller policy to Vault.
Define the KV policy
A policy must also be defined for the key-value secrets that will be brokered via Vault.
Create a new kv-read
policy in Vault.
Lastly, create a new Vault KV credential at the secret/my-secret
path and
provide the username and private key for the openssh-server target machine you
are connecting to. Ensure the path to the private key is entered after the @
symbol.
Note
If you brought your own target to test credential brokering
against, enter the target’s username after username
and path to the private
key after the @
.
Additionally, brokered credentials can also be attached to SSH targets. These credentials will be brokered to the end user after injection. This is useful in the case that a user needs access to application credentials on the target after the SSH credentials are successfully injected.
Create a Vault token
Now create a Vault token.
Example:
Store the returned token value in the $CRED_STORE_TOKEN
variable.
Tip
The token generation and environment variable assignment can be performed in a single step with this command:
Set up Boundary
Start by logging in to HCP Boundary within the terminal.
Export the BOUNDARY_ADDR
and BOUNDARY_AUTH_METHOD_ID
environment variables. These
values are gathered from the HCP Boundary Admin Console, as demonstrated in the
Get Started with HCP
Boundary
tutorials.
Log in to the CLI as an admin user, or a user with privileges to manage
resources in the global scope. Enter your admin username for login-name
.
Enter the the admin login name and password when prompted.
You will also need an ORG_ID
to create the SSH test project within. You may
create a new global scope for this, or utilize an existing scope used for
testing.
If creating a new org for testing, execute the following:
Whether you create a new org or not, be sure to export the org ID.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Set up a new project
Create a new project scope within Boundary. You will need an org ID to create
the new project within. To view your existing orgs, execute boundary scopes
list -recursive
.
Note
You may use an existing org scope, or create a new org scope for the ssh-project. Refer to the Manage Scopes tutorial to learn more about creating and managing scopes.
Store the returned ID value in the $PROJECT_ID
variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Create a Vault credential store
Next, you will create a new credential store within Boundary using the new token.
When setting up an HCP worker, it's important to create a worker filter for the credential store. A worker filter will identify workers that should be used as proxies for the new credential store, and ensure these credentials are brokered from the private Vault.
Recall the filters defined in the hcp-worker.hcl
file earlier:
The Tags
or Name
of the worker (hcp-worker1
) can be used to create a
worker filter for the target.
The example below adds a worker tag filter that searches for workers with the
vault
tag. Boundary will consider any worker with this tag assigned to it an
acceptable proxy for the new credential store.
Create a new vault
credential store with a worker-filter
. The vault
credential store type is used to integrate with Vault, but static
credential
stores can also be used with credential injection.
Example output:
Store the returned ID value in the $CRED_STORE_ID
variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Create a Vault credential library
Create a new credential library of type ssh_private_key
within Boundary
using the credential store ID and passing the vault-path of my-secret
.
Example output:
Store the returned ID value in the $CRED_LIB_ID
variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Create an SSH target
First, create a new static
host catalog.
Example output:
Export the new host catalog ID as the HOST_CATALOG_ID
environment variable
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Now create a new static host.
Note
Learners may also bring their own target to test credential
injection. If bringing your own target, enter the connection address for the
-address
option. The connection port is supplied when creating a target later
on.
Example output:
Export the openssh host ID as the HOST_ID
environment variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Then create a static host set.
Example output:
Export the host set ID as the HOST_SET_ID
environment variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Add the new host to the host set.
With the host set up, create a new target of type ssh
and set its default
port to 2222
. Because the target is only accesible to Boundary through the self-managed worker, also specify the -egress-worker-filter
option to filter for the worker using the filter expression "worker" in "/tags/type"
.
Note
Learners may also bring their own target to test credential
injection. If bringing your own target, enter the SSH connection port (likely
22
for SSH) for the -default-port
option.
Example output:
Store the returned ID value in the $TOKEN_ID
variable.
Tip
If you have the jq utility installed, this can be performed in a single step with this command:
Add the host set to the target.
Associate the SSH target with the SSH credential library for credential injection.
Inject credentials into sessions
Now you are ready to inject credentials directly into the shell session. You can
accomplish this using the boundary connect
command, which has a helper called
ssh
.
Enter yes
when prompted to establish the connection.
Troubleshooting
If the boundary connect ssh
command fails with the following error message, then the Vault credential store token may have expired.
Expand the accordion below to continue troubleshooting.
The error information states that No egress workers can handle this session, as they have all been filtered
.
This implies that Boundary does not understand which worker should handle the session, and cannot route traffic through the worker it selected.
In this example the error could be due to either of the following errors:
- Boundary is unable to log into Vault using the provided credential store token.
- The openssh target's egress worker filter is unset, or incorrect
First, troubleshoot the Vault credential store by generating a new Vault token.
Copy this token (such as hvs.CAESIAbmG5WIi0qILYm87ucbJSGa0rv879aJAchvFR6wG0pbGh4KHGh2cy5xY1BzTGpHUW91ZEx4ZGFTcFVDTkdPMTY
), and then update Boundary's Vault cred store with the new token value.
Log in to the Boundary Admin UI and select the
testing-org
scope. Select thessh-project
, then click Credential Stores.Select the Vault credential store (such as
csvlt_EsUGNcboLT
). Scroll down to the bottom of the credential store's Details page, and click Edit Form.Paste the newly generated vault token into the Token field, then click Save at the bottom of the page.
With the updated token in place, attempt to connect to the SSH target again.
If you are still unable to establish a connection, check that the filter has been defined correctly on the SSH target.
Navigate to Targets using the sidebar and select the openssh target.
Scroll down to the bottom of the target Details page. Ensure that the Egress worker filter toggle is on, and the Filter contains the following expression:
If this is missing, click Edit Form and enable the Egress worker filter, and paste in the above filter expression. When finished, click Save.
After verifying the correct filter value, attempt to establish a session.
When finished, the user can close the connection to the server using exit
, or
the session can be canceled directly from Boundary in a new terminal window:
Copy the session ID and cancel the session:
You can verify the session was canceled by listing the sessions again and
noticing the terminated
Status:
Note
There are cases in which targets might have multiple SSH keys or username_password credentials attached as injected application credential sources. SSH supports multiple credential sources, and Boundary will try them until it finds a usable credential when attempting a connection. This scenario is useful when rotating private keys. Both the old key and the new key can be attached to a target simultaneously, and Boundary will try both of them, stopping if one is successful. This facilitates key rotation without downtime.
Inject credentials with the Desktop App
To log into Boundary using the Desktop App, the BOUNDARY_ADDR
(Boundary
cluster address) and BOUNDARY_AUTH_METHOD_ID
(user Auth Method ID) values must be
gathered from the HCP Boundary Admin Console, as demonstrated in the HCP
Boundary Getting Started
tutorial.
Open the Boundary desktop app.
Enter the Boundary cluster URL (for example,
https://ffee961b-5fd8-4e68-ba1d-2bbb487b576e.boundary.hashicorp.cloud
) and
click Submit.
Authenticate using your HCP Boundary user credentials.
Under the Targets page, notice the target details for ssh-target.
Click Connect to initiate a session.
The Successfully Connected page will display the target ID (Target Connection details) and Proxy URL.
To start a session, open your terminal or SSH client. A session can be started using SSH and the Proxy URL from the Boundary desktop app.
For the openssh docker target, connect on 127.0.0.1 and provide the proxy
port using the -p
option. Enter yes
when prompted to establish a connection.
When finished, the user can close the connection to the server by entering
exit
, or the session can be canceled directly from the Boundary desktop app
under the Sessions view.
Cleanup and teardown
Locate the terminal session used to execute the
vault dev
server command, and executectrl+c
to stop Vault.Unset the environment variables used in any active terminal windows for this tutorial.
Destroy the boundary-worker-hcp container created for the tutorial.
Destroy the openssh-server container created for the tutorial.
Check your work by executing
docker ps
and ensure there are no more containers from the tutorial leftover. If unexpected containers still exist, executedocker rm -f <CONTAINER_ID>
against each to remove them.Cleanup the
testing-org
org and associated test resources in your HCP Boundary cluster.Open the Orgs page and select the
testing-org
.Navigate to the Org Settings page and click the Manage dropdown.
Click Delete Org and confirm the deletion.