Skip to content

fix(ci): build SecureBoot signed AMT installers#5

Merged
kkroo merged 1 commit into
mainfrom
secureboot-installer-compose
Jul 11, 2026
Merged

fix(ci): build SecureBoot signed AMT installers#5
kkroo merged 1 commit into
mainfrom
secureboot-installer-compose

Conversation

@kkroo

@kkroo kkroo commented Jul 11, 2026

Copy link
Copy Markdown

Summary

Fixes the deployable AMT installer compose workflow so an image tagged *-signed is actually a Talos SecureBoot installer.

Changes:

  • derive/use the matching ghcr.io/blockcast/imager:<base tag> instead of the stock Sidero imager
  • invoke secureboot-installer instead of installer
  • mount Talos SecureBoot signing material at /secureboot
  • load _out/installer-amd64-secureboot.tar
  • fail before publish if the imager log shows secureboot: false or unsigned.uki

Root Cause

The previous compose workflow overlaid the signed AMT extension with ghcr.io/siderolabs/imager:${TALOS} installer. The run log for 29136475511 showed secureboot: false and copying .../unsigned.uki, which matches the data-4 SecureBoot canary failure.

Required Secrets

This workflow now requires these repo secrets, populated from the Vault SecureBoot PKI path:

  • TALOS_SECUREBOOT_UKI_SIGNING_KEY_PEM
  • TALOS_SECUREBOOT_UKI_SIGNING_CERT_PEM
  • TALOS_SECUREBOOT_PCR_SIGNING_KEY_PEM

Validation

  • ruby -e 'require "yaml"; YAML.load_file(...)'
  • extracted compose shell with yq and ran bash -n
  • git diff --check

@kkroo kkroo merged commit f80333f into main Jul 11, 2026
1 check failed
@kkroo kkroo deleted the secureboot-installer-compose branch July 11, 2026 04:50

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.

Important Issues (1)

  • [native-codex] .github/workflows/compose-signed-installer.yml:139-148 — The new secureboot-installer path (subcommand name, /secureboot/{uki-signing-key,uki-signing-cert,pcr-signing-key}.pem mount convention, and the secureboot: true / signing systemd-boot log markers the script now hard-greps for) has never actually executed. compose-signed-installer.yml is workflow_dispatch-only, so opening this PR did not run it, and none of the workflow's last 5 runs are at this PR's head SHA (74d6523) — the only run cited in the PR body (29136475511) is the old, buggy code path. The PR's "Validation" section covers YAML parse / bash -n / git diff --check only, not a live imager invocation.
    • I checked the mount path and filenames against upstream Talos docs and they do match the imager SecureBoot profile convention (/secureboot/uki-signing-key.pem, /secureboot/uki-signing-cert.pem, /secureboot/pcr-signing-key.pem), so the design looks right. But the two literal grep -q checks (secureboot: true, signing systemd-boot) are exact-string bets on this imager build's log wording, and this is exactly the kind of signing-pipeline change where a wrong guess fails either open (falls through to publish) or closed (blocks all future signed builds) with no prior evidence either way.
    • Recommend a workflow_dispatch dry run against this branch (with the three new secrets populated) before merge, to confirm the tool accepts secureboot-installer, the log lines actually appear verbatim, and _out/installer-amd64-secureboot.tar is produced — otherwise this ships unverified into the exact signing path that caused the original SecureBoot canary failure.

Suggestions (1)

  • [pr-review-toolkit] .github/workflows/compose-signed-installer.yml:35-37,70talos_version / TALOS is no longer used anywhere in the script body now that ghcr.io/siderolabs/imager:${TALOS} was replaced by the derived $IMAGER. Either drop the now-dead input/env, or use it to sanity-check that the derived imager tag actually matches the requested Talos version.

Strengths

  • Solid secret hygiene on the new SecureBoot key handling: PEM files are written to a mktemp -d'd directory (tmpfs via /dev/shm when available) under umask 077 (mode 600), mounted :ro into the imager container, and cleaned up via an EXIT trap set before any secret material is written.
  • The added pre-flight checks (all three new secrets present, openssl pkey/openssl x509 sanity-parsing the key/cert material before use) fail closed early rather than surfacing an opaque docker run error.
  • The fail-closed grep -Eq 'secureboot: false|unsigned\.uki' guard directly encodes the root-cause signature from the cited failing run (29136475511), which is the right instinct even though it's unverified against the new code path (see Important above).

Recommended Action

  1. Run a workflow_dispatch smoke test on this branch to confirm the new imager invocation and log-marker assertions actually match reality before relying on this for production signed installers.
  2. Optionally clean up the now-unused talos_version input.

reviewed head: 74d6523

@kkroo

kkroo commented Jul 11, 2026

Copy link
Copy Markdown
Author

Addressed in #6.

Live smoke results against the real ct6 private inputs on the x86 devbox, using disposable keys and no push:

  • custom imager digest: sha256:68a01c7fcdf6fddab788ed379541fbf672982bccce4390f07a08866e14e6abe2
  • secureboot: true observed
  • signing systemd-boot observed
  • /out/installer-amd64-secureboot.tar produced at 135,628,800 bytes
  • no secureboot: false or unsigned.uki marker

The first smoke run found that Talos v1.13 rejects PKCS#8 PCR keys. #6 normalizes both RSA inputs to PKCS#1, verifies the UKI key/cert pair, removes the dead talos_version/TALOS fields, and passed a second full compose starting from PKCS#8 inputs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant