Skip to content

feat: add SLSA 3 provenance, OpenSSF Scorecard, and security hardening#96

Open
stephrobert wants to merge 1 commit intogetplumber:mainfrom
stephrobert:feature/slsa3-scorecard
Open

feat: add SLSA 3 provenance, OpenSSF Scorecard, and security hardening#96
stephrobert wants to merge 1 commit intogetplumber:mainfrom
stephrobert:feature/slsa3-scorecard

Conversation

@stephrobert
Copy link
Contributor

Summary

Add SLSA Level 3 provenance, OpenSSF Scorecard, and comprehensive security hardening to maximize the project's OpenSSF Scorecard score.

Context

Following the hackerbot-claw supply chain attack that compromised aquasecurity/trivy and 6 other major repositories, this PR hardens Plumber's CI/CD supply chain against the anti-patterns exploited in that campaign.

Changes

SLSA Level 3 Provenance (release.yml)

  • New hash job: computes SHA256 hashes of all release binaries
  • New provenance job: generates SLSA Level 3 provenance attestations using slsa-framework/slsa-github-generator@v2.1.0
  • Provenance is uploaded as release assets alongside binaries

OpenSSF Scorecard (scorecard.yml)

  • New workflow: runs ossf/scorecard-action@v2.4.3 weekly + on push to main
  • Publishes results to the OpenSSF Scorecard API
  • Uploads SARIF to GitHub Security tab

Security Policy (SECURITY.md)

  • Vulnerability reporting instructions (GitHub Security Advisories)
  • Response timeline commitments
  • Coordinated disclosure policy

Fuzz Testing

  • configuration/expression_fuzz_test.go: Fuzzes the boolean expression parser (ParseRequiredExpression)
  • utils/gitremote_fuzz_test.go: Fuzzes the git remote URL parser (ParseGitRemoteURL)
  • Both run 10s clean with native Go fuzzing, no crashes

Workflow Hardening (all 4 workflows)

  • Pin all GitHub Actions by SHA commit hash (not mutable tags)
  • Add persist-credentials: false to all checkout steps
  • Move permissions to job-level with least privilege in release.yml
  • Workflow-level permissions: {} (deny-all) on release.yml

Cleanup

  • Remove compiled main binary from source tree (was committed accidentally)
  • Add main to .gitignore

README

  • Add OpenSSF Scorecard badge
  • Add SLSA Level 3 badge

Expected Scorecard Impact

Check Before After How
Security-Policy 0 10 SECURITY.md
Binary-Artifacts 9 10 Remove main binary
Signed-Releases 0 10 SLSA provenance (after first release)
Token-Permissions 0 10 Job-level permissions, deny-all default
Fuzzing 0 10 Native Go fuzz tests
Pinned-Dependencies 8 10 All actions pinned by SHA
Dangerous-Workflow 10 10 No pull_request_target
Dependency-Update-Tool 10 10 Dependabot
License 10 10 MPL-2.0
Packaging 10 10 Docker workflow
Vulnerabilities 10 10 No known vulns
SAST 8 8 CodeQL

Checks requiring manual action (not in this PR)

Check Current Action needed
Branch-Protection 3 Enable "Require PR reviews" + "Require status checks" on main (needs admin)
Code-Review 1 Approve PRs before merging (process change)
CII-Best-Practices 0 Register at bestpractices.coreinfrastructure.org
Maintained 0 Will improve over time (project < 90 days old)
Contributors 3 Will improve with more contributors

Validation

  • zizmor v1.22.0: 0 findings (1 ignored: SLSA unpinned-uses — by design, SLSA generator requires tag reference)
  • All existing tests pass
  • Fuzz tests: 10s runs, 0 crashes

- Add SLSA Level 3 provenance generation in release workflow (hash + provenance jobs)
- Add OpenSSF Scorecard workflow (weekly + on push to main)
- Add SECURITY.md with vulnerability reporting policy
- Add fuzz tests for expression parser and git remote URL parser
- Remove compiled binary from source tree, add to .gitignore
- Pin all GitHub Actions by SHA commit hash
- Add persist-credentials: false to all checkout steps
- Move permissions to job-level (least privilege) in release workflow
- Add OpenSSF Scorecard and SLSA Level 3 badges to README

Scorecard improvements:
  Security-Policy: 0 → 10 (SECURITY.md)
  Binary-Artifacts: 9 → 10 (remove main binary)
  Signed-Releases: 0 → 10 (SLSA provenance, after first release)
  Token-Permissions: 0 → 10 (job-level permissions)
  Fuzzing: 0 → 10 (native Go fuzz tests)
  Dangerous-Workflow: 10 (maintained)
  Pinned-Dependencies: 8 → 10 (all actions pinned by SHA)

Validated with zizmor v1.22.0: 0 findings (1 ignored: SLSA unpinned-uses).
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