Skip to content

chore: org hardening — SHA-pinned actions, SLSA provenance, CODEOWNERS, SECURITY, CONTRIBUTING - #78

Merged
FumingPower3925 merged 7 commits into
mainfrom
chore/org-hardening
Sep 5, 2026
Merged

chore: org hardening — SHA-pinned actions, SLSA provenance, CODEOWNERS, SECURITY, CONTRIBUTING#78
FumingPower3925 merged 7 commits into
mainfrom
chore/org-hardening

Conversation

@FumingPower3925

Copy link
Copy Markdown
Contributor

File-based hardening for goceleris/loadgen following the org hardening review 2026-09-06 (read-only audit of the goceleris org against mature open-source configuration). Workflow semantics are unchanged except where listed. Repository settings, rulesets and the bench cluster are handled separately and are not touched here.

Changes

# Change Rationale
1 SHA-pin every third-party action in ci.yml and release.yml (actions/checkout3d3c42e5 v7.0.1, actions/setup-gob7ad1dad v7.0.0, golangci/golangci-lint-actionba0d7d2e v9.3.0, softprops/action-gh-releaseefb35369 v3.0.3), with a # vN.M.P comment Floating tags are mutable; a hijacked upstream tag runs arbitrary code with our GITHUB_TOKEN. Each SHA is exactly the commit the current tag resolves to (annotated tags dereferenced via the GitHub refs API), so there is no behaviour change. Dependabot's existing github-actions ecosystem keeps SHA + comment current.
2 persist-credentials: false on actions/checkout in the CI lint, test, integration jobs and the release publish job Those jobs never push, tag or write releases, yet by default the token is written to .git/config where go install …@latest, golangci-lint and the integration testserver could read it. The release binaries job keeps the default because it feeds a release-writing step.
3 SLSA build provenance in release.yml: the binaries job gets permissions: {contents: write, id-token: write, attestations: write} and a new actions/attest-build-provenance@4d101475 # v4.2.2 step whose subject-path is the tarball, placed before the (kept) softprops/action-gh-release upload probatorium fetches these tarballs onto bench hosts; a SHA-256 on the release page only proves download integrity, not that GitHub's workflow built the artifact from a given commit.
4 README "Verify a release" section: gh attestation verify <asset> -R goceleris/loadgen Consumers need to know the attestation exists and how to check it; notes that ≤ v1.4.13 releases carry none.
5 .github/CODEOWNERS — header comment, * @FumingPower3925, commented area-delegation example Makes review ownership explicit; pairs with the "Require review from Code Owners" branch-protection setting (configured separately).
6 SECURITY.md — private reporting via the Security tab → "Report a vulnerability" (preferred) or security@goceleris.dev, 72-hour acknowledgement, supported versions (latest release), scope, pointer to celeris/SECURITY.md for the engine The repo had no security policy, leaving a public issue as the only reporting route.
7 CONTRIBUTING.md — Go build/test/lint commands as CI runs them, PR flow, commit conventions, merge rule by reference to celeris/GOVERNANCE.md One governance source of truth for the org; contributors can reproduce a green CI locally.
8 .github/PULL_REQUEST_TEMPLATE.md — Summary, Changes, Test Plan, Closes # Mirrors celeris; adds the loadgen-specific reminder that JSON-schema/flag changes must update the README contract probatorium parses.
9 .github/release.yml — categories Breaking Changes / Security / Fixes / Performance / Features / Other; excludes dependencies, github_actions labels Same categories as celeris so release pages read alike across the org; Dependabot bumps are noise for binary consumers.

