Host cert lifecycle: 10-year certs, no revocation, reusable VM names defeat 'recreate the VM' #77

Open
opened 2026-08-22 10:59:07 +00:00 by a73x · 0 comments
a73x commented 2026-08-22 10:59:07 +00:00 (Migrated from git.a73x.sh)

From the pre-launch security audit (finding GATE-5, ranked #3 of the outstanding set).

Risk. Guest host certificates are issued with a 10-year validity, there is no
host-cert revocation, and VM names are reusable within a tenant. Destroying a VM
therefore does not destroy its identity: a tenant who kept the guest's host key can
still authenticate as <tenant>.<name> when that name is later reused. This quietly
defeats the "recreate the VM" remediation the codebase recommends elsewhere. Proven
black-box: the production gate cert read off the wire carried a 2026→2036 window.

Blast radius. Contained within one tenant (a cert only ever carries the tenant of
its signing CA), which is why this is Medium, not higher.

Why it's deferred, not fixed. The naive fix — shorten the TTL and add renewal — was
implemented and then REVERTED. The host cert only reaches a guest via the cloud-init
seed, which is built exactly once in create() (reconcile.go, single e.Seed call
site); converge never rebuilds a seed. So a shorter TTL created a fleet-wide
verification cliff while renewal re-signed a DB row nothing reads. Now recorded as an
accepted limitation in docs/assumptions.md ("A guest keeps the host certificate it was
born with, for as long as it lives").

Real fix. A seed-rebuild / re-delivery path so converge can hand a guest a rotated
host cert without recreating the VM. Design first — this is the desired-state work the
reconcile model needs anyway. Until then: accepted risk, documented.


Migrated from git-collab issue 7250604ad2c73628af4b9433c9d33164124988e7.

Original author: a73x dev@a73x.sh.

From the pre-launch security audit (finding GATE-5, ranked #3 of the outstanding set). **Risk.** Guest host certificates are issued with a 10-year validity, there is no host-cert revocation, and VM names are reusable within a tenant. Destroying a VM therefore does not destroy its identity: a tenant who kept the guest's host key can still authenticate as `<tenant>.<name>` when that name is later reused. This quietly defeats the "recreate the VM" remediation the codebase recommends elsewhere. Proven black-box: the production gate cert read off the wire carried a 2026→2036 window. **Blast radius.** Contained within one tenant (a cert only ever carries the tenant of its signing CA), which is why this is Medium, not higher. **Why it's deferred, not fixed.** The naive fix — shorten the TTL and add renewal — was implemented and then REVERTED. The host cert only reaches a guest via the cloud-init seed, which is built exactly once in `create()` (reconcile.go, single `e.Seed` call site); converge never rebuilds a seed. So a shorter TTL created a fleet-wide verification cliff while renewal re-signed a DB row nothing reads. Now recorded as an accepted limitation in docs/assumptions.md ("A guest keeps the host certificate it was born with, for as long as it lives"). **Real fix.** A seed-rebuild / re-delivery path so converge can hand a guest a rotated host cert without recreating the VM. Design first — this is the desired-state work the reconcile model needs anyway. Until then: accepted risk, documented. --- Migrated from git-collab issue `7250604ad2c73628af4b9433c9d33164124988e7`. Original author: a73x <dev@a73x.sh>.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
a73x/eitri#77
No description provided.