Skip to content

feat(fork-review-check): scan build inputs and ship the action with a receipt - #339

Open
Piotr1215 wants to merge 3 commits into
devops-1740/fork-review-check-imagefrom
devops-1740/fork-review-check-scan
Open

Piotr1215 wants to merge 3 commits into
devops-1740/fork-review-check-imagefrom
devops-1740/fork-review-check-scan

Conversation

@Piotr1215

@Piotr1215 Piotr1215 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Build step 4 of the fork review check design: a scan mode that finds every fork a product build consumes, plus the composite action and reusable workflow a product release calls to write the JSON receipt it attaches. Stacked on #338 (image and binary modes), which is stacked on #337 (the CLI).

Key Changes

  • scan mode walks go.mod, go.work, Dockerfiles, shell scripts, Makefiles, .goreleaser files and workflows below -root. Each github.com/loft-sh/<fork> or ghcr.io/loft-sh/<fork> reference resolves through the existing paths: Go module graph, digest-pinned image (with ARG defaults substituted), git clone -b or a workflow repository: checkout as a source pin, release download as a binary.
  • Fail-closed net: a fork reference no resolver understands fails with file:line. A templated reference (a variable with no default in the file) passes only when the caller names that fork with -image, -url/-sha256 or the new -source fork=ref. Non-fork loft-sh repos are ignored. An image whose name matches no repo (ghcr.io/loft-sh/kine-fips) is traced to the repo GitHub links its package to: a non-fork build repo (loft-sh/fips-builds, which builds kine-fips from upstream rancher/kine) is ignored, a fork publishing under another name fails, and an unreadable package fails. Jobs need packages: read. Links (/blob/, /pull/, /releases/tag/, ...) are ignored.
  • check() now shares per-form resolvers between the modes; existing tests pass unchanged.
  • Composite action fork-review-check (default mode scan, advisory by default). All logic sits in src/action.sh, which passes the CLI exit code through but still writes receipt and pass outputs on a rule failure. bats suite added and wired into the test workflow.
  • Reusable workflow fork-review-check.yaml: checkout, the action at fork-review-check/v1, upload the receipt artifact. The token is an optional secrets: github-token, defaulting to the workflow token.
  • live-scan job (advisory, continue-on-error) runs scan against public loft-sh/kubernetes.

Dependencies

TODO

References DEVOPS-1740

https://claude.ai/code/session_017edg9gFKBwMnmsAVXxEJzn

… receipt

Product release workflows cannot list every fork their build consumes by
hand: kine reaches loft-enterprise as an image, loft-sh/kubernetes as a
release binary and a source clone, and vnode-internal as a Go replace. A
list kept by hand drifts, and the design (loft-sh/architecture
fork-review-check.md, build step 4) asks the check to fail any fork
reference no resolver understands, so a new form cannot slip past review.

scan walks go.mod, go.work, Dockerfiles, shell scripts, Makefiles,
goreleaser files and workflows, resolves each fork reference through the
existing go, image and ref paths, and fails references it cannot pin. A
templated reference passes only when the caller names that fork with the
matching explicit flag. Non-fork loft-sh repos and image names with no repo
behind them are ignored.

The composite action and the workflow_call wrapper give release workflows
one step that writes the JSON receipt to attach to the release. The
action script keeps the CLI exit code but still publishes the receipt and
pass outputs on a rule failure, so an advisory caller can read them.

Builds on 7ac5cbc and c9cb3fc.

Claude-Session: https://claude.ai/code/session_017edg9gFKBwMnmsAVXxEJzn
@Piotr1215
Piotr1215 requested a review from a team as a code owner October 27, 2026 10:00
…repository

scan treated any ghcr.io/loft-sh image whose name matched no repository as
not a fork and skipped it. kine-fips is such an image: today loft-sh/fips-builds
builds it from upstream rancher/kine, so skipping it was right by luck. A fork
that published an image under another name would have passed with no review
evidence, a hole in the fail-closed net the design promises auditors.

The scan now asks GitHub which repository the container package is linked to.
A non-fork build repository is still ignored; a fork publishing under another
name fails, and so does a package the token cannot read, because the image
could carry fork code. The job needs packages: read for that lookup.

Claude-Session: https://claude.ai/code/session_017edg9gFKBwMnmsAVXxEJzn
@Piotr1215
Piotr1215 requested a review from vcauesantos October 27, 2026 12:43
Builds can consume vendored Go code that differs from the module graph. Apply the base branch verification to scan-discovered modules as well as explicit Go directories, and let action callers provide the trusted verifier.
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.

2 participants