Skip to content

feat: enforce block-mode egress for release-rust's plan and build jobs - #30

Merged
purpleclay merged 1 commit into
mainfrom
23-switch-egress-policy-to-block
Jul 31, 2026
Merged

feat: enforce block-mode egress for release-rust's plan and build jobs#30
purpleclay merged 1 commit into
mainfrom
23-switch-egress-policy-to-block

Conversation

@purpleclay

@purpleclay purpleclay commented Jul 31, 2026

Copy link
Copy Markdown
Owner

closes #23

Summary by CodeRabbit

  • Security

    • Release workflows now restrict network access to approved GitHub, release asset, and build mirror endpoints.
    • Rust release builds apply target-specific network permissions for improved supply-chain protection.
  • Maintenance

    • Updated workflow security annotations and standardized build step naming.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Release workflows now block runner egress and use explicit endpoint allowlists. The Rust workflow builds target-specific lists, including dynamic Zig community mirrors, and applies them to planning, build, and provenance jobs. Zizmor ignore references now match the updated workflow location.

Changes

Workflow egress hardening

Layer / File(s) Summary
CI plan validation
.github/workflows/release-rust.yml
The planning job constructs common and ZigBuild endpoint lists, retrieves Zig community mirrors, and assigns the correct list to each target.
Rust release planning and builds
.github/workflows/release-rust.yml
Build jobs now block egress and use target-specific endpoint lists. Build step names use lowercase. The provenance job uses an explicit GitHub and Sigstore allowlist.
Release policy alignment
.github/workflows/release.yml, .github/zizmor.yml
The release workflow blocks egress to GitHub and release asset endpoints. Zizmor ignore entries target the updated Rust workflow location.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PlanJob
  participant ZigMirrors
  participant TargetMatrix
  participant BuildJob
  participant ProvenanceJob
  PlanJob->>ZigMirrors: Fetch community mirror endpoints
  ZigMirrors-->>PlanJob: Return mirror list
  PlanJob->>TargetMatrix: Assign target-specific allowlist
  TargetMatrix->>BuildJob: Pass allowed-endpoints
  BuildJob->>BuildJob: Enforce blocked egress
  ProvenanceJob->>ProvenanceJob: Enforce GitHub and Sigstore allowlist
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The release-rust hardening is in scope, but the separate release.yml egress change is not covered by issue #23. Move the release.yml change to a separate PR or link an issue that defines its requirements.
Linked Issues check ❓ Inconclusive The PR moves plan and build to block mode, but the provided context does not confirm audit coverage or dependency allowlist validation required by issue #23. Provide evidence that mirror rotation and dependency egress were fully validated, or document why the allowlist is sufficient.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: block-mode egress enforcement for the release-rust plan and build jobs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 23-switch-egress-policy-to-block

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 67-118: The matrix planner is duplicated, so hardening tests can
diverge from production behavior. In .github/workflows/ci.yml lines 67-118,
replace the inline planner with a call to the shared implementation and pass the
fixed test targets; in .github/workflows/release-rust.yml lines 95-137, move the
planner logic into that shared implementation while retaining the production
workflow as its caller. Ensure both workflows use the same matrix and
endpoint-policy generation.

In @.github/workflows/release-rust.yml:
- Around line 95-111: Update the release workflow’s Cargo endpoint setup around
common_endpoints to support caller-specific registry, source-replacement, and
Git dependency hosts: add a validated caller endpoint input and include its
approved values in the Cargo allowlist, or add an equivalent pre-build
validation that rejects unsupported Cargo sources before invoking Cargo.
Preserve the existing zigbuild endpoint handling and ensure untrusted endpoint
values cannot bypass validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 18bc9115-5393-497f-9222-d17c862529d2

📥 Commits

Reviewing files that changed from the base of the PR and between 6232689 and 5953898.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-rust.yml
  • .github/workflows/release.yml
  • .github/zizmor.yml

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/release-rust.yml
Comment thread .github/workflows/release-rust.yml
@purpleclay
purpleclay force-pushed the 23-switch-egress-policy-to-block branch from 5953898 to 55393b3 Compare July 31, 2026 13:48
@pull-request-size pull-request-size Bot added size/M and removed size/L labels Jul 31, 2026

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release-rust.yml (1)

94-131: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

actions/upload-artifact@v7 requires endpoint allowlist entries missing from both common_endpoints and zigbuild_endpoints.

Every build job step upload_archive (line 239) runs actions/upload-artifact@v7. The v4+ versions of this action use a dedicated backend separate from github.com. Required endpoints include:

  • actions.githubusercontent.com (Actions artifact/cache/log services)
  • *.blob.core.windows.net (Azure Blob Storage for artifact data storage)

Neither common_endpoints nor zigbuild_endpoints includes these hosts. With egress-policy: block enabled on the build job (line 152), every build leg will fail at the upload step after a successful compile, blocking all releases.

