Repository navigation
Description
Security Finding
Severity: high
Type: unsafe-pattern (supply-chain / signature verification not enforced) + closed-but-unfixed
common#847 ("policy.json: ghcr.io/projectbluefin missing sigstoreSigned entry — images accepted without signature verification") was closed as completed on 2026-09-13 when #933 merged — but #933 only shipped the trust materials (fulcio_v1.crt.pem, rekor.pub). The enforcing half, #883 ("security: enforce Sigstore signatures for projectbluefin images"), which added the sigstoreSigned entry for ghcr.io/projectbluefin to system_files/shared/etc/containers/policy.json, was closed unmerged.
Current main system_files/shared/etc/containers/policy.json still has only sigstoreSigned entries for quay.io/toolbx-images and ghcr.io/ublue-os; the catch-all "" docker scope remains insecureAcceptAnything. Nothing requires a signature for ghcr.io/projectbluefin/*.
Net effect: the issue is closed and reads as fixed, but projectbluefin images are still accepted without signature verification anywhere this policy ships. The merged trust materials are dead weight until a sigstoreSigned scope references them.
Impact
Every consumer of the common base image (finpilot, and any downstream) pulls ghcr.io/projectbluefin/* with no signature check. A compromised GHCR namespace or hijacked tag substitutes a malicious image silently. Downstream findings blocked on this (e.g. finpilot#330/#356 — kickstart bootc switch to mutable :stable with no verification) remain unfixable via the signed transport because the policy side never landed.
Recommendation
Re-open #847 (or track here) and land the policy half of #883: add a sigstoreSigned entry for ghcr.io/projectbluefin in system_files/shared/etc/containers/policy.json using the Fulcio/Rekor trust materials merged in #933, with a fulcioIssuer + certificate identity regexp scoped to ^https://github\.com/projectbluefin/[^/]+/\.github/workflows/ (matching the identity regexp already used by the promotion release gates), and drop or narrow the insecureAcceptAnything catch-all as far as compatibility allows.
Note for whoever lands it: the change touches system_files/, not .github/workflows/, so it is pushable by an ISSUES_AND_PRS-tier agent — a hold-gated fix PR is possible.
Filed by sec-check agent (ACMM L4/L5 — hold-gated mode)
— hive: agent=sec-check backend=copilot model=kimi-k3
Activity
hivecommons-hive commentedon Sep 16, 2026
sec-check follow-up with an implementation caveat found while re-verifying:
#883's exact approach is probably not landable as-written. Its policy entry used:
containers/image's
sigstoreSignedfulcio block binds identity viasubjectEmailonly — there is nosubjectRegExp/URI-SAN matching in the policy schema (the #883 body itself noted this). But GitHub Actions keyless (Fulcio) certificates carry the signer identity as a URI SAN (https://github.com/<org>/<repo>/.github/workflows/<wf>@<ref>), not an email SAN.subjectEmail: noreply@github.comwould match nothing, so every pull ofghcr.io/projectbluefin/*would fail verification on systems with this policy — a self-DoS, and a plausible reason #883 was closed unmerged.Viable paths, in rough order of safety:
ghcr.io/ublue-osentry (keyPath+matchRepository): sign with a projectbluefin-held cosign keypair, ship the pubkey under/usr/lib/pki/containers/. Fully expressible in today's policy.json. Cost: key management/rotation.cosign verify --certificate-identity-regexp ...works client-side precisely because cosign matches URIs; policy.json cannot). If any image variant's cert does carry an email SAN,subjectEmailbecomes usable for that scope.Until one of these lands, the correct interim posture is: keep the finding open, don't gate installs on
ostree-image-signed:(finpilot#330 stays blocked), and don't ship asigstoreSignedentry that would reject all projectbluefin pulls.— hive: agent=sec-check backend=copilot model=kimi-k3
kylerankin commentedon Sep 23, 2026
Covered by PR #1194 (open, targeting ).
It lands the enforcement half of #883 that #847 was closed on: a keyless scope for in , referencing the Fulcio/Rekor trust materials already shipped in #933 (, ), with scoped to — the certificate identity the action emits.
Not done here, deliberately: the catch-all is left in place. Narrowing it would reject every unlisted registry (Fedora base, rpm-ostree layers, COPRs) and needs the full consumed-registry surface validated first — a follow-up.
Assisted-by: lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K via GitHub Copilot
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
— hive: backend=pi model=lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K
🐝 Hive Agent:
contributor| SHA:7b4956fkylerankin commentedon Sep 23, 2026
Covered by PR #1194 (open, targeting
main).It lands the enforcement half of #883 that #847 was closed on: a keyless
sigstoreSignedscope forghcr.io/projectbluefininsystem_files/shared/etc/containers/policy.json, referencing the Fulcio/Rekor trust materials already shipped in #933 (fulcio_v1.crt.pem,rekor.pub), withsubjectRegExpscoped to the certificate identity thesign-and-publishaction emits — the same regexp used by the promotion release gates.Not done here, deliberately: the
insecureAcceptAnythingcatch-all is left in place. Narrowing it would reject every unlisted registry (Fedora base, rpm-ostree layers, COPRs) and needs the full consumed-registry surface validated first — a follow-up.Assisted-by: lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K via GitHub Copilot
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
— hive: backend=pi model=lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K
🐝 Hive Agent:
contributor| SHA:7b4956fcastrojo commentedon Sep 26, 2026
test
🐝 Hive Agent:
contributor| SHA:unknownkylerankin commentedon Sep 27, 2026
This finding is currently blocked on a maintainer-only design decision, not on anything shippable from an agent.
What covers / blocks it:
PR #1194 ("fix(containers): enforce sigstore signatures for projectbluefin images") landed exactly the enforcement half #847/#1133 asked for — a
sigstoreSignedscope forghcr.io/projectbluefinreferencing the Fulcio/Rekor trust materials from #933. It was closed by @castrojo on 2026-09-26 after review, with the following confirmed blockers:subjectRegExpis unsupported by containers/image. The policy parser rejects the unknown key and fails to load the whole file, so every container pull on the host fails closed (reproduced with skopeo 1.24.0), not just projectbluefin.fulcioblock structurally supports onlycaPath/caData/oidcIssuer/subjectEmail(all mandatory), and keyless GH Actions certs carry a URI SAN, never an email — so no available field can match them.bluefin:latestandbluefin:gtshave no legacy.sigat their current digest; withdefault: reject+matchRepositoryover the whole org namespace those tags would fail closed on every host.Current
main(system_files/shared/etc/containers/policy.json) still has noghcr.io/projectbluefinentry and the""docker scope remainsinsecureAcceptAnything, so the issue's stated net effect is unchanged.The decision @castrojo held for the core team (the thing this is waiting on): key-based signing (a projectbluefin-held cosign keypair, like the existing
ghcr.io/ublue-osentry, plus re-signing the unsigned tags) vs. waiting on upstream containers/image to support URI-SAN identity binding in the fulcio policy block. That is a supply-chain / trust-policy architectural call, so per operating mode it is gated behind a human decision and nothing mechanical is shippable until it is made.— hive: backend=pi model=lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K
🐝 Hive Agent:
contributor| SHA:unknownhivecommons-hive commentedon Oct 1, 2026
What to reply
/hive approve: go with the recommendation/hive decision <your instructions>: go ahead, following your instructions/hive help: show these againIf this issue is waiting only for reporter confirmation after a merged fix, the reporter or a maintainer can reply
/fixedinstead.Only a maintainer with write access can un-park; everything else is ignored. Full command reference: https://github.com/hivecommons/hive/blob/v5/src/docs/maintainer-commands.md.
feat: streamline common issue intake and lifecycle (#1367)
3 remaining items
castrojo commentedon Oct 4, 2026
Substantive triage
Outcome: Specific maintainer decision required
Established: Common #847 was closed when trust anchors (
fulcio_v1.crt.pem,rekor.pub) landed in #933, but signature enforcement insystem_files/shared/etc/containers/policy.jsonwas never merged. PR #1194 attempted enforcement but was closed due to structuralcontainers/imageincompatibilities.Evidence:
containers/imagepolicy parser strictly allows onlysubjectEmail,oidcIssuer,caPath, andcaDataunderfulcio;subjectRegExpcauses fatal parser errorUnknown key "subjectRegExp", breaking all container pulls host-wide. Furthermore, GitHub Actions keyless certificates use URI SANs, not email SANs, and per-arch image instances onghcr.io/projectbluefin/commonlack individual cosign signatures.Next actor: maintainer / core team (@castrojo, @hanthor)
Next action / exact decision: Core team architectural decision on signing mechanism: either migrate to explicit cosign keypair signing (
keyPath+matchRepositorylikeublue-os) withregistries.dsigstore attachments, or wait for upstreamcontainers/imageto support Fulcio URI SAN matching.Completion criteria:
policy.jsonpassesskopeo copy --policyagainst multi-arch Bluefin images without parser rejection.Verification limits: Cannot enforce keyless signatures via
policy.jsonwith currentcontainers/imageimplementation without breaking image pulls.Preserved controls: Existing ownership and human holds/preferences remain authoritative. This assessment does not grant implementation acceptance, infer image delivery, or clear Hive admission controls.
github-actions commentedon Oct 4, 2026
Status: Waiting for information or a decision
Next actor and steps: Maintainer: resolve the recorded decision and update the agreed scope and completion criteria in the issue body first. Then remove
needs-decisionif its reason is resolved and use GitHub's Labels picker to addtriage/accepted. Removing a waiting label or posting/hive approvedoes not record Common implementation acceptance.Reporter action: No action needed unless information is requested.
hivecommons-hive commentedon Oct 10, 2026
sec-check impact update (2026-10-10), for the pending decision — no new ask, just a new consumer that changes the blast radius:
registry-actions.yml) now moves a mutableghcr.io/projectbluefin/gutenprint-printer-app:stabletag on every verified release (oras tag "${IMAGE}@${DIGEST}" stable). The sibling printer-app repos are on the same template.AutoUpdate=registry(internal/printerapp/printerapp.go:146,230; ADR-0020 deliberately replaced digest pins with the moving tag sopodman-auto-update.timerworks).With the current
policy.json(""→insecureAcceptAnything), that pull path is the first place where a moving projectbluefin tag is fetched unattended on end-user machines. The release workflow cosign-signs and verifies the index, but nothing on the host checks that signature: whoever can retag the GHCR package (package write token, compromised workflow run) gets code onto every machine with a printer family enabled at the next timer tick, with no reviewed commit involved.Until #1194's approach (or key-based signing) is decided, the mitigation lives entirely in the registry-side controls — so the decision here now gates a user-facing auto-update channel, not only image-build inputs.
🐝 Hive Agent:
security| Instance:hosted-projectbluefin-knuckle-gjvq| SHA:unknown— hive: agent=sec-check backend=copilot model=claude-fable-5.1 copilot=1.0.88
castrojo commentedon Oct 21, 2026
Still reproduces on Dakota
:testing20261013 (sha256:2c794dbb…, bootc 1.17.1):/etc/containers/policy.jsonhas noghcr.io/projectbluefinentry,docker: ""isinsecureAcceptAnything, and/usr/lib/pki/containers/ships no projectbluefin key. bootc pullsghcr.io/projectbluefin/dakota:testingwith no signature check. Dakota'sos-releasemeanwhile claimsIMAGE_REF=ostree-image-signed:…; filed as projectbluefin/dakota#1803.