url | none | Gateway base URL. Set by login, or by login --url with a piped key. With no --url and no OUTERLAYER_URL, a cloud command refuses without it. |
apiKey | none | The factory key, set by a piped login. It wins over accountToken. Never printed back. |
appId | none | The factory id of a factory key, set by login --app-id. With an account login instead of a factory key, commands ignore it and use the factory the repository is connected to (outerlayer connect). |
accountToken | none | Your account’s login token, used only when no factory key is set. Never printed back. logout removes it. |
dashboard | none | The dashboard login signed in to, so logout can revoke the token there. |
autoSync | true once the file exists | Whether the hooks run sync --quiet in the background and the daemon streams launched sessions. false leaves every upload to you. |
tier | "full" | Capture tier for a sync without --tier: metrics, redacted or full. |
repos | none | Which repositories may sync, and which the runner takes work in. Patterns match the host-qualified remote, such as github.com/acme/app. * matches anything, and matching ignores case. exclude wins over include. With include set, a session with no remote is skipped. A Linear or Jira item matches by the repository it was added with (work build --repo). One added without a repository matches no pattern. An excluded session is skipped for good; loosen the filter, then run sync --all to pick it up. |
scrub | none | Extra scrubbers on top of the built-in secret patterns. literals are exact strings. patterns are regular expressions, each with an optional label shown in the redaction marker. |
runnerVm | none | Written by outerlayer runner init --vm on a Mac. instance is the Lima VM the runner lives in; since is when it was made. While set, doctor reports the VM and runner init --vm refuses to make another. See Running on macOS. |
runner.name | this machine’s hostname | The runner’s name, which claims are recorded under. One machine can run several runners, so two config files on one machine need distinct names, or both runners can claim the same item. The API reports the value as host. runner.host is the earlier name of this key. It still works, and outerlayer doctor warns about it. Setting both to different values is refused. |
runner.queues | both | Which of implement and amend this runner takes work from. |
runner.concurrency | 1 | Jobs running at once. A whole number of at least 1. |
runner.pollSeconds | 60 | How often the runner looks for new work. From 5 to 86400. |
runner.timeLimitMinutes | 480 | A job past this age ends timed_out. Also the ceiling on any one hook. At most 1320. |
runner.idleLimitMinutes | 30 | A job whose log stops growing for this long, using almost no CPU, ends idle. It is also how long a hook may write nothing to its own log before the runner ends it. |
runner.commands.implement / .amend | none | The command line that starts the agent for that queue. Runs through /bin/sh -c, so $OUTERLAYER_WORK expands. Required for every queue in runner.queues. |
runner.hooks.provision / .cleanup | none | Run before and after the command. Both required. Either an absolute path to an executable, with no arguments and no $HOME or ~, or the same built-in for both: builtin:container (Container builds), builtin:vm (MicroVM builds) or builtin:process (The process fallback). |
runner.hooks.report | none | Optional executable, same path rule, run when a job starts and ends. It cannot be a built-in. |
runner.autoUpdate | true when both hooks are built-in, false when you supply your own | Whether the runner updates itself to the CLI version its gateway names. It installs each version under <config dir>/runner/versions/<version>/. A version that fails its checks is rolled back to the previous one. A runner with no install layout cannot update itself until you run outerlayer runner install. See Keep the runner up to date. |
runner.update.maxWaitHours | 6 | How long an update may wait for builds that do not carry on through a restart while the runner keeps taking work. After that the runner claims nothing until it has updated. 0 holds work as soon as an update is pending. A negative or non-numeric value is refused. A service runner whose builds all carry on through a restart does not wait. See When the runner holds work for an update. |
runner.build.memory | 8g | Container memory limit, with no swap. A microVM build gets this much memory. A number with an optional k, m or g, such as 8g or 1.5g. Also the provision hook’s OUTERLAYER_MEMORY, and the limit of the runner’s own image builder. |
runner.build.cpus | 4 | Container CPU limit, above 0. A container build also sees only this many cores, rounded up. A microVM build gets this many virtual CPUs, so it needs a whole number. Also OUTERLAYER_CPUS. |
runner.build.pids | 4096 | Container process limit, at least 1. A microVM build has no process limit. Also OUTERLAYER_PIDS. |
runner.build.disk | 40g | The most a container build’s volume may hold. A container build past it is released failed with disk_limit_exceeded. A microVM build’s disk is this size, and a write past it fails. Same form as memory. Also OUTERLAYER_DISK. |
runner.build.variables | [] | Container and microVM builds only. Up to 100 names of host variables passed into the build, the only way one enters it. A name the runner sets itself (OUTERLAYER_*, PATH, ANTHROPIC_BASE_URL and the like) is refused. GH_TOKEN, GITHUB_TOKEN, GH_ENTERPRISE_TOKEN and GITHUB_ENTERPRISE_TOKEN are skipped and logged. CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY are accepted, but the build gets a placeholder, never the value. |
runner.build.allowHosts | none (every public host) | The public hosts a build may reach through the tunnel. Each entry is a host name, an IP address, or *. and at least two labels, which matches names under that domain but not the domain itself. At most 500. See Limiting the hosts a build reaches. |
runner.housekeeping.jobsKeepDays | 30 | Whole days a finished build’s job directory is kept after it last changed, at least 1. An unfinished build’s directory is never removed. See Housekeeping. |
runner.housekeeping.buildCacheMax | "20g" | The most the runner’s own image builder keeps in its cache, in the same form as runner.build.memory, or "off" to leave the cache alone. |
runner.housekeeping.minFreeDisk | runner.build.disk | Free space the runner’s file system must hold for the runner to claim work, in the same form as runner.build.memory. Below it the runner claims nothing until there is room. |
runner.build.destinations | [] | Credentialed services the runner forwards a build’s requests to, with the secret kept on the host. At most 18. gateway and claude are built in and refused as names. See Destinations. |
runner.build.destinations[].name | none | 1 to 63 lower-case letters, digits and hyphens, unique. Required. |
runner.build.destinations[].upstream | none | The service’s https:// address, with no login, query or fragment. Required. |
runner.build.destinations[].header | none | Name: value, set on every forwarded request. The value may read the runner’s environment as ${NAME}. The runner refuses to start while one is unset. A name may not also be in runner.build.variables. Required. |
runner.build.destinations[].env | {} | Variables set in the build to point its tools at the destination. {local} in a value is the destination’s local address. A name the runner sets, or another destination sets, is refused. |
runner.checks.timeLimitMinutes | 10 | From 1 to 240. The longest the host checks’ environment may take to set up, and the longest one check command may run. A check past it is recorded as a fail. See Host checks. |