Test Plan

  • actionlint clean on both workflows
  • python3 -c 'import yaml' parses ci.yml, release.yml, .github/release.yml, dependabot.yml
  • grep -E 'uses: [^./][^@]*@v' .github/workflows/*.yml finds nothing (no unpinned action left)
  • go build ./... && go vet ./... (no Go source changed; sanity)
  • Every SHA cross-checked against the releases/latest tag of each action (floating major and exact release tag point at the same commit)
  • The attestation step is exercised on the next release; verify with gh attestation verify loadgen_linux_amd64.tar.gz -R goceleris/loadgen

Follow-ups outside this PR (settings, not files)

  • Enable private vulnerability reporting on the repository (SECURITY.md already describes it as the preferred channel).
  • Turn on "Require review from Code Owners" in the main ruleset so CODEOWNERS becomes a merge gate.
  • celeris/GOVERNANCE.md (linked from CONTRIBUTING.md) is being added in the celeris hardening PR.

Floating tags (actions/checkout@v7, softprops/action-gh-release@v3, ...)
are mutable: whoever controls the upstream tag controls what runs with
our GITHUB_TOKEN. Pinning to the 40-hex commit the current tag resolves
to makes the workflow reproducible and immune to tag hijacking; the
trailing "# vN.M.P" comment keeps the version human-readable and lets
Dependabot's github-actions ecosystem keep both the SHA and the comment
current.

Resolved on 2026-09-06 via the GitHub refs API (annotated tags
dereferenced to their commit):

  actions/checkout@v7               -> 3d3c42e5 (v7.0.1)
  actions/setup-go@v7               -> b7ad1dad (v7.0.0)
  golangci/golangci-lint-action@v9  -> ba0d7d2e (v9.3.0)
  softprops/action-gh-release@v3    -> efb35369 (v3.0.3)

No behavior change: each SHA is exactly the commit the floating tag
pointed at. Org hardening review 2026-09-06.
actions/checkout writes the job's GITHUB_TOKEN into .git/config
(persist-credentials: true by default). Every subsequent step — and any
tool they run, e.g. `go install ...@latest`, golangci-lint, the
integration testserver — can read it back. None of the CI jobs (lint,
test, integration) nor the release "publish" job push, tag or write to
the repository, so they get `persist-credentials: false`.

The release "binaries" job is left at the default: it hands a
release-writing step (softprops/action-gh-release) the token, and the
review rule is to leave the default wherever a step pushes, tags or
writes releases.

No behavior change for the workflows' own steps. Org hardening review
2026-09-06.
Bench orchestrators (probatorium) fetch loadgen tarballs straight from
GitHub Releases and run them on the load hosts. Until now the only
integrity signal was the SHA-256 GitHub displays next to the asset,
which proves the download matched what was uploaded — not that it was
built by this repository's workflow from a given commit.

The "binaries" job now runs actions/attest-build-provenance (pinned to
4d101475, v4.2.2) on the exact archive it is about to upload, BEFORE the
softprops/action-gh-release step, so the attestation covers the bytes
that ship. The job gets the minimum permission set the attestation
needs: contents: write (upload, unchanged), id-token: write (OIDC
identity that Sigstore signs the SLSA predicate with) and
attestations: write (store it in the repo's attestation store). The
upload step itself is unchanged.

README gains a "Verify a release" section:

  gh attestation verify <asset> -R goceleris/loadgen

and notes that releases before this change (<= v1.4.13) carry no
attestation. Org hardening review 2026-09-06.
Makes review ownership explicit and machine-enforceable: GitHub
auto-requests @FumingPower3925 on every pull request, and the "Require
review from Code Owners" branch-protection option (configured
separately) can turn that into a hard merge gate. The header explains
the precedence rule and a commented example shows how to delegate a
subsystem to a second maintainer when the time comes. Org hardening
review 2026-09-06.
loadgen had no security policy, so a researcher's only option was a
public issue. The new policy prefers GitHub private vulnerability
reporting (Security tab -> "Report a vulnerability", enabled on the
repository) with security@goceleris.dev as the fallback, commits to an
acknowledgement within 72 hours, states that only the latest release is
supported, scopes what counts as a loadgen vulnerability (response
parsers, TLS handling, federation protocol, result output, release
pipeline) and points engine issues at celeris/SECURITY.md. Org
hardening review 2026-09-06.
Documents what CI actually runs (go build/vet, golangci-lint v2.13, the
-race unit suite, the live-celeris integration matrix) so contributors
can reproduce a green run locally, the branch/commit conventions shared
with celeris, and the merge rule — protected main, PR + CI + code-owner
approval, maintainer merge — by reference to celeris/GOVERNANCE.md so
the org has one governance source of truth. The PR template (Summary,
Changes, Test Plan, Closes #) mirrors celeris' and adds the loadgen
specific reminder that JSON-schema or flag changes must update the
README contract that probatorium parses. Org hardening review
2026-09-06.
Auto-generated release notes were uncategorised. Adopt the same
categories as celeris (Breaking Changes, Security, Fixes, Performance,
Features, Other) so release pages across the org read alike, and
exclude the dependencies / github_actions labels because Dependabot
bumps are noise for people downloading the binaries. Org hardening
review 2026-09-06.
@FumingPower3925
FumingPower3925 merged commit 57f552a into main Sep 5, 2026
6 checks passed
@FumingPower3925
FumingPower3925 deleted the chore/org-hardening branch September 5, 2026 23:16
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