feat: Implement new bazel rules for building SEV recovery GuestOS images#10571
feat: Implement new bazel rules for building SEV recovery GuestOS images#10571frankdavid wants to merge 5 commits into
Conversation
Introduces the build infrastructure for SEV recovery GuestOS images. These
images are recovery images whose measured boot components (kernel, initrd, OVMF,
boot args) are taken from a previously released GuestOS version and whose
launch measurements are verified against an NNS-signed
`BlessAlternativeGuestOsVersion` proposal at build time. The signed proposal
is embedded in the boot partition (and later verified at boot time).
## Build usage
```bash
ALTERNATIVE_GUESTOS_BASE_VERSION=<commit> \
ALTERNATIVE_GUESTOS_PROPOSAL_ID=<proposal_id> \
bazel build //ic-os/guestos/envs/sev-recovery:update-img.tar.zst
```
## Changes
### New crates
- **`rs/ic_os/alternative_guestos`** — Extracts the existing proposal
verification logic (`read_and_verify_signed_bless_alternative_guest_os_version_proposal`)
out of `open_rootfs` into a reusable library. The `nns_public_key_override`
parameter is now always present (previously conditionally compiled), with
`None` passed in production builds so the hardcoded NNS public key is used.
- **`rs/ic_os/build_tools/alternative_guestos`** — A build tool
(`alternative_guestos_proposal_tool`) with two subcommands:
- `download-signed-proposal`: fetches a certified `get_proposal_info`
response from the NNS governance canister via ic-agent and stores the
CBOR certificate to disk, verifying it immediately.
- `validate-measurements`: checks that locally generated launch
measurements overlap with the measurements blessed in the proposal.
### Bazel build rules (`ic-os/alternative_guestos.bzl`)
- `download_alternative_guestos_proposal` — downloads and verifies a signed
proposal, driven by the `ALTERNATIVE_GUESTOS_PROPOSAL_ID` env var.
- `prepare_alternative_guestos_base_bootfs_tree_tar` — downloads a released
GuestOS update image, extracts its boot partition via fuse2fs, and produces
a tarball of the boot file tree. Driven by `ALTERNATIVE_GUESTOS_BASE_VERSION`.
- `validate_launch_measurements_match` — runs the measurement-overlap check
against the downloaded proposal.
### Build wiring (`ic-os/defs.bzl`)
- Adds a `build_alternative_guestos_image` flag to `icos_build`. When enabled,
the boot partition is built from the downloaded base bootfs tree (plus the
embedded proposal), the boot args are reused from the base release, and the
launch measurements are validated against the proposal.
- Refactors boot partition file extraction (`extract_boot_partition_files`)
to extract initrd, vmlinuz, OVMF, and boot args directly from the built boot
partition image via `debugfs`, so launch measurements reflect the actual
partition contents.
|
✅ No security or compliance issues detected. Reviewed everything up to 3656d95. Security Overview
Detected Code Changes
|
There was a problem hiding this comment.
Pull request overview
Introduces build-time support for “alternative GuestOS” (SEV recovery) images whose boot components and blessed launch measurements are pinned to a previously released GuestOS version and verified against an NNS-signed BlessAlternativeGuestOsVersion proposal that gets embedded into the boot partition.
Changes:
- Adds a reusable Rust library (
rs/ic_os/alternative_guestos) plus a build tool (rs/ic_os/build_tools/alternative_guestos) to download/verify proposals and validate launch-measurement overlap. - Wires new Bazel/Starlark rules to (a) download the signed proposal and (b) build a recovery image boot partition from a released GuestOS bootfs tree, then validate generated measurements during the build.
- Refactors SEV measurement inputs to be extracted from the built boot partition image (boot args/initrd/kernel/OVMF) to better reflect real partition contents.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| rs/ic_os/open_rootfs/src/recovery.rs | Switches proposal verification callsite to the new alternative_guestos library and standardizes the public-key override parameter handling. |
| rs/ic_os/open_rootfs/src/main.rs | Removes the now-redundant local proposal module from the binary crate. |
| rs/ic_os/open_rootfs/Cargo.toml | Adds a path dependency on the new alternative_guestos crate. |
| rs/ic_os/open_rootfs/BUILD.bazel | Adds Bazel dep on //rs/ic_os/alternative_guestos for open_rootfs binaries/tests. |
| rs/ic_os/config/tool/src/guestos/bootstrap_ic_node.rs | Minor import gating cleanup related to GuestOS bootstrap tooling. |
| rs/ic_os/build_tools/alternative_guestos/src/proposal_build.rs | Implements measurement-overlap validation logic with unit tests. |
| rs/ic_os/build_tools/alternative_guestos/src/main.rs | Adds a CLI tool with download-signed-proposal and validate-measurements subcommands. |
| rs/ic_os/build_tools/alternative_guestos/src/download.rs | Implements NNS-governance certified proposal download + immediate verification. |
| rs/ic_os/build_tools/alternative_guestos/Cargo.toml | Defines the new build tool crate and its dependencies. |
| rs/ic_os/build_tools/alternative_guestos/BUILD.bazel | Adds Bazel targets for the new Rust build tool. |
| rs/ic_os/alternative_guestos/src/proposal.rs | Makes the NNS public key override parameter consistently available and verifies certified proposal replies. |
| rs/ic_os/alternative_guestos/src/lib.rs | Exposes the proposal verification module as a library API. |
| rs/ic_os/alternative_guestos/Cargo.toml | Defines the new alternative_guestos library crate and dependencies. |
| rs/ic_os/alternative_guestos/BUILD.bazel | Adds Bazel rust_library target for the new crate. |
| ic-os/guestos/envs/sev-recovery/BUILD.bazel | Adds a new SEV recovery GuestOS Bazel environment target wiring build_alternative_guestos_image = True. |
| ic-os/defs.bzl | Adds alternative-GuestOS build flag and integrates proposal download, base bootfs extraction, and in-rule measurement validation. |
| ic-os/alternative_guestos.bzl | Adds Starlark rule/macro to download proposals and to prepare the released bootfs tree tarball. |
| Cargo.toml | Registers the two new Rust workspace members. |
| Cargo.lock | Locks dependencies for the new crates. |
| bazel/workspace_status.sh | Exposes ALTERNATIVE_GUESTOS_* env vars as stable workspace status vars for Bazel actions. |
| bazel/BUILD.bazel | Adds stable-status file targets for proposal ID and base version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }} | ||
| trap cleanup EXIT | ||
|
|
||
| curl --fail --silent --show-error --location \ |
There was a problem hiding this comment.
we should definitely not be downloading via curl inside a build. Can you turn this into an http_file or similar?
| proposal_id="$(cat {proposal_id_file})" | ||
|
|
||
| if [[ -z "$proposal_id" ]]; then | ||
| echo "//{package}:{name} requires ALTERNATIVE_GUESTOS_PROPOSAL_ID to be set in the environment before invoking Bazel." >&2 |
There was a problem hiding this comment.
My instincts say this is probably not the right way to do it. In practice, when will this be built? And can the targets still be built on a clean checkout with e.g. bazel build //...? Otherwise it's probably best to run this as a bazel run
There was a problem hiding this comment.
nit: lots of new code in this directory, would be good to have a README or a few top-level comments explaining what this is for. Also, what's the difference between rs/ic_os/alternative_guestos and rs/ic_os/build_tools/alternative_guestos?
Introduces the build infrastructure for SEV recovery GuestOS images. These images are recovery images whose measured boot components (kernel, initrd, OVMF, boot args) are taken from a previously released GuestOS version and whose launch measurements are verified against an NNS-signed
BlessAlternativeGuestOsVersionproposal at build time. The signed proposal is embedded in the boot partition (and later verified at boot time).Build usage
Changes
New crates
rs/ic_os/alternative_guestos— Extracts the existing proposalverification logic (
read_and_verify_signed_bless_alternative_guest_os_version_proposal)out of
open_rootfsinto a reusable library. Thenns_public_key_overrideparameter is now always present (previously conditionally compiled), with
Nonepassed in production builds so the hardcoded NNS public key is used.rs/ic_os/build_tools/alternative_guestos— A build tool(
alternative_guestos_proposal_tool) with two subcommands:download-signed-proposal: fetches a certifiedget_proposal_inforesponse from the NNS governance canister via ic-agent and stores the
CBOR certificate to disk, verifying it immediately.
validate-measurements: checks that locally generated launchmeasurements overlap with the measurements blessed in the proposal.
Bazel build rules (
ic-os/alternative_guestos.bzl)download_alternative_guestos_proposal— downloads and verifies a signedproposal, driven by the
ALTERNATIVE_GUESTOS_PROPOSAL_IDenv var.prepare_alternative_guestos_base_bootfs_tree_tar— downloads a releasedGuestOS update image, extracts its boot partition via fuse2fs, and produces
a tarball of the boot file tree. Driven by
ALTERNATIVE_GUESTOS_BASE_VERSION.validate_launch_measurements_match— runs the measurement-overlap checkagainst the downloaded proposal.
Build wiring (
ic-os/defs.bzl)build_alternative_guestos_imageflag toicos_build. When enabled,the boot partition is built from the downloaded base bootfs tree (plus the
embedded proposal), the boot args are reused from the base release, and the
launch measurements are validated against the proposal.
extract_boot_partition_files)to extract initrd, vmlinuz, OVMF, and boot args directly from the built boot
partition image via
debugfs, so launch measurements reflect the actualpartition contents.