Skip to content

Flip harden-runner to egress-policy: block with allowlist (phase 2 of #164) #216

Description

@AbongileBoja

Summary

Phase 2 follow-up to #164. Phase 1 (PR #215) deployed step-security/harden-runner in egress-policy: audit across every job in ci.yml, release.yml, and mutation.yml (14 jobs total, pinned to 8d3c67de8e2fe68ef647c8db1e6a09f647780f40 / v2.19.0). Audit mode records observed runner egress but does not block it. Phase 2 curates the observed endpoints into an explicit allowlist and flips egress-policy: block per workflow so that a compromised pinned action cannot exfiltrate to an arbitrary endpoint.

Prerequisite

At least one full CI cycle (push + PR + scheduled run) must have completed against develop after PR #215 merges. The harden-runner job summary on each run lists every endpoint contacted; phase 2 reads those lists and curates the allowlist from them.

Reference allowlist (starting point — refine from observed data)

These are the endpoints we expect to see and that should be allow-listed; the actual allowlist is curated from the audit summaries, not pasted from this list verbatim.

Common (every workflow):

  • api.nuget.org — NuGet feed
  • github.com and objects.githubusercontent.com — checkout, artifact storage
  • dotnetcli.azureedge.net and dotnetbuilds.azureedge.netactions/setup-dotnet SDK download
  • pkgs.dev.azure.com — NuGet OIDC auth path
  • aka.ms and dotnet.microsoft.com — .NET redirect host

Per-workflow additions:

  • ci.yml commitlint job: registry.npmjs.org (commitlint deps; Dependabot is now active per Add Dependabot configuration for nuget, github-actions, and npm #162).
  • ci.yml codeql job: codeload.github.com, objects.githubusercontent.com.
  • release.yml publish job: *.actions.githubusercontent.com (OIDC), tuf-repo-cdn.sigstore.dev, rekor.sigstore.dev, fulcio.sigstore.dev (Sigstore for actions/attest-build-provenance).

Proposed remediation

For each workflow, copy the curated endpoint list into allowed-endpoints on every job and change egress-policy: audit to egress-policy: block. The allowlist may differ per job (e.g. mutation.yml has no NuGet push path; release.yml publish has Sigstore endpoints not needed elsewhere). Use the per-job harden-runner job summary as the source of truth.

When in doubt, prefer narrower scope per job over a single shared list — the principle of least authority applies to network egress just as it does to GitHub token scopes.

Risk and verification

The single failure mode is over-pruning the allowlist: a missing endpoint causes the job to fail at the first egress attempt to that host. Mitigation: ratchet one workflow at a time. Flip ci.yml first (lowest-stakes — push events re-run cheaply), wait one full week of green runs, then flip mutation.yml, then release.yml last (highest-stakes — failed release blocks shipping).

Verify by reading the post-flip harden-runner job summary: it should report zero blocked egress events on a healthy run. Any blocked event means the allowlist is incomplete or an action is reaching out to an unexpected endpoint and warrants investigation before adding to the list.

Acceptance criteria

  • Allowlist curated from observed audit data on develop
  • ci.yml flipped to egress-policy: block and verified green for one week
  • mutation.yml flipped to egress-policy: block and verified green for one scheduled run
  • release.yml flipped to egress-policy: block and verified green on the next tagged release
  • Lock down GitHub Actions egress with step-security/harden-runner #164 closed once all three workflows are in block mode

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions