Skip to content

feat(labctl): protect Talos cidata as secret material and size dynamically#66

Merged
jmgilman merged 1 commit intomasterfrom
session-057/talos-cidata-hardening
May 3, 2026
Merged

feat(labctl): protect Talos cidata as secret material and size dynamically#66
jmgilman merged 1 commit intomasterfrom
session-057/talos-cidata-hardening

Conversation

@jmgilman
Copy link
Copy Markdown
Contributor

@jmgilman jmgilman commented May 3, 2026

Summary

Talos machine configuration embedded in NoCloud user-data carries the cluster's PKI and API credentials. Previously the cidata image landed at the platform default mode (typically 0644 / world-readable), and was hard-capped at a 16 MiB FAT32 volume regardless of payload size — a controlplane.yaml that inlined custom config or extensions would surface as an opaque diskfs failure instead of a clear error.

This is PR 2 of 5 from the session 057 plan. Independent of PR 1 (#65) — different files, can land in either order.

What changed

  • 0600 mode. nocloudcidata.Builder.Build chmods the cidata image to 0600 right after diskfs.Create, before any FAT32 content is written. Aligns with Talos's published security checklist guidance to treat machine config as root-secret material.
  • Dynamic sizing. Image size is now roundUpMiB(max(payload + 4 MiB overhead, 16 MiB)), capped at CidataMaxSize = 64 MiB. Payloads beyond the cap fail with a clear "exceeds the maximum cidata image size" error instead of a low-level diskfs failure. The 16 MiB floor preserves the working FAT32 size diskfs needs for small payloads.

Why now

Session 057's review (and Talos's own security docs) flag the machine config as the root secret of the cluster. Default file mode on a shared CI runner or laptop is 0644; that ships PKI to anyone with shell access. Fixing it before a real cluster lands is cheaper than after.

Out of scope

  • HTTP/download reliability and SHA256 verification (PR 1 feat(labctl): harden Talos image build reliability #65).
  • Schema defaults and output.dir constraint tightening (PR 3).
  • Progress reporting (PR 4).
  • Declarative extensions (PR 5).
  • Talos machine-config generation from patches + secrets bundle (deferred).

Test plan

  • go test ./internal/adapters/nocloudcidata/... — passes.
  • go test ./... from tools/labctl/ — full suite passes.
  • moon run labctl:check --summary minimal — format/lint/test pass.
  • New unit tests cover: file mode is 0600, a 32 MiB user-data payload fits (would have failed under the old 16 MiB cap), and an over-CidataMaxSize payload errors with no partial image on disk.

🤖 Generated with Claude Code

…cally

Talos machine configuration embedded in NoCloud user-data carries the
cluster's PKI and API credentials and must be protected accordingly.
Previously the cidata image landed at the platform default (typically
0644) and was hard-capped at a 16 MiB FAT32 volume regardless of
payload — a controlplane.yaml that inlined extra config or extensions
would surface a low-level diskfs failure rather than a clear error.

- nocloudcidata.Builder.Build now chmods the cidata image to 0600 right
  after diskfs.Create, before any FAT32 content is written. Aligns with
  Talos's own security checklist guidance to treat machine config as
  root-secret material.
- Image size is now derived from the payload: payload + 4 MiB FAT32
  overhead, floored at the 16 MiB working size diskfs needs, rounded up
  to the nearest MiB. Cap at 64 MiB (CidataMaxSize); payloads larger
  than that surface a clear "exceeds the maximum cidata image size"
  error instead of an opaque diskfs failure.

Tests cover the 0600 mode, a 32 MiB user-data payload that previously
would not fit in the fixed 16 MiB image, and the over-cap rejection
with no partial image left on disk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jmgilman jmgilman merged commit 1c3160a into master May 3, 2026
6 checks passed
@jmgilman jmgilman deleted the session-057/talos-cidata-hardening branch May 3, 2026 05:19
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