Controller values
You configure the Boundary controller Helm chart with Helm values and a Boundary HCL configuration. This page documents the Helm values you use to deploy the controller on Red Hat OpenShift, including the shared chart values and the OpenShift-specific values. The chart is the source of truth for supported values.
Boundary runtime configuration
The controller.config contains the Boundary controller HCL. The chart writes the HCL values into a ConfigMap and mounts it at /etc/boundary/controller.hcl.
The chart does not fully validate Boundary controller semantics. You are responsible for configuring valid listeners, database settings, cluster addresses, key management system (KMS) stanzas, rate limits, and event sinks.
The chart performs these targeted checks:
- An API listener exists. An operations listener also exists when
tls.ops.disabled=false. - API and operations listener
tls_disablesettings align withtls.api.disabledandtls.ops.disabled. - TLS-enabled API and operations listeners use
tls_cert_fileandtls_key_filepaths undertls.mountPath. - Authenticated Encryption with Associated Data (AEAD) key management system (KMS) keys do not use unsupported
env://BOUNDARY_KMS_*references. - Secret-backed database, migration, and license fields use the chart's environment variable names or names declared in
extraEnv. - The referenced Secret contains the keys required by the rendered configuration and enabled bootstrap Job when
secretRefs.validateExisting=true. - Database migrations run with
controller.replicas=0, and a repair version is set only when migration is enabled.
OpenShift infrastructure configuration
OpenShift-specific values control the Deployment, Services, ConfigMap, Job hooks, security contexts, ServiceAccount, and scheduling options. These values do not replace or generate the Boundary runtime HCL.
For example, if you change controller.service.api.targetPort to 9220, you must also update the API listener port in the controller.config.
Refer to the configuration alignment checklist before you finalize any changes.
The following sections describe the available Helm values grouped by function. Each table lists the key, default value, and a description.
Naming and namespace values
| Key | Default | Description |
|---|---|---|
nameOverride | "" | Overrides the chart-generated resource base name |
fullnameOverride | "" | Fully overrides the chart-generated resource name |
namespace | "" | Overrides the namespace the chart renders namespaced resources into. An empty value uses the Helm release namespace. |
Image values
| Key | Default | Description |
|---|---|---|
image.repository | "" | Image repository override. An empty value uses hashicorp/boundary-enterprise. |
image.tag | "" | Image tag override. An empty value uses the chart application version, 1.0.2-ent for chart 0.2.0. |
image.pullPolicy | IfNotPresent | Image pull policy |
imagePullSecrets | [] | Optional image pull secrets for private registries |
TLS values
| Key | Default | Description |
|---|---|---|
tls.api.disabled | false | Disables TLS for the API listener when true. |
tls.ops.disabled | false | Disables TLS for the operations listener when true. |
tls.secretName | boundary-controller-tls | Name of the TLS Secret mounted when TLS is enabled |
tls.mountPath | /etc/boundary/tls | Container path where the TLS Secret is mounted |
You can configure API and operations TLS independently. The chart mounts the TLS Secret when either listener has TLS enabled. Keep each listener's tls_disable setting aligned with its corresponding chart value and keep certificate paths aligned with tls.mountPath. The chart checks the paths but does not validate certificate contents, trust, expiration, or subject alternative names (SANs).
Secret reference values
| Key | Default | Description |
|---|---|---|
secretRefs.secretName | boundary-controller-secrets | Name of an existing Secret that contains the values referenced by secretRefs.keys |
secretRefs.validateExisting | false | When true, looks up the referenced Secret and checks the keys required by the rendered HCL and enabled bootstrap Job during rendering. Requires cluster lookup access. |
secretRefs.keys.databaseUrl | database-url | Key in the Secret used for env://BOUNDARY_PG_URL in controller.config. Set to the key name used in your Secret. |
secretRefs.keys.migrationUrl | migration-url | Key in the Secret used for env://BOUNDARY_PG_MIGRATION_URL in controller.config. Required only when referenced in controller.config. Set to the key name used in your Secret. |
secretRefs.keys.license | license | Key in the Secret used for env://BOUNDARY_LICENSE in controller.config. Set to the key name used in your Secret. |
secretRefs.keys.adminUsername | admin-username | Key in the Secret whose value is used by the bootstrap admin Job. Set to the key name used in your Secret. |
secretRefs.keys.adminPassword | admin-password | Key in the Secret whose value is used by the bootstrap admin Job. Set to the key name used in your Secret. |
The secretRefs.keys values are key names inside your Secret. The chart mounts no Secret as a file. Instead, it conditionally creates environment variables from Secret key references when the rendered HCL uses env://BOUNDARY_PG_URL, env://BOUNDARY_PG_MIGRATION_URL, or env://BOUNDARY_LICENSE. The bootstrap Job always references the administrator keys when enabled.
Validation is targeted. With secretRefs.validateExisting=true, the chart checks only the keys used by the rendered configuration and enabled bootstrap settings. With the default false, a missing Secret or key is reported when the pod is created. Neither mode validates the values or external service connectivity.
Controller runtime values
| Key | Default | Description |
|---|---|---|
controller.replicas | 2 | Number of controller replicas in the Deployment |
controller.rollingUpdate.maxUnavailable | 1 | Maximum unavailable pods during a rolling update |
controller.rollingUpdate.maxSurge | 1 | Maximum extra pods during a rolling update |
controller.config | Embedded development HCL | Boundary controller HCL stored in a ConfigMap and mounted into the controller container and hook Jobs. The default uses inline AEAD keys that you must replace with a production KMS provider. |
The default controller.config includes disable_mlock = true. The chart's default security model drops all Linux capabilities and disallows privilege escalation. We do not recommend changing this value.
Listener Service values
The chart creates separate Services for the API, cluster, and ops listeners.
API Service values
| Key | Default | Description |
|---|---|---|
controller.service.api.type | LoadBalancer | Service type for Boundary API traffic |
controller.service.api.port | 9200 | Service port for API traffic |
controller.service.api.targetPort | 9200 | Container port targeted by the API Service. Must match the API listener in controller.config. |
controller.service.api.annotations | {} | Annotations added to the API Service |
Cluster Service values
| Key | Default | Description |
|---|---|---|
controller.service.cluster.type | ClusterIP | Service type for worker registration and controller cluster traffic |
controller.service.cluster.port | 9201 | Service port for cluster traffic |
controller.service.cluster.targetPort | 9201 | Container port targeted by the cluster Service. Must match the cluster listener in controller.config. |
controller.service.cluster.annotations | {} | Annotations added to the cluster Service |
Ops Service values
| Key | Default | Description |
|---|---|---|
controller.service.ops.type | ClusterIP | Service type for health and metrics traffic |
controller.service.ops.port | 9203 | Service port for the operations endpoint |
controller.service.ops.targetPort | 9203 | Container port targeted by the ops Service. Must match the ops listener in controller.config |
controller.service.ops.annotations | {} | Annotations added to the ops Service |
Keep the ops Service internal unless a trusted monitoring path requires a different exposure model.
Probe values
The chart always renders HTTP GET liveness and readiness probes for /health on the named ops container port. The chart derives the scheme from tls.ops.disabled: HTTPS when false and HTTP when true. The probe scheme is not exposed as a value. The probes are not conditional on parsing an operations listener from HCL.
| Key | Default | Description |
|---|---|---|
controller.livenessProbe.initialDelaySeconds | 60 | Initial liveness probe delay |
controller.livenessProbe.periodSeconds | 10 | Liveness probe period |
controller.livenessProbe.failureThreshold | 3 | Liveness probe failure threshold |
controller.livenessProbe.timeoutSeconds | 5 | Liveness probe timeout |
controller.readinessProbe.initialDelaySeconds | 15 | Initial readiness probe delay |
controller.readinessProbe.periodSeconds | 10 | Readiness probe period |
controller.readinessProbe.failureThreshold | 3 | Readiness probe failure threshold |
controller.readinessProbe.timeoutSeconds | 5 | Readiness probe timeout |
Resource values
| Key | Default | Description |
|---|---|---|
controller.resources.requests.cpu | 250m | CPU request for the controller container |
controller.resources.requests.memory | 512Mi | Memory request for the controller container |
controller.resources.limits.cpu | 500m | CPU limit for the controller container |
controller.resources.limits.memory | 1Gi | Memory limit for the controller container |
Tune resource values for your expected API load, worker volume, session coordination, and audit event volume.
Database job values
The chart uses hook Jobs for database initialization, migration, and optional repair.
| Key | Default | Description |
|---|---|---|
database.init.enabled | true | Runs the pre-install database initialization Job |
database.migrate.enabled | false | Runs the pre-upgrade database migration Job |
database.repair.version | "" | When set with database.migrate.enabled=true, also runs a pre-upgrade repair migration Job for the specified version |
database.resources.requests.cpu | 100m | CPU request for database Jobs |
database.resources.requests.memory | 128Mi | Memory request for database Jobs |
database.resources.limits.cpu | 500m | CPU limit for database Jobs |
database.resources.limits.memory | 512Mi | Memory limit for database Jobs |
The initialization Job runs only on install and is enabled by default. Disable it when another workflow manages database initialization. Migration and repair are pre-upgrade hooks. Enabling migration requires controller.replicas=0. Setting a repair version requires you to enable migration. When you set both values, Helm runs repair first at hook weight -10 and migration at hook weight -5.
Bootstrap admin values
The bootstrap admin Job creates or updates a global password auth method, user, account, and role using Boundary recovery privileges.
| Key | Default | Description |
|---|---|---|
bootstrapAdmin.enabled | true | Runs the bootstrap admin Job after install |
bootstrapAdmin.runOnUpgrade | false | Also runs the bootstrap admin Job after upgrades when true |
bootstrapAdmin.waitTimeoutSeconds | 120 | Maximum time the bootstrap Job waits for the controller API to become reachable |
bootstrapAdmin.authMethodName | bootstrap-auth-method | Name of the password auth method created or reused by the Job |
bootstrapAdmin.userResourceName | bootstrap-admin | Boundary user resource name created or reused by the Job |
bootstrapAdmin.accountResourceName | bootstrap-admin | Boundary account resource name created or reused by the Job |
bootstrapAdmin.roleName | bootstrap-global-admin | Boundary role name created or reused by the Job |
bootstrapAdmin.resources.requests.cpu | 100m | CPU request for the bootstrap Job |
bootstrapAdmin.resources.requests.memory | 128Mi | Memory request for the bootstrap Job |
bootstrapAdmin.resources.limits.cpu | 500m | CPU limit for the bootstrap Job |
bootstrapAdmin.resources.limits.memory | 512Mi | Memory limit for the bootstrap Job |
Disable this Job if you already manage Boundary auth methods and admin principals outside the chart.
Extra environment variables
| Key | Default | Description |
|---|---|---|
extraEnv | [] | Additional environment variables injected into controller and hook Job containers. Supports any valid env entry. |
Extra volume and manifest values
| Key | Default | Description |
|---|---|---|
extraVolumes | [] | Additional volumes added to the controller Deployment pod. The chart does not add them to hook Jobs. |
extraVolumeMounts | [] | Additional volume mounts added to the controller container. Each mount must reference a volume available to the controller pod. The chart does not add them to hook Jobs. |
extraManifests | [] | Additional manifests rendered with Helm's tpl function. Accepts a list or map whose entries are YAML objects or YAML strings. |
The chart renders each supported extraManifests entry as a separate YAML document. Helm applies these resources as part of the release, but the chart does not otherwise validate or modify them.
Security context values
The default security settings run the controller without elevated privileges.
| Key | Default |
|---|---|
podSecurityContext.runAsNonRoot | true |
podSecurityContext.runAsUser | 100 |
podSecurityContext.runAsGroup | 1000 |
podSecurityContext.fsGroup | 1000 |
podSecurityContext.fsGroupChangePolicy | OnRootMismatch |
podSecurityContext.seccompProfile.type | RuntimeDefault |
containerSecurityContext.runAsNonRoot | true |
containerSecurityContext.runAsUser | 100 |
containerSecurityContext.runAsGroup | 1000 |
containerSecurityContext.allowPrivilegeEscalation | false |
containerSecurityContext.readOnlyRootFilesystem | true |
containerSecurityContext.capabilities.drop | ALL |
containerSecurityContext.seccompProfile.type | RuntimeDefault |
The Deployment and Jobs also set SKIP_SETCAP=1, which prevents the container startup path from attempting Linux capability modification.
ServiceAccount values
| Key | Default | Description |
|---|---|---|
serviceAccount.name | "" | Existing ServiceAccount used by the Deployment and hook Jobs. When empty, the chart omits serviceAccountName and the namespace's default account is used. The chart does not create an account. |
serviceAccount.automountServiceAccountToken | false | Controls whether the pod service account token is mounted |
Availability and shutdown values
| Key | Default | Description |
|---|---|---|
podDisruptionBudget.enabled | true | Creates a PodDisruptionBudget for controller pods |
podDisruptionBudget.minAvailable | 1 | Minimum available controller pods during voluntary disruptions |
podDisruptionBudget.maxUnavailable | not set | Optional alternative to minAvailable. Use only one of the two. |
terminationGracePeriodSeconds | 15 | Termination grace period before SIGKILL. Must exceed graceful_shutdown_wait_duration in controller.config. |
Scheduling values
| Key | Default | Description |
|---|---|---|
podAnnotations | {} | Additional pod annotations |
nodeSelector | {} | Node selector constraints |
tolerations | [] | Pod tolerations |
affinity | {} | Pod affinity rules |
topologySpreadConstraints | [] | Topology spread constraints added to the controller Deployment pod specification. The chart does not add them to hook Jobs. |
OpenShift values
Set openshift.enabled=true to render OpenShift Routes, use security contexts that let a security context constraint (SCC) assign user and group IDs, and select the Red Hat certified image defaults. OpenShift mode does not change the configured Service types. The OpenShift security contexts apply to the controller Deployment and all hook Jobs.
| Key | Default | Description |
|---|---|---|
openshift.enabled | false | Enables OpenShift Routes, SCC-compatible security contexts, and Red Hat image resolution. |
The chart evaluates the remaining values under openshift only when OpenShift mode is enabled.
OpenShift image resolution
OpenShift mode changes the resolved image only when you leave the corresponding shared image value empty.
| Key | Default | OpenShift behavior |
|---|---|---|
image.repository | "" | Resolves to registry.connect.redhat.com/hashicorp/boundary-enterprise when openshift.enabled=true. An explicit value takes precedence. |
image.tag | "" | Resolves to Chart.appVersion plus -ubi, which is 1.0.2-ent-ubi in chart 0.2.0. An explicit value takes precedence. |
The Red Hat registry requires authentication. Reference a pull Secret in the shared imagePullSecrets value, or link one to the ServiceAccount used by the controller. The shared image.pullPolicy behavior does not change in OpenShift mode.
OpenShift security context values
When openshift.enabled=true, these values replace the shared podSecurityContext and containerSecurityContext on the Deployment and hook Jobs.
| Key | Default |
|---|---|
openshift.podSecurityContext.runAsNonRoot | true |
openshift.podSecurityContext.seccompProfile.type | RuntimeDefault |
openshift.containerSecurityContext.runAsNonRoot | true |
openshift.containerSecurityContext.allowPrivilegeEscalation | false |
openshift.containerSecurityContext.readOnlyRootFilesystem | true |
openshift.containerSecurityContext.capabilities.drop | ALL |
openshift.containerSecurityContext.seccompProfile.type | RuntimeDefault |
The values omit runAsUser, runAsGroup, and fsGroup so that the project's SCC can assign IDs from its allowed range. The defaults are compatible with the restricted-v2 SCC and do not require elevated privileges. Do not pin an ID unless the ServiceAccount uses an SCC that permits it.
API Route values
| Key | Default | Description |
|---|---|---|
openshift.route.api.enabled | true | Creates a Route to the API Service. |
openshift.route.api.host | "" | Sets the Route hostname. OpenShift generates one when empty. |
openshift.route.api.tls.termination | reencrypt | Sets edge, reencrypt, or passthrough termination. |
openshift.route.api.tls.insecureEdgeTerminationPolicy | Redirect | Sets Allow, Redirect, or None handling for HTTP requests. |
openshift.route.api.tls.key | "" | Sets the private key for a client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.api.tls.certificate | "" | Sets the client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.api.tls.caCertificate | "" | Sets the CA certificate chain for the client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.api.tls.destinationCACertificate | "" | Sets the CA certificate used to verify the backend for reencrypt termination. |
openshift.route.api.annotations | {} | Adds annotations to the Route. |
openshift.route.api.labels | {} | Adds labels to the Route. |
For edge termination, set tls.api.disabled=true. For reencrypt or passthrough, set tls.api.disabled=false. For reencrypt, also set destinationCACertificate to the certificate authority (CA) that issued the controller certificate. Helm rendering fails when the Route termination and listener TLS setting do not match these requirements.
The key, certificate, and caCertificate fields configure the certificate that the OpenShift router presents to API clients for edge and re-encrypt Routes. They are distinct from destinationCACertificate, which lets the router verify the controller's backend certificate for re-encrypt termination. When the client-facing fields are empty, the Route uses the ingress controller's default certificate.
Cluster Route values
| Key | Default | Description |
|---|---|---|
openshift.route.cluster.enabled | true | Creates a Route to the cluster Service. Disable it when workers do not need an external controller endpoint. |
openshift.route.cluster.host | "" | Sets the Route hostname. OpenShift generates one when empty. |
openshift.route.cluster.annotations | {} | Adds annotations to the Route. |
openshift.route.cluster.labels | {} | Adds labels to the Route. |
The chart fixes cluster Route termination to passthrough because the listener carries Boundary mutual TLS over TCP. External workers connect to the router on port 443, not the Service port 9201. Set the controller's advertised public_cluster_addr to <ROUTE_HOST>:443 when workers use this Route.
Ops Route values
| Key | Default | Description |
|---|---|---|
openshift.route.ops.enabled | true | Creates a Route to the operations Service. |
openshift.route.ops.host | "" | Sets the Route hostname. OpenShift generates one when empty. |
openshift.route.ops.tls.termination | reencrypt | Sets edge, reencrypt, or passthrough termination. |
openshift.route.ops.tls.insecureEdgeTerminationPolicy | Redirect | Sets handling for insecure HTTP requests. |
openshift.route.ops.tls.key | "" | Sets the private key for a client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.ops.tls.certificate | "" | Sets the client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.ops.tls.caCertificate | "" | Sets the CA certificate chain for the client-facing Route certificate. Omitted for passthrough termination. |
openshift.route.ops.tls.destinationCACertificate | "" | Sets the CA certificate used to verify the backend for reencrypt termination. |
openshift.route.ops.annotations | {} | Adds annotations to the Route. |
openshift.route.ops.labels | {} | Adds labels to the Route. |
For edge termination, set tls.ops.disabled=true. For reencrypt or passthrough, set tls.ops.disabled=false. Helm rendering fails when the Route termination and listener TLS setting do not match these requirements. Avoid exposing health and metrics endpoints unless a trusted monitoring path requires the Route.
The ops key, certificate, and caCertificate fields have the same client-facing behavior as their API Route counterparts. The chart omits them for passthrough termination because the router does not terminate the client TLS connection. For reencrypt termination, destinationCACertificate verifies the operations listener's backend certificate.
Service type caveat
Routes add ingress paths to Services. The Routes do not replace Services or change their types. The API Service remains LoadBalancer by default even when you enable the API Route. Set controller.service.api.type=ClusterIP when you want the Route to be the only external API path. The cluster and operations Services default to ClusterIP.
Configuration alignment checklist
Before installing or upgrading a controller, confirm that:
- The API listener port in
controller.configmatchescontroller.service.api.targetPort. - The cluster listener port in
controller.configmatchescontroller.service.cluster.targetPort. - The ops listener port in
controller.configmatchescontroller.service.ops.targetPort. - The
public_cluster_addrsetting matches the endpoint workers can actually reach. - Each listener's
tls_disablesetting matchestls.api.disabledortls.ops.disabled, and enabled listeners use certificate paths undertls.mountPath. - The probe scheme derived from
tls.ops.disabledmatches the operations listener. - The referenced Secret contains every key required by the current
controller.configand bootstrap settings. - The
terminationGracePeriodSecondssetting exceedsgraceful_shutdown_wait_durationin the controller HCL.
On OpenShift, also confirm the following settings:
- Set
openshift.enabled=true. - Decide whether each Route is required, and set exposed Services to
ClusterIPunless you also want their configured external Service path. - Use
<CLUSTER_ROUTE_HOST>:443aspublic_cluster_addrfor workers that connect through the cluster Route. - Align API and operations listener TLS with each Route termination mode and provide destination CA certificates for
reencryptRoutes. - Confirm that the ServiceAccount can pull the Red Hat image and that its SCC admits the OpenShift security contexts.
- Check project
ResourceQuotaandLimitRangepolicies for the Deployment and hook Jobs.
Troubleshooting
Controller pods fail readiness or liveness probes
If controller pods fail readiness or liveness probes after you change TLS settings, confirm that the operations listener exists on controller.service.ops.targetPort. Also confirm that its TLS setting matches tls.ops.disabled. Both probe schemes derive from tls.ops.disabled.
Controller pods fail admission
An unable to validate against any security context constraint error means the pod requests settings that no SCC allows. Confirm that openshift.enabled=true, remove pinned runAsUser, runAsGroup, and fsGroup values, and verify the SCC assigned to the controller ServiceAccount.
Controller image pulls fail
Confirm that the pull Secret contains credentials for registry.connect.redhat.com and is present in imagePullSecrets or linked to the controller ServiceAccount. An explicit image.repository or image.tag overrides the Red Hat defaults.
Routes return TLS errors
Confirm that listener TLS matches the Route termination mode. For reencrypt, verify that destinationCACertificate contains the CA that issued the backend certificate. Inspect the Route with oc describe route ROUTE_NAME --namespace PROJECT_NAME.
Workers cannot register through the cluster Route
Confirm that the cluster Route is enabled, uses its fixed passthrough termination, and is reachable on port 443. Set public_cluster_addr to the Route hostname and port 443.
More information
To view example controller configurations, refer to Controller OpenShift Helm chart examples.
To install a controller using these values, refer to Deploy controllers on OpenShift using a Helm chart.