Skip to main content
A build sometimes needs a service that wants a credential, such as a private package registry or a test API. A destination lets the build use it without holding the secret. The runner serves the service on a local address and forwards each request to the service’s HTTPS address. It sets the credential itself, so the secret never enters the build. List destinations in runner.build.destinations:

How the runner forwards a request

The runner drops any credential the build sends and sets the destination’s header itself. It reads the ${NAME} variables from its own environment. It refuses to start while one is unset, and so does outerlayer runner check. Under the service runner init sets up, the runner’s environment is runner.env beside the config file. Put each secret there, then restart the service, which reads the file only when it starts:
outerlayer runner check reads the Claude credential from runner.env beside the config when your shell has none. It checks no other variable in that file; see Check the host. The build’s record (outerlayer work status --json, under claims) names the destinations a build called, never a secret. A destination may point at a private address; the tunnel’s address rules do not apply to it. The local address depends on how the build runs:
  • A container or microVM build reaches the first destination in the list at http://127.0.0.1:3129/, the second at 3130, and so on.
  • A builtin:process build reaches it on a loopback port the runner chooses.
  • With your own hooks, a command run through an exec uses the same fixed ports. The hook’s relay must forward each one with --forward, as The provision hook shows. A command with no exec uses the loopback port.
The runner does not rewrite answers. A tool that follows an absolute URL in an answer leaves the local address and reaches the upstream with no credential. Set the tool to stay on the local address, such as npm’s NPM_CONFIG_REPLACE_REGISTRY_HOST=always above.

Settings for common tools

Each row is a destination with the tool’s own variable in env:

When a secret must be a variable

A destination works only when the tool can be pointed at another address. The runner does not terminate TLS for the build’s own requests. So a tool that only reaches the service’s real HTTPS address cannot use one, such as a SaaS client with the address compiled in. For that tool, name the secret in build.variables. It is then in the build’s environment, readable by everything the build runs. The build’s record names the variable, never its value.
A secret in build.variables is as exposed as it would be in a build that runs as the host’s user. Give it the narrowest credential the tool accepts.
A variable may not be both a header variable and a build.variables name.