Skip to content

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

Merged
yunseo-kim merged 5 commits into
mainfrom
feat/reusable-workflow-egress-inputs
Oct 26, 2026
Merged

yunseo-kim merged 5 commits into
mainfrom
feat/reusable-workflow-egress-inputs

Conversation

@yunseo-kim

@yunseo-kim yunseo-kim commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

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

…inputs

Expose egress-policy (string, default "audit") and allowed-endpoints
(string, default empty) workflow_call inputs in all four reusable
workflows and wire them into the step-security/harden-runner step.
Audit remains the non-removable floor: no input can disable
harden-runner. Callers may opt into block mode by passing
egress-policy: block together with allowed-endpoints.

The smoke workflow passes egress-policy: audit explicitly so CI
exercises the input plumbing path. The five files form one behavioral
unit: actionlint validates the smoke workflow's with: keys against the
locally referenced reusable workflows' input definitions.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Add a "Harden Runner in Reusable Workflows" subsection under Runner
Security explaining why harden-runner must live inside the reusable
workflow: a caller job using jobs.<id>.uses cannot define steps, and
each job runs on a fresh ephemeral VM so harden-runner only monitors
the job it executes in. Document the new egress-policy and
allowed-endpoints inputs (audit as the floor, block opt-in), the
Policy Store behavior where the calling repository's policy applies
to a called reusable workflow, and notes for callers outside the
organization. Update the stale v2.21.1 example pins to v2.22.2 to
match the workflows, and append GitHub and StepSecurity reference
links.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Add the two new caller-facing inputs to the Dependency Review and
Scorecard Available Inputs tables, and to the OSV Scanner Standard
Defaults list, noting that audit is the minimum floor and
allowed-endpoints only takes effect with egress-policy: block.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Document the DCO sign-off requirement (git commit -s, enforced by the
lefthook commit-msg hook) and the preference for heredoc commit bodies
over repeated -m flags.

Signed-off-by: Yunseo Kim <git@yunseo.kim>
Switch this repository's three caller workflows (dependency-review,
osv-scanner-smoke, scorecard) from audit to egress-policy: block with
allowed-endpoints allowlists derived from months of accumulated audit
baseline data in the StepSecurity dashboard.

dependency-review allows both api.securityscorecards.dev (the host the
action currently queries, per its source) and api.scorecard.dev
(forward-looking, in case the action migrates to the current OpenSSF
Scorecard API host that scorecard-action already uses for publishing).

Signed-off-by: Yunseo Kim <git@yunseo.kim>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Confidence score: 3/5

  • In .github/workflows/scorecard.yml, the Upload artifact step can fail in block mode because allowed-endpoints omits the artifact storage endpoints. Add the required endpoints to the allowlist.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/scorecard.yml">

<violation number="1" location=".github/workflows/scorecard.yml:38">
P2: The `allowed-endpoints` list omits the artifact storage endpoints that `actions/upload-artifact` needs, and `upload-artifact` is enabled by default here. In block mode, the "Upload artifact" step in `scorecard-reusable.yml` can fail on `main` after merge. This caller runs only on push, schedule, and branch-protection events, so PR CI will not exercise this change. Confirm the allowlist against an audit run of this job, or add the artifact endpoints before switching to `block`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread .github/workflows/scorecard.yml
@yunseo-kim
yunseo-kim merged commit 7479655 into main Oct 26, 2026
13 checks passed
@yunseo-kim
yunseo-kim deleted the feat/reusable-workflow-egress-inputs branch October 26, 2026 14: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