Skip to content

feat(security): provide shared runsc provisioning for Bluefin-family hosts - #1039

Open
joshyorko wants to merge 2 commits into
projectbluefin:mainfrom
joshyorko:feat/shared-runsc-provisioning
Open

feat(security): provide shared runsc provisioning for Bluefin-family hosts#1039
joshyorko wants to merge 2 commits into
projectbluefin:mainfrom
joshyorko:feat/shared-runsc-provisioning

Conversation

@joshyorko

@joshyorko joshyorko commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • re-home the reviewed runsc provisioner into Common's shared Bluefin-family overlay
  • expose ujust runsc install, ujust runsc update, and ujust runsc remove from Common's canonical shared recipe
  • preserve the pinned release, architecture/digest checks, archive allowlist, ownership protection, atomic lifecycle, and no-runtime-fallback contract from Bluefin #1142

Closes #1038
Refs projectbluefin/bluefin#1139
Supersedes the implementation location in projectbluefin/bluefin#1142
Consumer contract: projectbluefin/review#348 and merged #349
Future consumer: projectbluefin/review#362

Why Common

Common owns reusable host infrastructure in system_files/shared/, which is
distributed through the Bluefin-family image composition path. Bluefin consumes
Common's image and copies its shared overlay into the resulting image. The
runsc capability is not GNOME-specific or image-specific.

Validation

  • just check
  • shellcheck -S warning system_files/shared/usr/libexec/bluefin-runsc
  • npx --yes bats tests/test_runsc_provisioning.bats — 13/13
  • affected Python tests with ephemeral pytest/jsonschema dependencies — 109 passed
  • ephemeral uv run ... pre-commit run --all-files — passed
  • git diff --check
  • Bluefin composition source proof: Common is consumed as COMMON_IMAGE, and
    Bluefin copies Common's shared overlay; old Bluefin-local helper and
    60-custom.just are absent from testing

The host's broad BATS sweep has unrelated existing setup/changelog/update
failures; all 13 transferred runsc cases pass. No local image build or native
runtime proof is claimed.

Native acceptance boundary

After a capable Bluefin Testing image consumes this Common layer, native
acceptance must separately prove ujust runsc install, runsc --version,
rootless podman --runtime=runsc, OCIRuntime=runsc, ordinary networking,
install/update/remove lifecycle, no ignore-cgroups=true, no host networking,
the real Review fail-closed path, and separate arm64 evidence. This PR does
not close Bluefin #1139 or Review #348.

Move the reviewed runsc host provisioner into Common shared infrastructure for Bluefin-family consumers.

Closes projectbluefin#1038

Refs projectbluefin/bluefin#1139 and #1142

Assisted-by: GPT-5 via GitHub Copilot

Co-authored-by: Copilot <223556219@users.noreply.github.com>
Assisted-by: GPT-5 via GitHub Copilot

Co-authored-by: Copilot <223556219@users.noreply.github.com>
@joshyorko
joshyorko marked this pull request as ready for review August 29, 2026 02:00

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Read the full bluefin-runsc helper (253 lines) and the 301-line bats suite, not just the summary. This is a genuinely careful implementation for a security-sensitive, sudo-invoked installer:

  • Supply chain: per-arch pinned SHA256, HTTPS-only + TLS1.2+ + --proto '=https', hash verified before tar -tjf ever parses the archive, then an explicit member allowlist checked before extraction (runsc, gvisor-bin/*, containerd-shim-runsc-v1 — anything else aborts). Extraction uses --no-same-owner --no-same-permissions plus explicit chmod, so the archive can't smuggle setuid bits or odd ownership.
  • Directory-confusion safety: every root/release/link path is checked for -L (symlink) before being trusted, and an ownership marker (cmp-verified fixed content) distinguishes installer-owned directories from pre-existing/foreign ones — remove and install both refuse to touch anything not carrying that marker. This is exactly the right defense against a symlink planted at /usr/local/libexec/bluefin-runsc before a sudo invocation.
  • Atomicity: release publish is mv -T (rename, not copy-over), and the /usr/local/bin/runsc symlink is replaced via stage-then-mv -Tf, avoiding a window where the link is missing or half-written. A trap cleanup EXIT rolls back staged/partial state on any failure, verified by the bats case that fails an update mid-mv and confirms the previously-active release and link are untouched.
  • Scope discipline: the recipe (shared.just) only calls the helper — no ignore-cgroups, no host networking, no default-runtime change — and one bats test greps the helper + recipe to pin exactly that (runsc recipe and helper do not change defaults or weaken runtime isolation).

I did not independently re-derive the pinned SHA256 values against the real upstream google/gvisor release artifact (that needs fetching a real multi-MB release asset, out of scope for a review), so that trust boundary rests on the author's stated verification. The PR is explicit and correctly scoped about what it does not prove — native podman --runtime=runsc acceptance on real hardware, arm64 evidence, the Review fail-closed path — and defers those to a separate acceptance step rather than claiming them here.

CI green: validate, test, Compose PR test image, and both arch builds all pass; Trivy is neutral (non-blocking) and the manifest/E2E jobs are correctly skipped on a PR.


Generated by Claude Code

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.

feat(security): provide shared runsc provisioning for Bluefin-family hosts

2 participants