Some networks allow outbound traffic only through an HTTP(S) proxy, and some of those proxies inspect TLS traffic and re-sign it with a private certificate authority (CA). In such a network, the Edge runner process and every step it runs need both the proxy address and the private CA.
This guide explains how to:
-
Route the runner’s own traffic through the proxy.
-
Pass the proxy settings to steps.
-
Make steps, and the runner itself, trust your private CA.
-
Configure the Docker daemon, which pulls step images on its own.
Before beginning, complete Get started with Edge Runners. For a full list of the settings used in this guide, refer to Settings reference.
|
The settings in this guide are set to |
Route the runner’s traffic through the proxy
The runner reads the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables, in upper or lower case.
All of the runner’s own traffic uses them, including polling CloudBees Unify, uploading step logs to AWS S3, and downloading updates.
-
Set the variables in the environment that starts the runner. For example, if the runner runs as a
systemdservice, add them to the unit:[Service] Environment="HTTPS_PROXY=http://proxy.example.com:3128" Environment="HTTP_PROXY=http://proxy.example.com:3128" Environment="NO_PROXY=localhost,127.0.0.1,.internal.example.com" -
If the proxy requires authentication, include the credentials in the URL, for example
http://user:password@proxy.example.com:3128. The runner logs the names of the proxy variables it passes to steps, never their values.
Pass the proxy settings to steps
By default, the runner passes its proxy settings to every step, in both native and container execution modes. This includes the system steps that CloudBees Unify adds to each job, which call the CloudBees Unify API, so no workflow changes are required.
The runner passes the following variables:
-
HTTP_PROXYandhttp_proxy -
HTTPS_PROXYandhttps_proxy -
NO_PROXYandno_proxy -
ALL_PROXYandall_proxy
Each value comes from the runner’s environment, passed under the same name as the runner has it.
To give steps a different value than the runner uses, set an override in the step_proxy block of config.yaml.
An override is passed under both the upper and lower case name.
step_proxy: https_proxy: http://proxy.example.com:3128 http_proxy: http://proxy.example.com:3128 no_proxy: localhost,127.0.0.1,.internal.example.com
A variable is not passed to a step that already has it, in either case.
This prevents a step from using two different proxies.
Proxy variables set in a workflow’s env take precedence over the runner’s for the commands in your steps.
In container mode, the passed variables take precedence over the same variables set in the step image.
To stop passing proxy settings to steps, for example when the runner needs a proxy but your steps reach their destinations directly, disable it:
step_proxy: enabled: false
|
Disable |
Use a proxy that listens on the runner host
A local proxy agent often listens on a loopback address, such as http://127.0.0.1:3128.
Container steps run on their own Docker network, where a loopback address is the container itself.
If a proxy URL points at localhost, 127.0.0.0/8, or ::1, the runner still passes it to native steps, but not to container steps.
The runner logs a warning at startup that names the variables it left out.
NO_PROXY is always passed, because it lists hosts rather than a proxy.
To make a local proxy reachable from container steps:
-
Configure the proxy to listen on the Docker bridge interface, not only on the loopback address.
-
Add an extra host that points at the Docker host, and set step proxy overrides that use it:
container_runtime: extra_hosts: - host.docker.internal:host-gateway step_proxy: http_proxy: http://host.docker.internal:3128 https_proxy: http://host.docker.internal:3128
Trust a private CA
When the trust bundle is enabled, the runner builds a single CA bundle at startup and makes every step trust it. The trust bundle is disabled by default.
Choose the contents of the bundle:
-
The host’s trusted CAs only. Use this if your private CA is already installed in the runner host’s trust store.
trust_bundle: enabled: true -
The host’s trusted CAs, plus extra CA files. Use this if your private CA is not installed on the host.
trust_bundle: enabled: true ca_files: - /etc/pki/corporate/proxy-ca.pem - /etc/pki/corporate/scm-ca.pem -
A complete bundle that you provide. The runner uses the file as-is and does not add the host’s CAs.
trust_bundle: enabled: true bundle_file: /etc/pki/corporate/ca-bundle.pem
The files must be PEM encoded and use absolute paths.
bundle_file cannot be combined with ca_files or with include_system_roots: true.
The runner stops at startup if a configured file is missing or holds anything other than valid certificates, or if the resulting bundle is empty.
It logs the subject and expiry date of each certificate in ca_files, and logs a warning for any that has expired.
The runner writes the bundle to trust/ca-bundle.pem in its working directory, and rebuilds it each time it starts.
Where the host’s trusted CAs come from
The runner reads the same files it trusts for its own connections, for example /etc/ssl/certs/ca-certificates.crt or /etc/pki/tls/certs/ca-bundle.crt.
If SSL_CERT_FILE or SSL_CERT_DIR is set for the runner, those are used instead.
How container steps trust the bundle
In container mode, the runner mounts the bundle read-only into every step container at /etc/cloudbees-runner/ca-bundle.pem.
It also mounts the bundle over the standard CA bundle files of common Linux distributions, so that tools that read only the system trust store trust it:
-
/etc/ssl/certs/ca-certificates.crt(Debian, Ubuntu, Alpine, distroless) -
/etc/pki/tls/certs/ca-bundle.crt(RHEL family) -
/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem(RHEL, Fedora, Amazon Linux) -
/etc/ssl/ca-bundle.pem(SUSE)
These mounts replace any CAs that a step image added to its own bundle.
If your images add CAs of their own, either include them in the trust bundle, or turn off the mounts with override_system_paths: false.
Environment variables for language runtimes
Several tools and language runtimes ignore the system trust store. By default, the runner points the following variables at the bundle in every step:
-
SSL_CERT_FILE -
NODE_EXTRA_CA_CERTS -
REQUESTS_CA_BUNDLE -
PIP_CERT -
CURL_CA_BUNDLE -
GIT_SSL_CAINFO -
AWS_CA_BUNDLE -
NPM_CONFIG_CAFILE
In container steps, they point at /etc/cloudbees-runner/ca-bundle.pem.
In native steps, they point at the bundle in the runner’s working directory. Native steps get no mounts.
A variable that is already set for the step is left alone.
In container mode, the variables take precedence over the same variables set in the step image.
To stop setting them, use inject_env: false.
How the runner itself trusts the bundle
If ca_files or bundle_file is set, the runner’s own connections also trust the bundle, in addition to the host’s trusted CAs.
This covers polling CloudBees Unify, uploading logs, and downloading updates and the workflow runtime.
If neither is set, the runner trusts the host’s trusted CAs, the same as it does without a trust bundle.
The delete command also uses the trust bundle, so you can remove a runner whose connection to CloudBees Unify needs your private CA.
Configure the Docker daemon
In container mode, step images are pulled by the Docker daemon, not by the runner. The daemon does not use the runner’s proxy settings or trust bundle, so configure it separately:
-
Proxy: Set the proxy for the Docker daemon, for example in a
systemddrop-in file or in theproxiessection ofdaemon.json. For more information, refer to the Docker documentation. -
Registry CA: Install your private CA in the host’s trust store and restart the Docker daemon, or add it for a single registry under
/etc/docker/certs.d/<registry-host>/ca.crt.
Limitations
-
Java: Java uses its own truststore and ignores the trust bundle and its environment variables. Import your CA into the truststore that your step uses, for example with
keytool. -
Certificate pinning: Tools that pin certificates, or that ship their own fixed set of trusted CAs, do not trust the bundle.
-
Proxy credentials in steps: Proxy URLs are passed to steps as-is, including any credentials they contain. A step that prints its environment, or writes it to a file or artifact, can expose them.
Settings reference
The settings below are set to config.yaml, in the runner’s working directory.
step_proxy
Controls the proxy variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY, ALL_PROXY, in upper and lower case) that the runner passes to steps.
| Setting | Default | Description |
|---|---|---|
|
|
Pass proxy variables to steps. Set to |
|
Empty |
The value passed to steps as |
|
Empty |
The value passed to steps as |
|
Empty |
The value passed to steps as |
|
Empty |
The value passed to steps as |
Proxy URLs that point at a loopback address are passed to native steps only, never to container steps.
trust_bundle
Controls the CA bundle that the runner builds at startup and makes every step trust.
| Setting | Default | Description |
|---|---|---|
|
|
Build the trust bundle and make steps trust it. |
|
|
Add the runner host’s trusted CAs to the bundle. Cannot be |
|
Empty |
Absolute paths of PEM files to add to the bundle. When set, the runner’s own connections also trust the bundle. |
|
Empty |
Absolute path of a complete PEM bundle to use as-is, instead of |
|
|
In container mode, also mount the bundle over the standard CA bundle files of common Linux distributions in step containers. |
|
|
Point |
The runner fails to start if a configured file cannot be read or is not valid PEM, or if the resulting bundle is empty.