Skip to content

Device pools and WireGuard

A device pool is a single WireGuard subnet shared by every device in your Edgible organization. It is the private network on which gateway and serving devices find each other and exchange traffic. Workloads, even on different physical machines in different physical locations, can communicate as if they were on the same LAN.

WireGuard is a kernel-level VPN protocol with a small, deliberate design. Edgible uses it to establish point-to-point encrypted tunnels between devices in the same pool. Three properties matter for our purposes:

  1. Outbound-initiated. Each device opens connections out to its peers. Neither side needs to accept incoming connections to make the tunnel work, which is why a serving device behind a home router or a CGNAT will still happily join the mesh.
  2. Per-peer keys. Each device has its own WireGuard keypair. The public key serves as the device’s identity; only the device with the matching private key can decrypt packets aimed at it.
  3. Stable identity, mobile network. A device’s WireGuard IP stays the same even when its public IP changes. Move the machine to a different network, the tunnel re-establishes, and routes that pointed to it before still work.

You don’t manage the pool directly — the control plane does. When a new device registers in your organization:

  • The control plane assigns it a unique IP in the pool’s subnet (e.g., 10.42.7.4).
  • The device generates a WireGuard keypair locally; only the public key is uploaded.
  • The control plane pushes the new peer’s information to every other device in the pool, and pushes the existing peers’ information to the new device.
  • WireGuard configurations are reloaded on each device. Within a few seconds, the new device is reachable.

When a device is deleted, the reverse happens — the peer entries are pulled from every other device, and the IP is released back to the pool’s allocator.

Two kinds of traffic ride the WireGuard mesh:

  • Public traffic that was forwarded by a gateway. When https://api.example.com hits a managed gateway, HAProxy looks up which serving device should receive that hostname’s traffic, picks the WireGuard tunnel to that device, and writes the encrypted bytes through it. The serving device’s Caddy receives the connection on its WireGuard interface and proxies onward to the workload.
  • Device-to-device traffic between your own workloads. If application A on serving device 1 needs to call application B on serving device 2, that traffic goes directly over the mesh — peer to peer, encrypted, without traversing the gateway. (At time of writing, declarative service-discovery for this case is on the roadmap; for now you can address other devices by their pool IP.)
  • Workload-to-internet egress. When your workload makes an outbound HTTP call to a third party, it leaves the serving device through the device’s normal default route. The pool is not a transit network for general internet access.
  • Control-plane traffic. The agent’s WebSocket to the Edgible API uses the device’s normal internet connection (TCP/443), not the WireGuard mesh.

Today, an organization has exactly one device pool. Multiple isolated pools per organization are not yet a concept, so all devices in an organization can — at the network layer — see each other. Access policy enforcement happens at the application layer, in Caddy, not at the network layer in WireGuard.

If you need hard isolation between two sets of devices, the right boundary today is a separate Edgible organization.