# ADR-0005: WireGuard beneath SSH for the mesh transport ## Status Accepted (2026-07-08) ## Context Peer bulk sync and SQL-over-SSH ([ADR-0004](ADR-0004-sql-over-ssh-contract.md)) need an encrypted, authenticated channel across an ad-hoc radio mesh. SSH alone would work at the application layer, but it leaves the drones' listening surface (sshd, any other service port) exposed on the raw mesh network, and it gives no cheap, uniform way to authenticate *the peer* before the application handshake. ## Options | Option | Pros | Cons | | --- | --- | --- | | A — SSH only | One daemon, familiar | Service ports exposed on the raw mesh; per-service auth; no network-layer peer identity | | B — WireGuard tunnel, SSH inside it | Network-layer peer auth via static keys; only the WG port is exposed; SSH speaks over a private, encrypted subnet | Two layers to provision | ## Decision Run **WireGuard as the network layer** and **SSH on top of it**. WireGuard authenticates peers by pre-shared static public keys and presents a private encrypted subnet; SSH forced commands then carry the SQL and bulk-sync contract over that subnet. Keys are issued **per device before deployment** — nothing joins the mesh at runtime (design principle 5). ## Consequences - The only thing exposed on the raw radio is the WireGuard port; sshd and the data services listen only on the WG interface. - Peer identity is established once, at the network layer, and reused by every application above it. - Provisioning must place both WG and SSH keys during host prep — handled by `infra/ansible/drone-provision.yml` ([ADR-0006](ADR-0006-iac-boundaries.md)). - Rationale and the "why not SSH alone" argument live in [`../05-network-security.md`](../05-network-security.md).