From 22b64543c3d92acff829e0fda768105b4c45e7d4 Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Mon, 1 Jun 2026 14:13:45 +0200 Subject: [PATCH] fix(workflows): restore persisted creds on caller checkout for open-pr The hardening commits in PRs #146 and #84 set `persist-credentials: false` on the calling-repo `actions/checkout` step. That broke PR creation because the `actions/open-pr` composite invokes `git push`, which only authenticates via the bearer token that `actions/checkout` writes into the remote URL. Without the persisted token the push fails with HTTP 403, as observed on https://github.com/DevSecNinja/wazzup/actions/runs/26754084476. Restore the default `persist-credentials: true` on the calling-repo checkout for both `config-sync.yml` and `vendored-file-sync.yml`. Suppress the resulting zizmor `artipacked` finding inline with a justification comment: - `config-sync.yml`: this job never executes content fetched from the central repo. It clones `DevSecNinja/.github` (with `persist-credentials: false`) and only `cp`-s files out of it, so persisted creds on the caller checkout cannot leak via that data path. - `vendored-file-sync.yml`: the caller-supplied `refresh-command` runs in this same job; the trust boundary is identical to any caller-owned step. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/config-sync.yml | 10 ++++++++-- .github/workflows/vendored-file-sync.yml | 9 ++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/config-sync.yml b/.github/workflows/config-sync.yml index 45fd006..a26134f 100644 --- a/.github/workflows/config-sync.yml +++ b/.github/workflows/config-sync.yml @@ -42,9 +42,15 @@ jobs: pull-requests: write steps: - name: Checkout calling repository + # zizmor: ignore[artipacked] + # Persisted credentials are required: the `actions/open-pr` step + # below invokes `git push` which relies on the bearer token that + # `actions/checkout` writes into the remote URL. Setting + # `persist-credentials: false` here breaks PR creation without + # offering meaningful isolation, since this job never executes + # content fetched from the central repo (it only reads files + # from `.config-sync-source/` to copy them). uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - name: Checkout central config source uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/vendored-file-sync.yml b/.github/workflows/vendored-file-sync.yml index 5ba7573..09f47d7 100644 --- a/.github/workflows/vendored-file-sync.yml +++ b/.github/workflows/vendored-file-sync.yml @@ -84,10 +84,17 @@ jobs: pr-url: ${{ steps.open-pr.outputs.pr-url }} steps: - name: Checkout code + # zizmor: ignore[artipacked] + # Persisted credentials are required: the `actions/open-pr` + # step below invokes `git push` which relies on the bearer + # token that `actions/checkout` writes into the remote URL. + # The caller-supplied `refresh-command` runs in this same job + # and could in theory exfiltrate the token, but the caller + # also controls the workflow that wires this input — so the + # trust boundary is the same as for any caller-owned step. uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - persist-credentials: false - name: Run vendored-file refresher env: