Deploy workers
Enterprise
This feature requires Boundary Enterprise.
A self-managed Boundary deployment needs at least one worker in each network boundary that contains targets.
Each worker runs the boundary server command with a configuration file that defines its proxy listener, its upstream, and the KMS key that encrypts its credentials on disk.
Before you deploy workers, you should have completed the following steps:
- Installed Boundary on at least three controller nodes.
- Prepared or have three existing network boundaries:
- Public/DMZ network
- Intermediate network
- Private network
- Prepared three virtual machines for Boundary workers, one in each network boundary with the Boundary binary installed on it.
Enterprise
This feature requires Boundary Enterprise.
In the following configuration files, there are common configuration components as well as some unique components depending on the role the Boundary worker performs. There are three files, one for each worker in a unique network boundary. Additionally, Boundary supports a multi-hop configuration in which the Boundary workers can serve one of three purposes: an ingress worker, an ingress/egress worker, or an egress worker.
Prepare the environment files
HashiCorp recommends using either the env:// or file:// notation within the configuration files, to securely provide secret configuration components to the Boundary worker binaries.
The following configuration example uses env:// to secure AWS KMS configuration items.
When you install the Boundary binary using a package manager, it includes a unit file which configures an environment file at /etc/boundary.d/boundary.env.
You can use this file to set sensitive values in the Boundary worker configuration file.
The following file is an example of how this environment file could be configured:
/etc/boundary.d/boundary.env
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
In the example above, the proper IAM (Identity and Access Management) roles and permissions for the given AWS_ACCESS_KEY and AWS_SECRET_ACCESS_KEY must be in place so that Boundary can use them to access the different KMS keys.
Prepare the worker KMS keys
The worker-auth storage KMS key is used by a Worker for the encrypted storage of authentication keys.
This is recommended for workers using controller-led or worker-led registration methods. If not specified, the authentication keys are not encrypted on disk. Optionally, if you deploy KMS authentication-driven Boundary workers, you must generate an additional KMS key to authenticate the Boundary worker with the controller.
HashiCorp strongly recommends using the Key Management System (KMS) of the cloud provider where you deploy your Boundary workers.
Boundary workers must have the correct level of permissions for interacting with the cloud provider's KMS.
Refer to your cloud provider's documentation for more information.
Create the worker configurations
After you create the requisite key or keys in the cloud provider of your choice, you can begin configuring the workers.
The following configuration examples all employ the worker-led authorization flow. For more information on configuring KMS authentication for Boundary workers, refer to the external KMS registration documentation.
You can configure ingress, intermediate, and egress workers to take advantage of multi-hop worker capabilities.
Note that "ingress," "intermediate," and "egress" are general ways to describe how the respective worker interacts with resources. A worker can serve more than one of those roles at a time. Refer to Multi-hop sessions for more information.
Complete the steps below to configure workers.
If you configure your workers to support session recording, you must add an auth_storage_path value and configure a storage backend. Refer to the Configure workers for storage documentation to learn more.
Ingress, intermediate, and egress workers
"Ingress," "intermediate," and "egress" are general ways to describe how the respective worker interacts with resources. A worker can serve more than one of those roles at a time. Refer to Multi-hop sessions for more information.
Ingress worker configuration
Create the ingress-worker.hcl file with the relevant configuration information:
/etc/boundary.d/ingress-worker.hcl
# disable memory from being swapped to disk
disable_mlock = true
# listener denoting this is a worker proxy
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
# worker block for configuring the specifics of the
# worker service
worker {
public_addr = "<worker_public_addr>"
initial_upstreams = ["<controller_lb_address>:9201"]
auth_storage_path = "/var/lib/boundary"
tags {
type = ["worker1", "upstream"]
}
}
# Events (logging) configuration. This
# configures logging for ALL events to both
# stderr and a file at /var/log/boundary/<boundary_use>.log
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
description = "All events sent to stderr"
event_types = ["*"]
format = "cloudevents-json"
}
sink {
name = "file-sink"
description = "All events sent to a file"
event_types = ["*"]
format = "cloudevents-json"
file {
path = "/var/log/boundary"
file_name = "ingress-worker.log"
}
audit_config {
audit_filter_overrides {
sensitive = "redact"
secret = "redact"
}
}
}
}
# kms block for encrypting the authentication PKI material
kms "awskms" {
purpose = "worker-auth-storage"
region = "us-east-1"
kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey3"
endpoint = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}
Intermediate worker configuration
Create the intermediate-worker.hcl file with the relevant configuration information:
/etc/boundary.d/intermediate-worker.hcl
# disable memory from being swapped to disk
disable_mlock = true
# listener denoting this is a worker proxy
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
# worker block for configuring the specifics of the
# worker service
worker {
public_addr = "<worker_public_addr>"
initial_upstreams = ["<ingress_worker_address>:9202"]
auth_storage_path = "/var/lib/boundary"
tags {
type = ["worker2", "intermediate"]
}
}
# Events (logging) configuration. This
# configures logging for ALL events to both
# stderr and a file at /var/log/boundary/<boundary_use>.log
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
description = "All events sent to stderr"
event_types = ["*"]
format = "cloudevents-json"
}
sink {
name = "file-sink"
description = "All events sent to a file"
event_types = ["*"]
format = "cloudevents-json"
file {
path = "/var/log/boundary"
file_name = "intermediate-worker.log"
}
audit_config {
audit_filter_overrides {
sensitive = "redact"
secret = "redact"
}
}
}
}
# kms block for encrypting the authentication PKI material
kms "awskms" {
purpose = "worker-auth-storage"
region = "us-east-1"
kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey4"
endpoint = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}
Egress worker configuration
Create the egress-worker.hcl file with the relevant configuration information:
/etc/boundary.d/egress-worker.hcl
# disable memory from being swapped to disk
disable_mlock = true
# listener denoting this is a worker proxy
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
# worker block for configuring the specifics of the
# worker service
worker {
public_addr = "<worker_public_addr>"
initial_upstreams = ["<intermediate_worker_address>:9202"]
auth_storage_path = "/var/lib/boundary"
tags {
type = ["worker3", "egress"]
}
}
# Events (logging) configuration. This
# configures logging for ALL events to both
# stderr and a file at /var/log/boundary/<boundary_use>.log
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
description = "All events sent to stderr"
event_types = ["*"]
format = "cloudevents-json"
}
sink {
name = "file-sink"
description = "All events sent to a file"
event_types = ["*"]
format = "cloudevents-json"
file {
path = "/var/log/boundary"
file_name = "egress-worker.log"
}
audit_config {
audit_filter_overrides {
sensitive = "redact"
secret = "redact"
}
}
}
}
# kms block for encrypting the authentication PKI material
kms "awskms" {
purpose = "worker-auth-storage"
region = "us-east-1"
kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey5"
endpoint = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}
Refer to the list below for explanations of the parameters used in the example above:
disable mlock (bool: false)- Disables the server from executing themlocksyscall, which prevents memory from being swapped to the disk. Disablingmlockis fine for local development and testing. However, it is not recommended for production unless the systems running Boundary use only encrypted swap or do not use swap at all. Boundary only supports memory locking on UNIX-like systems that supportmlock()syscall like Linux and FreeBSD.On Linux, to give the Boundary executable the ability to use
mlocksyscall without running the process as root, run the following command:sudo setcap cap_ipc_lock=+ep $(readlink -f $(which boundary))If you use a Linux distribution with a modern version of systemd, you can add the following directive to the "[Service]" configuration section:
LimitMEMLOCK=infinitylistener- Configures the listeners on which Boundary serves traffic (API cluster and proxy).worker- Configures the worker. If present,boundary serverstarts a worker subprocess.events- Configures event-specific parameters.The example events configuration above is exhaustive and writes all events to both
stderrand a file. This configuration may or may not work for your organization's logging solution.kms- Configures KMS blocks for various purposes.Refer to the links below for configuration information for the different cloud KMS blocks:
Refer to the documentation for additional top-level configuration options and additional worker-specific options.
Start the Boundary service
When the configuration files are in place on each Boundary worker node, you can enable and start the binary on each of the Boundary worker nodes using systemd.
Run the following commands on each worker node to enable and start the service:
Enable the service so that it starts when the node boots:
$ sudo systemctl enable boundaryStart the service:
$ sudo systemctl start boundaryConfirm that the service is running:
$ sudo systemctl status boundary
Manually configure systemd (optional)
If you installed Boundary manually, you can configure Boundary to run as a service under systemd.
Before you begin, check the location of your worker configuration file on disk, such as /etc/boundary.d/egress-worker.hcl in the example on this page.
You reference the location of the .hcl configuration file when you set up the unit file.
HashiCorp recommends that you run Boundary as a non-root user, and that you manage the Boundary process under systemd with that user.
Complete the following steps to run a worker as a systemd service:
Add the
boundarysystem user and group, and give the user ownership of the configuration file and binary:$ sudo adduser --system --group boundary || true ; $ sudo chown boundary:boundary /etc/boundary.d/egress-worker.hcl ; $ sudo chown boundary:boundary /usr/local/bin/boundaryIf you configure the worker for session recording, the
boundaryuser also requires access to therecording_storage_pathdirectory.Create a unit file at
/etc/systemd/system/boundary-worker.service. Update the path on theExecStartline to match the location of your worker configuration file:/etc/systemd/system/boundary-worker.service
[Unit] Description="HashiCorp Boundary worker" Documentation=https://developer.hashicorp.com/boundary/docs StartLimitIntervalSec=60 StartLimitBurst=3 [Service] EnvironmentFile=-/etc/boundary.d/boundary.env User=boundary Group=boundary ProtectSystem=full ProtectHome=read-only ExecStart=/usr/bin/boundary server -config=/etc/boundary.d/egress-worker.hcl ExecReload=/bin/kill --signal HUP $MAINPID KillMode=process KillSignal=SIGINT Restart=on-failure RestartSec=5 TimeoutStopSec=30 LimitMEMLOCK=infinity [Install] WantedBy=multi-user.targetThe
ExecReloaddirective sendsSIGHUPto the worker, which reloads theinitial_upstreams,tags, andssh_known_hosts_pathvalues without restarting the process. TheKillSignaldirective sendsSIGINT, which starts a graceful shutdown so that the worker drains any active sessions.Set the permissions on the unit file:
$ sudo chmod 664 /etc/systemd/system/boundary-worker.serviceReload the systemd daemon, then enable and start the service:
$ sudo systemctl daemon-reload ; $ sudo systemctl enable boundary-worker ; $ sudo systemctl start boundary-workerConfirm that the service is running:
$ sudo systemctl status boundary-worker
If you use the worker-led registration method, the worker writes its registration request to the auth_request_token file in the auth_storage_path directory.
You can also find the value in the service logs:
$ sudo journalctl -u boundary-worker | grep "Worker Auth Registration Request"
Register the workers
If you deploy a worker using the worker-led method described above, you must register the Boundary workers to a controller.
Complete the following steps to register the worker using the Admin UI:
Log in to Boundary as the admin user.
Select Workers in the navigation pane.
Click New.
(Optional) You can use the New PKI Worker page to construct the contents of the worker configuration file, if you did not create the configuration file already. Provide the following details, and Boundary constructs the worker configuration file for you:
- Boundary Cluster ID
- Worker public address
- Config file path
- Worker Tags
- Local Session Recording Storage
Under Confirm the worker when they connect, paste the Worker Auth Registration Request key. Boundary prints the Worker Auth Registration Request key in the CLI output when you start the worker. You can also read the value from the
auth_request_tokenfile in the worker'sauth_storage_pathdirectory.Click Register Worker. Boundary marks the registration request as Registered.
Click Done.
Boundary returns you to the Workers page, where the new worker appears in the list.
After the worker registers, Boundary deletes the auth_request_token file from the worker's auth_storage_path directory.
The activation token is single use, so you cannot register the same worker twice with the same token.
Repeat the registration process for the other workers, such as the intermediate and egress workers.
Verify the workers
Use the following command to list the workers that are registered with the controller:
$ boundary workers list
Boundary returns each registered worker, its address, and its release version:
Worker information:
ID: w_UJ3Qq63Jx0
Version: 1
Address: 10.0.0.10:9202
ReleaseVersion: Boundary v1.0.0+ent
Last Status Time: Fri, 07 Aug 2026 19:45:12 UTC
Authorized Actions:
no-op
read
update
delete
add-worker-tags
set-worker-tags
remove-worker-tags
A recent Last Status Time value indicates that the worker is connected to its upstream and reporting status.
Use the following command to view the details for a specific worker:
$ boundary workers read -id w_UJ3Qq63Jx0
Boundary returns the worker's configuration tags, storage state, and connected downstream workers:
Worker information:
Active Connection Count: 0
Address: 10.0.0.10:9202
Created Time: Fri, 07 Aug 2026 13:44:30 MDT
ID: w_UJ3Qq63Jx0
Last Status Time: 2026-08-07 19:45:22.616245 +0000 UTC
Local Storage State: not configured
Release Version: Boundary v1.0.0+ent
Type: pki
Updated Time: Fri, 07 Aug 2026 13:45:22 MDT
Version: 1
Scope:
ID: global
Name: global
Type: global
Tags:
Configuration:
type: ["worker1" "ingress"]
Canonical:
type: ["worker1" "ingress"]
Authorized Actions:
no-op
read
update
delete
add-worker-tags
set-worker-tags
remove-worker-tags
The output includes the following fields that indicate worker health:
Last Status Time- The time the worker last reported status to a controller.Local Storage State- The state of the worker's local storage. The value isnot configuredunless you configure the worker for session recording.Release Version- The Boundary version the worker runs.Tags- TheConfigurationtags come from the worker configuration file. TheCanonicaltags include both configuration tags and any API tags you add.
In a multi-hop deployment, the Directly Connected Downstream Workers field confirms the shape of the chain.
Read the ingress worker and check that it lists the intermediate worker, then read the intermediate worker and check that it lists the egress worker.
If a worker does not appear, or does not report status, refer to Troubleshoot workers.
Troubleshooting
Common issues when deploying and registering Boundary workers include:
- Expired
auth_request_token: The Worker Auth Registration Request token is time-limited. If registration fails because the token has expired, restart the worker to generate a new token and repeat the registration steps. - Worker fails to register: Confirm that the worker's configuration file references the correct KMS key or authorization method for its registration flow (worker-led, controller-led, or KMS), and that the controller's cluster listener is reachable from the worker's network boundary.
Next steps
After you configure workers, you should:
To route session traffic through these workers, refer to Route traffic through a worker and Configure multi-hop sessions for Boundary Enterprise.