stage1: split config-gen into a deploy tool; extract shared metadata + ed25519 libs#12
Merged
Merged
Conversation
…a + ed25519 libs The stage1 runtime binary was dual-purpose (boot on-instance AND generate deployment config via --make-config). Split config generation into a separate host-side tool so the on-instance binary carries only runtime concerns, and share the wire types + signer so "what we emit" and "what we verify" cannot drift. - crates/metadata (new): the _stage1/_stage2 wire types (UrlList, ArchConfig, StageConfig, UserData) + Verify + validate(Profile), extracted from the stage1 bin. The stage1 verifier and the deploy emitter both depend on it (one source of truth). Carries the JSON schema + the validate() test table. Profile::Stage0 is http-only; Stage1 allows https. - crates/ed25519-sign (new): the ed25519 wire primitive: sign_payload + verify + sha256_hex. Extracted from mkuki/sign.rs (mkuki re-exports it as `mkuki::sign`) with stage1's sig.rs verify folded in, so mkuki (sign), deploy (sign) and stage1 (verify) share one crate. - crates/deploy (new): `lockboot-deploy` create/validate/modify. `create` signs (or hashes) the UKI + stage2, composes mirror URL lists from repeated --base-url, and emits an upload-ready dir + a merged user-data.json carrying _stage1 + _stage2. `validate` checks a doc via the shared validate(); `modify` adds/removes mirror base URLs. - stage1 bin: slimmed to on-instance runtime only. Removed make_config*/emit_config and the --make-config* CLI; keeps --attest, --url/--file, PID1 boot, admission, measurement. Uses the metadata + ed25519-sign crates. Runtime behavior unchanged. - Makefile: exclude the host-only deploy tool from the payload-target cross-build. Repos stay fully separate: stage0 keeps its own config.rs/sig.rs (minimal root-of-trust audit surface); the shared crates live in the stage1 repo, consumed by its own crates. Verified: ed25519-sign (2) + metadata (12) + deploy (3) unit tests pass; both arches compile; the full chain (stage0 -> UKI -> stage1 -> example-stage2) boots and powers off cleanly against the deploy tool's OWN signed output: both ed25519 hops + signed remote args. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two hardening fixes from the boot-path security review: - Install a panic hook that routes any panic through the same poweroff() as a returned error. As PID 1 an unhandled panic would abort into a kernel panic and skip the log-drain wait; now every failure (error or panic) converges on one shutdown path so its logs reach the serial console before power-off. - download_binary returns reqwest's owned Bytes instead of .to_vec(), and download_first/admit_from/admit_payload thread Bytes through. This drops a full-length copy of the stage2 payload (and the signature / signed-args blobs). Bytes derefs to [u8], so admission and PCR 14 measurement see identical bytes and are unchanged. Verified: full chain boots and powers off cleanly in both sha256 and ed25519 modes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Splits deployment-config generation out of the on-instance stage1 binary into a separate host-side
deploytool, and extracts the wire types + ed25519 signer into shared crates so "what we emit" and "what we verify" cannot drift. Repos stay fully separate (stage0 keeps its own config.rs/sig.rs).New crates
_stage1/_stage2wire types (UrlList, ArchConfig, StageConfig, UserData) + Verify +validate(Profile), extracted from the stage1 bin. The stage1 verifier and the deploy emitter both depend on it (one source of truth). Carries the JSON schema + the validate() test table.Profile::Stage0is http-only;Stage1allows https.mkuki/sign.rs(mkuki re-exports it asmkuki::sign) with stage1'ssig.rsverify folded in, so mkuki (sign), deploy (sign) and stage1 (verify) share one crate.lockboot-deploycreate / validate / modify.createsigns (or hashes) the UKI + stage2, composes mirror URL lists from repeated--base-url, and emits an upload-ready dir + a mergeduser-data.jsoncarrying_stage1+_stage2.validatechecks a doc via the sharedvalidate();modifyadds/removes mirror base URLs.Slimmed
make_config*/emit_configand the--make-config*CLI; keeps--attest,--url/--file, PID1 boot, admission, measurement. Uses the metadata + ed25519-sign crates. Runtime behavior unchanged.Verification
create-> signed 2-mirror_stage1+_stage2+ signed args;validateclean;modifyadd/remove mirrors.Note:
deploy validateuses the authoritative Rustvalidate(). Wiring thejsonschemacrate + a combined user-data schema + fixtures (to machine-check the shipped JSON schema) is left as a small follow-up.Depends on nothing; the sibling stage0 fallback-URL change (lockboot/stage0#1) already merged.
Generated with Claude Code