Server certificate rotation

The server's QUIC identity is a self-signed ECDSA cert generated on first start (transport.GenerateServerCert, 2-year validity) and persisted next to the database (server.crt / server.key). Agents trust it by fingerprint pin carried in the join blob—not by CA path and not by expiry: an expired cert keeps working for already-enrolled agents. Rotation is therefore never an emergency at NotAfter; it is hygiene that bounds how long a stolen server.key stays useful.

The server logs its cert fingerprint at every startup. It warns, at startup and daily thereafter, when the cert is within 90 days of expiry (transport.CertRenewalDue).

Why rotate

Ceremony

Rotating the cert changes its fingerprint, which invalidates every agent's pin. Each agent must re-enroll to pick up the new fingerprint.

  1. Stop the server.
  2. Move the old cert+key aside: mv server.crt server.crt.old && mv server.key server.key.old (in the DB directory).
  3. Start the server—it generates and persists a fresh 2-year cert and logs the new fingerprint.
  4. For each host: mint a join token (POST /api/v1/enroll-tokens), copy the join blob, run eitri-agent join <blob> on the host, then restart the agent daemon (e.g. systemctl restart eitri-agent). join only rewrites the on-disk identity; the running daemon holds its identity in memory and keeps pinning the old fingerprint until restarted. Running VMs are untouched—they survive agent restarts by design, and the agent's reconcile state is independent of its server identity.
  5. Delete server.crt.old / server.key.old once every host has reconnected (watch GET /api/v1/hosts for online: true).

Until a host re-enrolls, its agent logs server cert pin mismatch and backs off—VMs keep running, but the host is dark to the control plane. Rotate during a window where that is acceptable, host by host.

Out of scope (future)

Related