Skip to content

feat(audit): report-only org-wide actions-conformance audit (#19, #7) - #27

Merged
bdelanghe merged 1 commit into
mainfrom
claude/actions-audit
Jul 9, 2026
Merged

feat(audit): report-only org-wide actions-conformance audit (#19, #7)#27
bdelanghe merged 1 commit into
mainfrom
claude/actions-audit

Conversation

@bdelanghe

Copy link
Copy Markdown
Contributor

What

A report-only, org-wide actions-conformance auditscripts/audit/actions.ts (Deno) + actions-audit.yml. It's the enforcement layer for the outer-set normalization (.github#57/#58): the whole point of routing repos through pinned reusable workflows is undone if nothing catches drift.

The rules

Rule Checks Why
R1a org reusable workflow on a floating branch (@main) hard tamper risk — a mutable ref runs in every caller's context
R1b org reusable workflow on a tag (@vX) mutable in principle; prefer SHA (soft/informational)
R3 external action not SHA-pinned org sha_pinning_required
R2 third-party actions outside the canonical set sprawl — indirection candidates

The canonical set is derived live from .github's repo-*.yml, so it self-updates as the reusable workflows grow — no hand-maintained list.

Baseline today (report-only, exit 0)

  • R1a = 16all gh-project-room/…/trigger-sync.yml@main (the front-desk notify pattern). The one genuinely worth fixing.
  • R1b = 72 — mostly mint/{release-provenance,version}.yml@v0.3.1. This is the intentional semver-tracking pattern — a policy call, not a bug.
  • R3 = 5 — genuine unpinned external actions (e.g. prx/pages.yml configure-pages@v6).
  • R2 = 15 — third-party sprawl (the clusters we've been consolidating).

Phased promotion

Report-only now (baseline the current state, like scripts/audit.mjs). Flip deno task audit:actionsaudit:actions:strict to make it fail on R1a + R3 (the hard, objective rules) once the 16 floating-branch refs are pinned. R1b/R2 stay informational.

Dogfooding

actions-audit.yml is bespoke (runs a Deno audit, like conformance-gate.yml) but SHA-pins its own actions — it passes its own R3.

PR checklist

  1. Independent PR — the audit only; fixes to the findings are separate
  2. Verified — runs locally (R1a=16/R1b=72/R3=5/R2=15, exit 0); fmt+lint+cspell clean; CI green on this PR
  3. Root cause — normalization needs an enforcement layer or it re-sprawls
  4. No duplication — canonical set derived from .github, not re-listed
  5. No unrelated changes

Advances #19 and the enforcement epic #7.

🤖 Generated with Claude Code

scripts/audit/actions.ts scans every repo's workflows against:
  R1a floating-branch ref to an org reusable workflow (hard tamper risk)
  R1b tag ref to an org reusable workflow (mutable; prefer SHA)
  R3  external action not SHA-pinned (org sha_pinning)
  R2  third-party actions outside the canonical reusable-workflow set (sprawl)

The canonical set is derived from .github's repo-*.yml, so it self-updates as the
reusable workflows grow. Report-only (exit 0), wired as actions-audit.yml on a daily
schedule + dispatch; promote to blocking via `audit:actions:strict` (fails on R1a+R3)
once the floating-branch refs are cleaned up.

Baseline today: R1a=16 (all gh-project-room trigger-sync@main), R1b=72 (mostly mint
release/version @vx — a semver-tracking policy call), R3=5, R2=15.

Enforcement layer for the outer-set normalization (#57/#58): keeps the canonical set
small by flagging any repo that introduces an unpinned or off-catalog action.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bdelanghe
bdelanghe marked this pull request as ready for review July 9, 2026 00:17
@bdelanghe
bdelanghe merged commit 96589af into main Jul 9, 2026
12 checks passed
@bdelanghe
bdelanghe deleted the claude/actions-audit branch July 9, 2026 00:17
@bounded-systems-front-desk bounded-systems-front-desk Bot moved this from Todo to Done in Front Desk Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant