Runners
Runners are machines you own that build and run your pipelines: a Mac mini in the office, a build server in your rack, a spare laptop. Instead of waiting on shared platform capacity, your pushes build on your own hardware — and your git credentials are never copied to it.
The Runners page in the console shows every machine connected to your org and lets you manage the codes that connect new ones.
Deploy modes
Every app has a deploy_mode — platform,
artifact, or self — that decides how
much of its pipeline runs on your hardware. It's set per app, at
creation or later through the app settings:
| Mode | Who builds | Who hosts |
|---|---|---|
platform (default) | Kapable | Kapable — your app is live at {app}.{org}.kapable.run. |
artifact | Your runner | Kapable — the build artifact uploads over a single-use token and the platform deploys it. |
self | Your runner | Your infrastructure — the runner builds, then launches the app in an Incus container on its own machine; Kapable does not host the running app. |
In self mode, secrets you file in
Secrets under the
app:NAME scope are merged into the app's environment when
its build is assigned to the runner. Receipts list secret
names only, not values; on a name collision, your value wins.
Self-deploy requires the incus capability chip —
see the runner card below; capability
matching selects an eligible runner automatically.
Builds without credentials
Org runners hold no git credentials. The platform
fetches your source server-side and gives the runner a single-use
download token bound to one (org, repository, commit). The token is
the whole address — the request itself carries no org,
repository, or commit — and it is revoked when the task ends;
it cannot authorize any other. This works from anywhere: a runner in
your office or your own cloud makes outbound HTTPS connections
to runner.kapable.ai only — no inbound
ports, no VPN, no platform-network access.
The runner card
Each connected machine appears as a card:
| Signal | Meaning |
|---|---|
| online (green) | Heartbeating now. Ready to pick up work. |
| stale (amber) | No heartbeat for 90+ seconds. The machine may be asleep, offline, or the runner stopped. |
| offline (red) | Gone quiet for long enough that the platform stopped offering it work. |
Shield chip (e.g. container) | The isolation tier: work runs inside a sandbox of that kind. |
| UNSANDBOXED (amber badge) | This runner executes work directly on the host with no sandbox. The badge is always visible by design — you should always know which machines run unprotected. |
| Capability chips | What the machine can build: rust, node, bun, os:macos, arch:arm64, and so on. Pipelines are matched to runners by these. |
| Version | The runner software version, when the runner advertises it. |
| Tasks | Active work / the runner's concurrency limit. |
Every org member can see the runners page; connecting and revoking machines is for org owners and admins.
Enrollment codes
A machine joins your org by presenting an enrollment code — a single-use, short-lived credential you mint from the Runners page.
- Single use. One code connects exactly one machine, then it's spent.
- Short-lived. Codes expire after 5–60 minutes (you pick at mint). An expired code is worthless; mint another.
- Shown once. The raw code appears exactly one time, immediately after minting, with a copy button and a live expiry countdown. It cannot be recovered afterward — only its fingerprint is stored.
- Revocable. A live code you no longer want can be revoked from the list. Used, expired, and revoked codes stay visible as history.
Give each code a label (office-mac-mini) so the history
stays legible.
Connecting a machine
-
Mint a code on the Runners page. Copy it — you won't see it again.
-
Install and connect the machine — one command. On the machine you're connecting (Linux or macOS on Apple Silicon), run the installer with your code — read it first at
https://runner.kapable.ai/install.shif you like. It downloads the runner, verifies its checksum, installs it to~/.local/bin, and trades the code for the machine's own private credential. Pick a--nameyou'll recognise on the Runners page:curl -fsSL https://runner.kapable.ai/install.sh | sh -s -- --code <your code> --name office-mac-miniThe binary lands in
~/.local/bin— if your shell doesn't have that onPATH, add it, or call~/.local/bin/kapable-runnerdirectly below. -
Start it working:
kapable-runner pull --foreman-url https://runner.kapable.ai --name office-mac-miniFor now
pullruns in the foreground — keep it alive undertmux, a systemd user unit, orlaunchd. A reboot-surviving background service is coming soon.
The machine appears on the Runners page, online, usually within seconds. Linux (x86-64) and macOS (Apple Silicon) builds are published today; Windows and additional architectures are on the roadmap.
The enrollment code itself is never stored on the machine — the runner trades it for a credential unique to that machine, which is what you later revoke.
Revoking a runner
Revoking a machine (the Revoke button on its card) immediately invalidates its credential: it stops receiving work and cannot reconnect. This is not reversible — to bring the machine back, mint a new enrollment code and connect it fresh.
Revoke when a machine is retired, lost, or you no longer trust it. Because each machine holds its own credential, revoking one never affects the others.
Security model, briefly
- Each runner holds a private, individually revocable credential; there is no shared org runner key.
- Org runners only ever receive your org's work — platform work is never scheduled onto them, and platform secrets never reach them. Runners are single-org: a machine connected to your org never builds for another.
- An unsandboxed runner is always visibly marked. If the badge makes you uncomfortable, that's the point: prefer a sandboxed tier for machines that build untrusted branches.