ADR-0006: Device identity key is separate from rotatable WireGuard keys
- Status: accepted
- Date: 2026-08-10
Context
The tempting simplification is to let a device's WireGuard public key be its identity. One key, one row, no indirection.
It makes key rotation impossible without re-enrolment. Rotating a WireGuard key would change the device's identity, so every reference — audit history, ACL tags, DNS records, route advertiser rows, assignment history — would have to be rewritten or would silently point at a device that no longer exists. In practice products that do this simply never rotate, which is a poor answer for a key that lives on a laptop for three years.
It also interacts badly with multi-network membership (ADR-0004), where a device deliberately holds a different WireGuard key per network.
Decision
Two kinds of key:
- Device identity: a long-lived Ed25519 keypair generated at enrolment.
devices.identity_public_keyis unique and is what the device authenticates the control channel with, by signing a server-issued challenge. It is the device's stable name for its whole life. - WireGuard keys: one per network membership, in
wireguard_keys, rotatable. Rotation creates a newcurrentkey while the previous one moves toretiringfor an overlap window so peers accept both, then toretired.
Enrolment proof is therefore concrete: the device generates its identity keypair
locally, and proves possession by signing the challenge in ClientHello. The
enrolment token authorises; the signature authenticates. Neither private key ever
leaves the device.
Consequences
WireGuard keys become routine to rotate, which we will want for scheduled hygiene and need for incident response. A device's history stays intact across rotations. Per-membership keys mean customer networks cannot correlate a shared device.
The cost is a second key to generate, store and protect, and an overlap window
during which two public keys are valid for one membership — which the peer
distribution logic and the wireguard_keys_one_current invariant have to handle
carefully. Rotation is a distributed operation: it is not complete until every
peer that needs the new key has applied it, so it is driven by the same
version-and-ack machinery as everything else rather than by a timer.
Alternatives considered
WireGuard key as identity. Simplest. Rejected: it trades away key rotation permanently, which is not a trade worth making for one saved column.
Certificate-based device identity (an internal PKI). More standard, and a better story for enterprises later. Rejected for v1 as a large amount of machinery — issuance, renewal, revocation lists, trust distribution — to solve a problem one Ed25519 key already solves.
Rendered from docs/adr/0006-identity-key-separate-from-wireguard-key.md, which is where it is edited.