Transport
Remote work travels over iroh: QUIC + TLS 1.3 with mutual authentication.
What it gives you
- Dial by NodeID. No open inbound ports, no host certificates to manage.
- Mutual authentication. Both sides prove possession of their key; the transport verifies the bound endpoint id equals the NodeID, so a peer cannot present a key it does not hold.
- A relay only forwards bytes. When a self-hosted relay is configured, it never sees plaintext.
RPC and blobs
The transport carries two things:
| Kind | Used for |
|---|---|
| RPC | ping, whoami, users.*, invites.redeem, deploy.run, build.run, compose.apply, route.apply, … |
| Blob streaming | Image tarballs (image.load, a docker save stream) and build contexts (build.run, a gzipped tar with .dockerignore applied) |
| Tunnel | Raw TCP bytes to a container port (ant nest tunnel), on a separate ALPN |
A request frame is capped at 2 MiB (response frames at 8 MiB; larger payloads stream as blobs). The resolved compose file travels inside one request frame, so a compose file larger than 2 MiB fails today (see Known issues).
Tunnels
A tunnel is a raw byte pipe to a published container port on a machine,
opened on its own ALPN (ant-tunnel/1) so it never shares the framing of an
RPC. The worker resolves the requested container:port only to a loopback port
ant published for a container ant manages; a tunnel can never reach the docker
socket, Caddy's admin API, or another local listener. Tunneling needs the
deploy capability, the same trust as running a container on the machine.
Direction, usage (CLI and dashboard), limits, and troubleshooting are covered in Tunnels.
Build tags
The transport is compiled only for Linux with CGO enabled (//go:build linux && cgo); the vendored iroh library ships for amd64 and arm64. On any
other build it is stubbed out: local-first works, and ant nest ping reports
that iroh is unavailable.
CGO_ENABLED=1 go build ./... # with transport
CGO_ENABLED=0 go build ./... # local-only, transport excluded
Authorization
The transport authenticates the channel. It does not decide what a caller may do; the daemon authorizes each RPC against its roster. See Security model.