Repository navigation
ci: stop claiming egress-block on jobs that do not enforce it - #489
Conversation
harden-runner has never enforced `egress-policy: block` in this repo. It arms block mode by reading an Actions cache entry, GitHub made that cache read-only for untrusted triggers, and an unguarded `new URL()` on the resulting miss fails open to `audit` with a single `core.info` line. Root cause, evidence and fix are in #487. Comments only. No policy value, permission, allowlist or logic changes, so behaviour is identical before and after. What changes is that the files stop asserting a control that is not running: - claude-repro.yml named egress-block as one of the two *real* controls behind I1, in the same comment that carefully demotes the credential check to a backstop. I1 rests on two legs, not three. - ai-scan.yml claimed "harden-runner blocks egress" in its security header. - .github/CLAUDE.md rule 10 and the I1 summary described block as the resting state for new jobs without noting that block is inert here. - ai-triage.yml's FOLLOW-UP asked for an audit-to-block flip that is now known to be a no-op. Replaced with the measured endpoint gap: a real session reaches nine hosts and the allowlist is missing three of them, so the flip would have broken triage at the Claude CLI download rather than hardening it. The allowlists are left as they are and the declared policies are unchanged, so closing #487 needs no edit here. Found while carrying out #456's audit-to-block obligation. The fail-closed assertion that would catch a future silent downgrade (`jq -e '.egress_policy == "block"' /home/agent/agent.json`) is deliberately not in this commit: it fails every AI run until enforcement is restored, so it has to land with the fix in #487. Refs #487, #456
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
WalkthroughThe changes update repository and workflow security documentation. They state that ChangesEgress control documentation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Preview DeploymentPreview URL: https://fca5dac4.bestax.pages.dev |
|
🎉 This PR is included in version 5.8.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 4.0.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 2.0.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Comment-only. Makes the workflow files stop asserting a security control that is not running.
Why
While carrying out #456's audit-to-block obligation I found that harden-runner has never
enforced
egress-policy: blockin this repo. It arms block mode by reading an Actions cacheentry; GitHub made that cache read-only for untrusted triggers (
issues,issue_comment,pull_request, i.e. all of these workflows), and an unguardednew URL()on the resulting missfails open to
audit, announcing it with onecore.infoline. Evidence, root cause from thepinned action source, the measured endpoint list and the fix are in #487.
So three files described a control that does not exist, and the review checklist in
.github/CLAUDE.mdends on exactly that failure mode: "Security comments claim exactly what themechanism delivers. No more."
What changes
Nothing executable. No
egress-policyvalue, nopermissions:block, no allowlist, no logic.Verified by parsing all three workflows after the edit: same jobs, same policy values
(
ai-scanblock,claude-reproblock,ai-triageaudit).claude-repro.ymlai-scan.yml.github/CLAUDE.mdblockas the resting state without noting it is inert here.ai-triage.ymlThe
ai-triagecomment gains something concrete in its place: a real session reaches nine hostsand the allowlist is missing three of them (
claude.ai,downloads.claude.ai, and the CLI'stelemetry endpoint), so that flip would have broken triage at the Claude CLI download rather than
hardening it. The original decision in #361 to introduce this job at
auditwas right, for abetter reason than the one recorded at the time.
Declared policies and allowlists are left untouched so that closing #487 needs no edit here.
Not in this PR, on purpose
The fail-closed guard that would catch a future silent downgrade. harden-runner writes its
effective config after the downgrade decision, so this works:
jq -e '.egress_policy == "block"' /home/agent/agent.jsonIt fails every AI run until enforcement is actually restored, which is the entire point of it, so
it has to land with the fix in #487 rather than ahead of it.
Review notes
.github/CLAUDE.md: this touches the I1 rationale and rule 10, which ismiddle-row ("name the invariant at stake, confirm it holds, then act"). I1 itself is unchanged
and still holds. Its two remaining legs, no execution primitive in the drafting job and the
token never sharing a job with
publish, are both real and both verified in the Post-merge obligations for the AI repro + security-scan automation (#361) #456 canary.What changed is the description, which had a third leg that was never load-bearing.
open since 2026-07-14 with no maintainer response.
Refs #487, #456
Summary by CodeRabbit