From e5b38a7e4275664dcf57a7b4a46fd55b1f681e87 Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Sun, 31 May 2026 23:40:46 -0400 Subject: [PATCH 1/2] =?UTF-8?q?ci(security):=20harden=20security=20workflo?= =?UTF-8?q?w=20=E2=80=94=20clear=20zizmor=20alerts=20#10=20&=20#11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves both open code-scanning alerts on .github/workflows/security.yml (zizmor 1.24.1, verified locally with `zizmor --persona=auditor`): - #11 secrets-inherit (warning): replace `secrets: inherit` — which hands the reusable workflow ALL of this repo's secrets — with named forwarding of just SEMGREP_APP_TOKEN (the only enabled token-consuming scanner). Enabled by resq-software/.github#21, which declares the secret under workflow_call.secrets; re-pinned to that workflow's new SHA (b48036af, #21). - #10 unpinned-uses (error): already SHA-pinned in #30; carried forward. Also clears two latent findings the stale scan predates: - excessive-permissions: drop workflow-level `permissions` to `{}` and move contents/security-events/pull-requests scopes onto the `scan` job, so they apply only to the reusable call. - undocumented-permissions: every scope now carries an explanatory comment. `zizmor --no-online-audits` reports "No findings" on the result. NOTE: this does not by itself explain the separate scheduled-run startup_failure (which persisted after the #30 pin); switching off `secrets: inherit` is the leading remaining hypothesis and this PR tests it. --- .github/workflows/security.yml | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 226e751..77c16cf 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -14,25 +14,27 @@ on: - cron: '17 6 * * 1' workflow_dispatch: -permissions: - contents: read - security-events: write - pull-requests: read +# No workflow-level permissions: the only job is a reusable-workflow call, +# and reusable callers must declare the forwarded scopes on the job itself. +permissions: {} jobs: scan: - # SHA-pinned to satisfy the org "actions must be pinned to a full-length - # commit SHA" policy. The previous mutable `@main` ref tripped the zizmor - # `unpinned-uses` code-scanning alert and is the most likely cause of the - # scheduled-run startup failures. Trailing comment lets Dependabot still - # propose updates. Matches the SHA-pin convention already used in ci.yml. - uses: resq-software/.github/.github/workflows/security-scan.yml@ee2001974be1e5610cff3a2c669cfab95c7415e7 # main (2026-05-04, #20) + # Scopes are set here (not workflow-level) so they apply only to the + # reusable call — avoids zizmor `excessive-permissions`. + permissions: + contents: read # checkout in the reusable's jobs + security-events: write # reusable uploads CodeQL/zizmor SARIF + pull-requests: read # reusable dependency-review reads PR diff + # SHA-pinned per org policy (mutable @main is rejected by zizmor + # unpinned-uses). Trailing comment keeps Dependabot updates working; + # matches the convention in ci.yml. + uses: resq-software/.github/.github/workflows/security-scan.yml@b48036af2c8f012f547979c29c819e1a19caf406 # main (2026-06-01, #21) with: languages: '["actions"]' enable-semgrep: true - # `inherit` is required here: the reusable workflow consumes org-level - # secrets (e.g. SEMGREP_APP_TOKEN) that are NOT declared in its - # `workflow_call.secrets` block, so they cannot be forwarded explicitly. - # Fully clearing the zizmor `secrets-inherit` warning needs an org-side - # `secrets:` declaration in security-scan.yml first (tracked separately). - secrets: inherit + # Forward only the secret this caller needs by name (semgrep is the only + # enabled token-consuming scanner) instead of `secrets: inherit`, which + # hands the reusable ALL of this repo's secrets — zizmor secrets-inherit. + secrets: + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} From cbb79c71de4e270101b6c85d2341e7adf76a77b9 Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Sun, 31 May 2026 23:43:51 -0400 Subject: [PATCH 2/2] fix(ci): grant actions:read so the security reusable can start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause of the security-workflow startup_failure (every run since 2026-05-04, 0 jobs executed): the reusable security-scan.yml's CodeQL and zizmor jobs request `actions: read` (added in resq-software/.github#20, 2026-05-04 — exactly when the failures began). A reusable workflow's jobs cannot request a permission the caller did not grant; GitHub rejects the entire run at startup. The prior #30 SHA-pin and the secrets-inherit removal did not fix it because neither granted actions:read. Add it to the scan job's permissions. --- .github/workflows/security.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 77c16cf..e87efd5 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -26,6 +26,10 @@ jobs: contents: read # checkout in the reusable's jobs security-events: write # reusable uploads CodeQL/zizmor SARIF pull-requests: read # reusable dependency-review reads PR diff + actions: read # reusable CodeQL + zizmor jobs request it; + # a reusable cannot exceed the caller's grant, + # so omitting this fails the run at startup + # SHA-pinned per org policy (mutable @main is rejected by zizmor # unpinned-uses). Trailing comment keeps Dependabot updates working; # matches the convention in ci.yml.