Worker Helm chart examples
- Worker with ingress capabilities
- Worker with intermediate capabilities
- Worker with egress capabilities
- Worker with a pre-configured DNS address
- Worker-led registration
- Controller-led registration
- KMS-backed worker authentication
- Enable session recording storage
- Change service ports
The following examples show common worker configurations. They focus on the worker chart and assume the Boundary controller or HCP Boundary cluster already exists.
Worker with ingress capabilities
An ingress worker accepts connections from downstream workers and clients. It commonly uses the controller cluster as its upstream and exposes the proxy listener publicly through a LoadBalancer Service.
Example HCL for a worker with ingress capabilities:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = "boundary-worker.example.com:9202"
initial_upstreams = ["boundary-controller-cluster:9201"]
tags {
type = ["worker", "ingress"]
}
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "ATTK2pMjMTEJGlAkUJAePnFMlNLQaXBnhSqJHVlJeKQ="
key_id = "global_worker-auth"
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enabled = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values for a worker with ingress capabilities and a public LoadBalancer:
worker:
service:
proxy:
enabled: true
type: LoadBalancer
port: 9202
targetPort: 9202
ops:
enabled: true
type: ClusterIP
port: 9203
targetPort: 9203
persistence:
authStorage:
enabled: false
recording:
enabled: false
Install the worker Helm chart:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values ingress-values.yaml \
--wait
If you do not know the public_addr until the load balancer is created, wait for the external address:
$ kubectl get svc boundary-worker-proxy --namespace boundary --watch
Update public_addr in ingress-worker.hcl, and then upgrade:
$ helm upgrade boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--reuse-values \
--values ingress-values.yaml \
--rollback-on-failure \
--wait
Worker with intermediate capabilities
A worker with intermediate capabilities relays traffic between upstream and downstream workers. It requires both initial_upstreams and public_addr.
Example HCL for a worker with intermediate capabilities:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["ingress-worker-address:9202"]
tags {
type = ["worker", "intermediate"]
}
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "ATTK2pMjMTEJGlAkUJAePnFMlNLQaXBnhSqJHVlJeKQ="
key_id = "global_worker-auth"
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values for a worker with intermediate capabilities and a LoadBalancer:
worker:
service:
proxy:
enabled: true
type: LoadBalancer
port: 9202
targetPort: 9202
ops:
enabled: true
type: ClusterIP
port: 9203
targetPort: 9203
persistence:
authStorage:
enabled: false
recording:
enabled: false
Install the worker Helm chart:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values intermediate-values.yaml \
--wait
If you do not know the public_addr until the load balancer is created, wait for the external address:
$ kubectl get svc boundary-worker-proxy --namespace boundary --watch
Update the public_addr in intermediate-worker.hcl, then upgrade:
$ helm upgrade boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--reuse-values \
--values intermediate-values.yaml \
--rollback-on-failure \
--wait
Worker with egress capabilities
A worker with egress capabilities connects to target systems and is usually the final hop before a target. It often does not need a public_addr.
Example HCL for a worker with egress capabilities:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["<ingress-or-intermediate-worker-address>:9202"]
tags {
type = ["worker", "egress"]
}
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "ATTK2pMjMTEJGlAkUJAePnFMlNLQaXBnhSqJHVlJeKQ="
key_id = "global_worker-auth"
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values for a worker with egress capabilities:
worker:
service:
proxy:
enabled: false
ops:
enabled: true
type: ClusterIP
persistence:
authStorage:
enabled: false
recording:
enabled: false
Install the worker with a values file that includes the worker configuration:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values egress-values.yaml \
--wait
Worker with a pre-configured DNS address
If you already control the DNS name for the worker, set public_addr during installation:
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
tags {
type = ["worker", "ingress"]
}
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "ATTK2pMjMTEJGlAkUJAePnFMlNLQaXBnhSqJHVlJeKQ="
key_id = "global_worker-auth"
}
After the Service receives an external address, point the DNS record to that address. This avoids changing the worker HCL after installation, but you remain responsible for ensuring that DNS resolves to the reachable worker endpoint.
Worker-led registration
For worker-led registration, install the worker without a controller-generated activation token. The worker generates identity material at startup and writes registration information to the pod logs. For more information, see Worker-led authorization.
Example HCL for worker-led registration:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
auth_storage_path = "/var/lib/boundary"
tags {
type = ["worker", "worker-led"]
}
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values for worker-led registration with auth storage persistence:
worker:
persistence:
authStorage:
enabled: true
size: 1Gi
The typical workflow is as follows:
- Install the worker chart with worker-led registration settings in
worker.config. - Read the worker pod logs.
- Register or authorize the emitted worker registration information with Boundary.
- Confirm the worker becomes active.
View logs:
$ kubectl logs --namespace boundary deployment/boundary-worker-deployment
Keep auth storage enabled for worker-led registration so the generated worker identity persists across restarts.
Controller-led registration
The typical workflow for controller-led registration is as follows. For more details about controller-led registration, refer to Controller-led authorization:
- Create the worker resource in Boundary or HCP Boundary.
- Obtain the controller-generated activation token.
- Supply the token using one of the methods below.
- Install the worker Helm chart.
- Confirm the worker registers and persists its credentials to auth storage.
The worker uses the activation token during initial bootstrap. After successful registration, the worker uses persisted credentials from auth storage.
The chart supports three ways to supply the activation token.
Plaintext token
Embed the token directly in worker.config. Suitable for development only — the token is visible to anyone who can read the ConfigMap.
Example HCL:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
auth_storage_path = "/var/lib/boundary"
controller_generated_activation_token = "<activation-token>"
tags {
type = ["worker", "controller-led"]
}
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values:
worker:
persistence:
authStorage:
enabled: true
size: 1Gi
Install the worker Helm chart:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values my-values.yaml \
--wait
Token via extraEnv
Set controller_generated_activation_token to the env:// reference in worker.config and supply the token as a key-value pair in extraEnv:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
auth_storage_path = "/var/lib/boundary"
controller_generated_activation_token = "env://BOUNDARY_WORKER_CONTROLLER_GENERATED_ACTIVATION_TOKEN"
tags {
type = ["worker", "controller-led"]
}
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
Example values:
extraEnv:
- name: BOUNDARY_WORKER_CONTROLLER_GENERATED_ACTIVATION_TOKEN
value: "<activation-token>"
worker:
persistence:
authStorage:
enabled: true
size: 1Gi
Install the worker Helm chart:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values my-values.yaml \
--wait
Token from a Kubernetes Secret
Store the activation token in a Kubernetes Secret and reference it using secretRefs. The chart injects the Secret value as the BOUNDARY_WORKER_CONTROLLER_GENERATED_ACTIVATION_TOKEN environment variable, which Boundary reads at startup via the env:// prefix.
Create the Secret before installing the chart:
$ kubectl create secret generic boundary-worker-secrets \
--namespace boundary \
--from-literal=worker-controller-generated-activation-token='<activation-token>'
The key name (worker-controller-generated-activation-token) must match the value set in secretRefs.keys.controllerGeneratedActivationToken in your Helm values file. This command is provided as an example — use any Secret management method that fits your workflow.
Set controller_generated_activation_token to the env:// reference in worker.config:
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
auth_storage_path = "/var/lib/boundary"
controller_generated_activation_token = "env://BOUNDARY_WORKER_CONTROLLER_GENERATED_ACTIVATION_TOKEN"
tags {
type = ["worker", "controller-led"]
}
}
Example values:
secretRefs:
secretName: boundary-worker-secrets
keys:
controllerGeneratedActivationToken: worker-controller-generated-activation-token
worker:
persistence:
authStorage:
enabled: true
size: 1Gi
Set secretRefs.validateExisting=true to make Helm fail early if the Secret is missing during installation.
Install the worker Helm chart:
$ helm install boundary-worker hashicorp/boundary-worker \
--version 0.1.0 \
--namespace boundary \
--values my-values.yaml \
--wait
KMS-backed worker authentication
Boundary only supports KMS-backed worker authentication in self-managed deployments. For more information, refer to KMS-led authorization and authentication. It is not available for HCP Boundary workers.
For self-managed deployments, configure the worker HCL with the required KMS worker-auth stanza. KMS authentication does not require persistent local auth material, so you should disable the auth storage PVC.
Example HCL for KMS-backed worker authentication:
disable_mlock = true
listener "tcp" {
address = "0.0.0.0:9202"
purpose = "proxy"
}
listener "tcp" {
address = "0.0.0.0:9203"
purpose = "ops"
tls_disable = true
}
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
tags {
type = ["worker", "kms"]
}
}
kms "aead" {
purpose = "worker-auth"
aead_type = "aes-gcm"
key = "ATTK2pMjMTEJGlAkUJAePnFMlNLQaXBnhSqJHVlJeKQ="
key_id = "global_worker-auth"
}
events {
audit_enabled = true
sysevents_enabled = true
observations_enable = true
sink "stderr" {
name = "all-events"
event_types = ["*"]
format = "cloudevents-json"
}
}
worker:
persistence:
authStorage:
enabled: false
When worker.persistence.authStorage.enabled is false, the chart mounts an emptyDir at the auth storage path instead of creating a PVC.
Enable session recording storage
If the worker will store session recordings, enable recording persistence and set recording_storage_path in worker.config.
Example values:
worker:
persistence:
recording:
enabled: true
size: 10Gi
path: /boundary/recording
Matching HCL:
worker {
name = "boundary-worker"
public_addr = ""
initial_upstreams = ["boundary-controller-cluster:9201"]
recording_storage_path = "/boundary/recording"
tags {
type = ["worker", "recording"]
}
}
Ensure the recording storage path in worker.config matches worker.persistence.recording.path.
Change service ports
If you change listener ports, update both the HCL and chart values.
Example values:
worker:
service:
proxy:
port: 9222
targetPort: 9222
Matching HCL:
listener "tcp" {
address = "0.0.0.0:9222"
purpose = "proxy"
}
The chart does not synchronize these settings automatically.
More information
To view supported Helm values so that you can configure or update workers, refer to Worker values.