# Build-iso CI hardening **Agent 8 of 9-agent wave, 2026-05-05.** ## State of play - Workflows: `build-iso.yml`, `lint.yml`, `Release Checksums` (auto) - Secrets/variables: **none configured** — only ambient `GITHUB_TOKEN` - Repo: private, MIT, no Pages, no Dependabot, no branch protection (Pro-gated until public flip) - Container: `registry.fedoraproject.org/fedora:43` (tag, not digest) - Actions: `actions/checkout@v4`, `addnab/docker-run-action@v3`, `softprops/action-gh-release@v2`, `ludeeus/action-shellcheck@master` — **all unpinned to SHA** - gum download: pinned by SHA256 ✓ - Kickstart repos: `releases/43/Everything` + `updates/43/Everything` — **both rolling**, byte-different daily ## Top 5 immediate (S effort, ship in v0.5.32) | # | Item | Why | |---|------|-----| | 1 | Pin all actions to commit SHA + add `.github/dependabot.yml` for `github-actions` | Supply-chain — `@master` on shellcheck is live-takeover vector; v3/v4 tags are mutable | | 2 | Pin Fedora container to digest (`registry.fedoraproject.org/fedora:43@sha256:...`) | One-line change; eliminates "container drift" repro class | | 3 | Add `permissions:` block at workflow level (`contents: read` default), override per-job | `contents: write` is workflow-wide; least-privilege the lint job | | 4 | Generate SBOM via `anchore/sbom-action`, attach to release | Free, ~30 lines, journalist-readable | | 5 | Add `actions/attest-build-provenance@v2` for SLSA L3 attestation on ISO + parts | Free, GH-native, `id-token: write` only | ## v0.4 release-eng roadmap (confirmed/added) - **Confirmed:** Sigstore/cosign signing of ISOs (already in roadmap) - **Add:** Fedora compose-ID pinning per release tag — switch `--baseurl` to `kojipkgs.fedoraproject.org/compose/branched/Fedora-43-...n.X/compose/Everything/x86_64/os/` for stable releases (rolling for `ci-latest`) - **Add:** Reproducible-Builds.org diffoscope job comparing 2 sequential builds of same SHA — gate on byte-equality - **Add:** `harden-runner` (StepSecurity) audit-mode pass to enumerate egress; promote to block-mode in v0.5 - **Add:** When repo flips public (v0.7), enable secret scanning + push protection + private vuln reporting + branch protection (require ≥1 review, status checks: lint + ksvalidate + build, no force-push) - **Add:** OIDC `id-token: write` only in tag-release job (not on `main` push) — keysless cosign signing scoped to release events ## YAML diffs ### 1. Workflow-level permissions + per-job override ```yaml permissions: contents: read jobs: build: permissions: contents: write # gh-release id-token: write # cosign keyless + attestation attestations: write ``` ### 2. SHA-pin actions ```yaml - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: addnab/docker-run-action@4f65375b03d588f307b7a3b0a8bb50f8b58a85b9 # v3 - uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0 ``` (SHAs to be re-checked at apply-time; dependabot keeps them current) ### 3. Pin Fedora digest ```yaml image: registry.fedoraproject.org/fedora:43@sha256: ``` Capture once via `skopeo inspect --raw docker://registry.fedoraproject.org/fedora:43 | jq -r .config.digest` and bump on each releasever bump. ### 4. SBOM + attestation + cosign ```yaml - name: Install cosign uses: sigstore/cosign-installer@d7d6e07a3ddf0f9a4f8b3b9e3f1d1a5ce8e9b5b3 # v3.7.0 - name: Sign ISO parts (keyless) if: github.event_name == 'release' run: | cd build/out for f in *.part-*; do cosign sign-blob --yes "$f" \ --output-signature "$f.sig" --output-certificate "$f.pem"; done - name: Generate SBOM (SPDX) uses: anchore/sbom-action@e8d2a6937ecead383dfe75190d104edd1f9c5751 # v0.17.4 with: path: build/out format: spdx-json output-file: build/out/veilor-os.spdx.json - name: Build provenance attestation uses: actions/attest-build-provenance@7668571508540a607bdfd90a87a560489fe372eb # v2.1.0 with: subject-path: 'build/out/*.part-*' ``` ### 5. New `.github/dependabot.yml` ```yaml version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: { interval: "weekly" } groups: actions: { patterns: ["*"] } ``` ### 6. Timeout Keep at 90min. Largest observed runs ~70min; trimming would false-fail Fedora-mirror-slow days. **No change.** ## Q&A - **Secrets in use:** none. Only ambient `GITHUB_TOKEN`. Once public, enable secret scanning + push protection (free for public repos). - **Pages:** not deployed from this repo. Docs site out-of-scope here. - **Dependency review:** only `gum` fetched out-of-band — already SHA256-pinned. Add `actions/dependency-review-action` on PRs once public.