ci(harden-runner): Add caller-configurable egress inputs and enforce block mode

Merged
YU
17h ago
+167-29

Summary

Reusable workflows previously hardcoded step-security/harden-runner to egress-policy: audit with no way for callers to opt into block mode. This PR:

  • Adds egress-policy (string, default "audit") and allowed-endpoints (string, default empty) workflow_call inputs to all four reusable workflows (OSV Scanner PR/Full, Dependency Review, Scorecard) and wires them into the harden-runner step. Audit remains the non-removable floor; no input can disable harden-runner.
  • Switches this repository's own caller workflows (dependency-review.yml, osv-scanner-smoke.yml, scorecard.yml) to egress-policy: block with allowlists derived from months of accumulated audit baseline data in the StepSecurity dashboard.
  • Documents why harden-runner must live inside the reusable workflow (a jobs.<id>.uses: caller job cannot define steps:, and harden-runner monitors only the runner VM of the job it executes in) in docs/security/workflow-hardening.md, including Policy Store behavior (the calling repository's policy applies to a called reusable workflow) and notes for cross-organization callers. New inputs are also documented in README.md.
  • Includes a pre-existing AGENTS.md addition documenting commit conventions (DCO sign-off, heredoc bodies) as a separate commit.

How to test: this PR itself is the runtime gate. osv-scanner-smoke.yml triggers on changes to .github/workflows/osv-scanner-*.yml, so the pr-smoke job runs the reusable workflow end-to-end in block mode; the StepSecurity dashboard should show the run with blocked-endpoint telemetry and no unexpected egress.

Related Issues

  • Related # (none)

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Test/CI
  • Breaking change
  • Other:

Changelog

  • Category: Added
  • User-facing note: Reusable workflows accept egress-policy / allowed-endpoints inputs so consumer repositories can opt into harden-runner block mode; audit remains the default floor.

Changelog update:

  • CHANGELOG.md [Unreleased] updated
  • Not needed because this change is not user-facing (this repository does not maintain a CHANGELOG.md)

Checklist

General

  • PR title follows Conventional Commits format:
    type(scope): Summary
  • This PR does not expose backend/internal implementation details in a public repo.
  • No secrets, tokens, keys, or private endpoints are included.
  • Changes stay within this repository's intended scope.

CI/Workflow Changes (if applicable)

If this PR modifies GitHub Actions workflows or CI/CD configuration, it must comply with our
Supply Chain Integrity requirements:

  • All uses: references are pinned to full 40-character commit SHAs (with # vX.Y.Z comment) — no new uses: references added
  • step-security/harden-runner is included as the first step in every job — unchanged; reusable workflow jobs retain it, and jobs.<id>.uses: caller jobs cannot define steps (documented in workflow-hardening.md)
  • Job-level permissions are used instead of top-level permissions

Protocol / Compatibility Impact

  • No protocol/spec impact
  • Protocol/spec updated
  • Conformance tests updated
  • Breaking change is versioned and migration notes are included

If impacted, describe compatibility impact:

Backward compatible: both new inputs have defaults matching previous behavior (audit, empty endpoints), so existing consumers are unaffected unless they opt in.

Testing

  • Unit tests added/updated
  • Integration or conformance tests added/updated
  • Tests pass
  • Lint and format pass
  • Type check passes
  • Manual verification performed

Describe test evidence:

  • actionlint passes on all workflow files, including validation of the smoke workflow's with: keys against the local reusable workflow input definitions
  • YAML parse verified for all five modified workflows; input defaults ("audit", "") asserted programmatically
  • bun run lint:md (0 issues, 18 files) and bun run format:check (38 files) pass
  • Block-mode allowlists verified against official sources: api.scorecard.dev is scorecard-action v2.5.0's publish base URL (action.yaml); dependency-review-action's scorecard.ts queries api.deps.dev + api.securityscorecards.dev; SARIF upload uses api.github.com; harden-runner's own telemetry endpoints are automatically allowed per StepSecurity docs
  • Runtime gate: this PR's pr-smoke job exercises the input plumbing end-to-end in block mode (workflow files cannot be executed locally)

Documentation

  • README updated
  • Spec/docs updated (docs/security/workflow-hardening.md — new "Harden Runner in Reusable Workflows" section, stale v2.21.1 example pins corrected to v2.22.2, reference links added)
  • Changelog decision completed above

Rollout / Risk

  • Risk level: Medium — block mode fails the job if a required endpoint is missing from the allowlist. Mitigation: allowlists are derived from the audit baseline; this PR's own smoke run validates the OSV path before merge.
  • Rollback plan: revert this branch, or set egress-policy: audit in the affected caller workflow (single input flip, no reusable workflow change needed).

Reviewer Checklist

  • Scope is clear and minimal
  • Security and boundary checks passed
  • Tests and docs are sufficient
  • Compatibility impact is correctly handled