Skip to content

Gate PRs on zizmor's online audits, audit dependabot.yml, rename the CI lock, guard workflow PR approval - #233

Merged
seathatflowsinourveins merged 1 commit into
mainfrom
claude/gh-hardening-20260925
Sep 25, 2026
Merged

seathatflowsinourveins merged 1 commit into
mainfrom
claude/gh-hardening-20260925

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator

Summary

Implements the verified gaps from the 2026-09-25 GitHub audit for this repository. The workflow YAML and dependabot.yml changes are in this one PR. No live repository setting is changed. The decision records are the new section "GitHub hardening follow-up (2026-09-25)" in docs/decisions/2026-09-22-github-automation-closure.md and "Approval guard (2026-09-25)" in docs/decisions/2026-09-23-bot-pr-dispatch.md.

Gap Change
ACT-14 (medium): zizmor's online audits never block a PR validate.yml's required zizmor step gets GH_TOKEN: ${{ github.token }} and drops --offline, so impostor-commit, known-vulnerable-actions, ref-confusion and ref-version-mismatch findings fail validate. No scope is added. ValidateZizmorGateTests pins the token line and forbids --offline, --no-exit-codes, SARIF output and continue-on-error, because zizmor 1.30.1 with no token silently falls back to offline mode and exits 0. This overturns closure section 4's rejected "online PR gate": 90 zizmor analyses on main, 0 results.
ACT-14 (low): CI zizmor never audits dependabot.yml Both zizmor runs (validate.yml and security-scan.yml's zizmor-online) now audit .. New DependabotConfigSecurityCoverageTests: the file passes, and a copy without cooldown exits 13 with dependabot-cooldown.
ACT-03: undocumented job-level grants Same-line # why comments on the 5 grants in catalog-freshness.yml (propose) and saturation-tracking.yml. test_saturation_ledger.py now compares through scopes(). At pedantic persona, zizmor's undocumented-permissions findings go from 4 to 0.
ACT-04: workflows could approve PRs The can_approve_pull_request_reviews setting stays on, because propose needs it for gh pr create. New NoWorkflowApprovesPullRequestsTests allows pull-requests: write only on catalog-freshness.yml:propose and allows no actions: write. It fails on any review/approve call, on write-all and on inline permissions. The overturn condition is recorded: move to an App token before requiring approvals.
DEP-03: dependency graph cannot see the CI lock Renamed .github/requirements-ci.lock to .github/requirements-ci.txt (byte-identical, same SHA-256). Live references are updated; pip version updates stay off. The post-merge SBOM check and its fallback are in section 8. OSV-Scanner is recorded as the only alert path for the NuGet and .lock-named pip locks.
DEP-01: npm/uv/NuGet omission unrecorded Documentation only: the dependabot.yml header, a section 8 bullet with an overturn condition, and the ownership sentence in docs/github-automation.md.
ACT-12: fork PR approval is first-time only The decision is recorded. The owner applies the gh api -X PUT ... approval_policy=all_external_contributors command given in the record; this PR does not change the setting.

Kept as decided (not edited):

  • blueprints/convergence-practice/ci-security/qualified-workflow.yml.txt is a hash-bound experiment input.
  • The historical commands in docs/github-automation-evidence.json stay as they were run.
  • The sealed lane text in catalogs/landscape/foundation.json, layer-verdicts-20260922.json and the handbook still names the old lock. The closure record corrects it until the next lane run.

The evidence hashes in manifests/evidence.json are refreshed for every registered file this PR edits.

Checks (local, this head)

Before merging, check that this PR's validate log has no zizmor "offline mode" warning.

🤖 Generated with Claude Code

…CI lock, guard workflow PR approval

Implements the verified 2026-09-25 GitHub audit gaps for this repository:

- validate.yml: the required zizmor step runs the online audits with the
  read-only job token and fails on findings (overturns closure section 4's
  rejected alternative); both zizmor runs audit "." so dependabot.yml is
  collected. Regression tests pin the token and forbid --offline.
- catalog-freshness.yml / saturation-tracking.yml: same-line comments on the
  5 job-level grants zizmor pedantic flagged; saturation test uses scopes().
- tests: cross-workflow guard that no workflow can approve a PR (the
  can_approve setting stays on for propose's gh pr create); dependabot.yml
  zizmor pass plus a no-cooldown failing control.
- .github/requirements-ci.lock -> requirements-ci.txt (byte-identical) so the
  dependency graph can see zizmor; pip version updates stay off.
- dependabot.yml header and closure section 8 record why npm/uv/NuGet have no
  version-update entry and that OSV-Scanner is the only alert path for
  graph-invisible locks.
- Fork PR approval: decision recorded; the owner applies the PUT (no live
  setting changed here).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​zizmor@​1.30.1100100100100100

View full report

@seathatflowsinourveins
seathatflowsinourveins merged commit 2768ddb into main Sep 25, 2026
24 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/gh-hardening-20260925 branch September 25, 2026 06:59
seathatflowsinourveins pushed a commit that referenced this pull request Sep 25, 2026
…y branch

evidence.json was rebuilt from main's copy. This branch's convergence-record
entry and its ten sim-capacity file registrations were re-applied. The CI lock
path this branch still carried was not re-registered, because #233 renamed it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
seathatflowsinourveins pushed a commit that referenced this pull request Sep 25, 2026
…porate-action and credential guards

Main moved 19 commits since 5ed8538. The conflicts were resolved by
keeping both sides:

- native_strategy.py: AdaptiveStrategy takes both halted= (E4) and
  corporate_action_guard= (#222). The constructor keeps the halt and
  callback-fault state and the corporate-action guard state.
  cancel_expired keeps the halted-exit skip (E4) and gains #222's
  symbols= immediate-cancel set.
- runner.py: the strategy gets both halted=controller.is_halted and the
  corporate-action guard. The shutdown runs stop_halt_seed() inside
  #222's try/finally, so the corporate-action refresh cleanup still runs
  if the halt-seed stop raises.
- source-hashes.json: the union of both sides' keys, every digest
  recomputed from the merged tree.
- manifests/evidence.json: main's registry, plus the branch's new
  engine-nautilus probe, with all stale digests refreshed. The branch's
  entries for the renamed CI lock (#233) and the renamed grype fixture
  (#224) are dropped.

Checks on the merged tree:
- pinned rc5 runtime, 23 paper modules: 1,320 tests OK (2 skipped);
- full python3 -m unittest: 4,944 tests OK (600 skipped);
- validate.py, evidence_manifest.py --check, and the source-hashes
  manifest test: pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
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