Before merging with block mode enabled, run the workflow with egress-policy: audit on the build job and check the Harden-Runner Insights page to capture the actual artifact-upload endpoints. Then add them to the allowed lists. Use the GitHub Meta API (curl https://api.github.com/meta | jq .domains.actions) to retrieve the authoritative current list of Actions endpoints.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-rust.yml around lines 94 - 131, The endpoint
allowlists used by the build matrix omit hosts required by
actions/upload-artifact@v7. Update common_endpoints and zigbuild_endpoints to
include the authoritative Actions domains from the GitHub Meta API, including
actions.githubusercontent.com and the required Azure Blob Storage hosts; first
validate the actual upload endpoints in audit mode, then ensure every
upload_archive job succeeds with egress-policy block.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/release-rust.yml:
- Around line 94-131: The endpoint allowlists used by the build matrix omit
hosts required by actions/upload-artifact@v7. Update common_endpoints and
zigbuild_endpoints to include the authoritative Actions domains from the GitHub
Meta API, including actions.githubusercontent.com and the required Azure Blob
Storage hosts; first validate the actual upload endpoints in audit mode, then
ensure every upload_archive job succeeds with egress-policy block.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7ed36103-b098-4435-b4e1-2ff6b9d6dfb8

📥 Commits

Reviewing files that changed from the base of the PR and between 5953898 and 55393b3.

📒 Files selected for processing (3)
  • .github/workflows/release-rust.yml
  • .github/workflows/release.yml
  • .github/zizmor.yml

Closes #23

`build`'s harden_runner moves from audit to block, with the allowed
endpoints computed per matrix leg rather than static:

- `plan` now assembles two endpoint sets — one for zigbuild (linux)
legs, one for native (macOS) legs — and bakes the appropriate one into
each matrix entry alongside runs-on/zigbuild, verified against real
harden-runner audit logs rather than guessed
- the zig mirror allowlist is fetched live from ziglang.org's own
authoritative mirror list, since mlugg/setup-zig picks a mirror at
random per run (confirmed: two real runs picked two different ones) —
allowlisting whichever one we'd happened to observe would have been
incomplete
- `plan` gets its own harden_runner (block, ziglang.org only), since
fetching that mirror list is the first time this job reaches the network

Signed-off-by: purpleclay <purpleclaygh@gmail.com>
@purpleclay
purpleclay force-pushed the 23-switch-egress-policy-to-block branch from 55393b3 to 0266693 Compare July 31, 2026 16:21

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-rust.yml:
- Around line 107-110: Update the endpoint construction in the release workflow
to stop deriving allowed endpoints directly from the mutable
community-mirrors.txt response. Use a reviewed repository-owned mirror list or
filter the fetched hosts against an explicit approved set before assigning
zig_mirrors, and preserve only validated hosts for Zig build steps.
- Line 111: Update the zigbuild_endpoints assignment in the release workflow to
include the Actions cache host identified by harden-runner audit logs,
preserving the existing endpoint values so setup_zig can restore and save the
Zig tarball successfully.
- Around line 265-277: Add pipelines.actions.githubusercontent.com:443 to the
allowed-endpoints list used by the harden-runner step in the release workflow,
preserving the existing block policy and all current endpoints.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4f3ffee5-6538-43f0-941d-e6099a0743e5

📥 Commits

Reviewing files that changed from the base of the PR and between 55393b3 and 0266693.

📒 Files selected for processing (3)
  • .github/workflows/release-rust.yml
  • .github/workflows/release.yml
  • .github/zizmor.yml

Comment thread .github/workflows/release-rust.yml
Comment thread .github/workflows/release-rust.yml
Comment thread .github/workflows/release-rust.yml
@purpleclay
purpleclay merged commit 9ffaad0 into main Jul 31, 2026
4 checks passed
@purpleclay
purpleclay deleted the 23-switch-egress-policy-to-block branch July 31, 2026 18:42
purpleclay added a commit that referenced this pull request Aug 1, 2026
#30)

Closes #23

`build`'s harden_runner moves from audit to block, with the allowed
endpoints computed per matrix leg rather than static:

- `plan` now assembles two endpoint sets — one for zigbuild (linux)
legs, one for native (macOS) legs — and bakes the appropriate one into
each matrix entry alongside runs-on/zigbuild, verified against real
harden-runner audit logs rather than guessed
- the zig mirror allowlist is fetched live from ziglang.org's own
authoritative mirror list, since mlugg/setup-zig picks a mirror at
random per run (confirmed: two real runs picked two different ones) —
allowlisting whichever one we'd happened to observe would have been
incomplete
- `plan` gets its own harden_runner (block, ziglang.org only), since
fetching that mirror list is the first time this job reaches the network

Signed-off-by: purpleclay <purpleclaygh@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move build job's egress-policy to block, once mirror coverage is confirmed via audit mode

1 participant