From: colbyt <colby@colbyt.com>
To: devel@spectrum-os.org
Subject: [RFC] Host-to-VM attestation: proving an unmodified Spectrum host
Date: Thu, 30 Jul 2026 12:20:25 -0700 [thread overview]
Message-ID: <20260730192028.1900831-1-colby@colbyt.com> (raw)
When reviewing the verity sub-VM series, Alyssa wrote that host-to-VM attestation "just needs some more design thought… e.g. we could prove to them that they're running on an unmodified Spectrum host." Here is my attempt at that design. It's deliberately minimal: one small host service, the same format used at each tier.
Problem
-------
A Spectrum VM today cannot distinguish (a) an unmodified Spectrum host running the dm-verity image the owner installed, from (b) a tampered host, or (c) a non-Spectrum host emulating the runtime surface. Every guarantee compartmentalization makes rests on the host, and that trust is currently implicit and unverifiable.
Once a VM can verify the host: a VM holding secrets can refuse to unlock except on an enrolled host identity; inter-VM protocols can require "both endpoints on the same attested host"; and remote parties can ask a VM to prove its execution environment before releasing data to it.
You pointed out that guest-side IPE or guest self-measurement (per the earlier review — the guest image and its hash come from the host, so measuring them in the guest adds nothing against the host); I will explain why that's important later (and why I implemented it that way).
The host identity Spectrum already builds is the dm-verity root hash of the running system, embedded in the UKI that booted. The attestation statement is:
spectrum_roothash: active dm-verity root hash
uki_id: BLS entry name that booted
boot_generation: monotonic per activation
nonce: challenger-supplied
vm_id: the asking VM, host-assigned
signed by a host attestation key. Fields are additive; unknown fields are ignored (similar to vhost-user capability negotiation).
Who signs, and what the signature means
---------------------------------------
Tier 0 (software, day one): the key is generated at install in a
dedicated attestation service and never leaves the machine. The
signature means "a process on a host that booted *some* image, with
access to this key, says so." That is weak against a fully compromised host — stated plainly — but it already defeats (c) and makes drift visible: a rebuilt or rolled-back host produces a different roothash and the VM sees it.
Tier 1 (measured, later): where the platform has a measurement chain (TPM PCRs on UEFI machines; Apple's boot policy when tooling matures), the same key is sealed to the measured boot state, so the signature additionally means "and the boot chain that unsealed this key matches the enrolled policy." The statement format does not change — only the strength of "signed by." This is how systemd-creds sealing already works, so no new concepts.
The tier is reported inside the statement; VM policy
decides what tier it requires for which action.
Transport and channel binding
-----------------------------
The VM asks over its existing vsock control channel. vm_id is bound by the hypervisor-guaranteed peer CID, not by the guest —
the CID is the authentication, as with the existing vsock services. The challenger supplies the nonce, so statements can neither be replayed across boots nor forwarded between VMs.
What the VM does with it
------------------------
Policy stays with the owner, inside the VM: "unlock only if
spectrum_roothash is in my enrolled set" is a file in the VM's
storage. Spectrum holds mechanism, not policy.
Relationship to inter-VM capabilities
-------------------------------------
Once both endpoints of an inter-VM channel can require the same host attestation, capability grants between VMs can carry an attested-host precondition. That restates the goal of our earlier series with the host, not the guests, as the root — which I think
answers the "what does guest-side verity buy you" question: nothing
against the host; everything between peers and toward remote parties.
Implementation sketch
---------------------
1. spectrum-attestd: a small host service (same s6 + vsock pattern as existing services) that reads the active roothash and signs statements. On the order of 200 lines.
2. A guest library and CLI (spectrum-attest verify --require-roothash-file ...) usable from unlock scripts.
3. Install-time keygen. Tier 1 sealing arrives later with no format change.
We run the contract form of this downstream today and would implement the Spectrum-native form upstream-first, with a QEMU integration test in release/checks.
Open questions
--------------
1. Statement encoding: JSON, or the netstring style the existing control plane favors?
2. Should boot_generation come from the bootloader (BLS counters) or the attestation service's own store?
3. Key custody at reinstall — is "new install = new identity, VMs re-enroll" acceptable v1 semantics? (I think yes: it makes reinstalls visible, which is the point.)
next reply other threads:[~2026-07-30 19:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 19:20 colbyt [this message]
2026-07-31 17:34 ` [RFC] Host-to-VM attestation: proving an unmodified Spectrum host Alyssa Ross
2026-08-01 22:01 ` colby
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730192028.1900831-1-colby@colbyt.com \
--to=colby@colbyt.com \
--cc=devel@spectrum-os.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://spectrum-os.org/git/doc
https://spectrum-os.org/git/mktuntap
https://spectrum-os.org/git/spectrum
https://spectrum-os.org/git/ucspi-vsock
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).