From 7c456abbdef898b838d9f8a29a45fd4a0b958e00 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Tue, 25 Aug 2026 22:34:21 -0400 Subject: [PATCH] ci: fix zizmor findings in GitHub Actions workflows Follow-up to the zizmor workflow added in the previous commit: addresses the findings it surfaces across the existing workflows now that the scan is in place. - Sets persist-credentials explicitly on every checkout: false where the job never pushes, true (with a comment) where it does and genuinely needs the persisted credential. - Disables setup-go's default caching in the container-build job that publishes runtime artifacts, per zizmor's cache-poisoning audit. - Swaps the spoofable github.actor bot check in skill-version-check.yml for github.event.pull_request.user.login. - Suppresses the dangerous-triggers finding on the two workflow_run based report workflows with a documented rationale: neither checks out or executes the triggering run's code, and the only untrusted value they consume (a PR number read from an artifact) only affects which PR gets commented on. With the zizmor workflow gating on medium+ severity only, this clears everything at that threshold. The remaining low/informational findings (template-injection warnings on already-scoped env values, one ad-hoc npm install) are left as-is. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/build-containers.yml | 8 ++++++++ .github/workflows/build-skills.yml | 7 +++++++ .github/workflows/ci.yml | 6 +++++- .github/workflows/mcp-scan-report.yml | 9 ++++++++- .github/workflows/periodic-security-scan.yml | 4 ++++ .github/workflows/renovate-validation.yml | 6 +++++- .github/workflows/skill-scan-report.yml | 9 ++++++++- .github/workflows/skill-version-check.yml | 7 +++++-- 8 files changed, 50 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 84c4ebf1..747746f3 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -60,6 +60,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # Need full history for change detection + persist-credentials: false - name: Find configuration files to build id: find-configs @@ -197,6 +198,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 @@ -268,6 +271,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -431,11 +436,14 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: 'go.mod' + cache: false - name: Set up QEMU uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 diff --git a/.github/workflows/build-skills.yml b/.github/workflows/build-skills.yml index eb2a0288..7a27898d 100644 --- a/.github/workflows/build-skills.yml +++ b/.github/workflows/build-skills.yml @@ -56,6 +56,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 + persist-credentials: false - name: Find skill configurations to build id: find-configs @@ -182,6 +183,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 @@ -212,6 +215,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install yq uses: mikefarah/yq@c14f446382944492701b16c1ddb48bb9dbe683e3 # v4.53.6 @@ -398,6 +403,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ce7fdab..f434f683 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 @@ -40,6 +42,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 @@ -60,4 +64,4 @@ jobs: run: go mod download - name: Build - run: go build -v ./cmd/dockhand \ No newline at end of file + run: go build -v ./cmd/dockhand diff --git a/.github/workflows/mcp-scan-report.yml b/.github/workflows/mcp-scan-report.yml index 82a29c9a..4857b5f0 100644 --- a/.github/workflows/mcp-scan-report.yml +++ b/.github/workflows/mcp-scan-report.yml @@ -1,10 +1,17 @@ # This workflow runs in the context of the base repository and has write access # to post PR comments, even for PRs from forks. It triggers after the main # build-containers workflow completes and downloads scan result artifacts. +# +# `workflow_run` is required for that base-repo write access; the trade-off it +# flags is a privileged workflow trusting event data from an untrusted run. +# This workflow never checks out or executes the triggering run's code, and +# the only value it takes from it (the PR number, read from an artifact) is +# used solely to target the comment, so a bad value means a comment lands on +# the wrong PR, not privilege escalation. name: MCP Scan Report on: - workflow_run: + workflow_run: # zizmor: ignore[dangerous-triggers] workflows: ["Build MCP Server Containers"] types: [completed] diff --git a/.github/workflows/periodic-security-scan.yml b/.github/workflows/periodic-security-scan.yml index ff156fe5..72000d7d 100644 --- a/.github/workflows/periodic-security-scan.yml +++ b/.github/workflows/periodic-security-scan.yml @@ -21,6 +21,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Find all configuration files id: find-configs @@ -50,6 +52,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install yq uses: mikefarah/yq@c14f446382944492701b16c1ddb48bb9dbe683e3 # v4.53.6 diff --git a/.github/workflows/renovate-validation.yml b/.github/workflows/renovate-validation.yml index 606cbbe1..f7a373ea 100644 --- a/.github/workflows/renovate-validation.yml +++ b/.github/workflows/renovate-validation.yml @@ -40,6 +40,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -84,6 +86,8 @@ jobs: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -105,4 +109,4 @@ jobs: "$GITHUB_REPO" || { echo "::warning::Dry run failed. This might be due to missing permissions or configuration issues." exit 0 - } \ No newline at end of file + } diff --git a/.github/workflows/skill-scan-report.yml b/.github/workflows/skill-scan-report.yml index ccaa89cc..5c75cac6 100644 --- a/.github/workflows/skill-scan-report.yml +++ b/.github/workflows/skill-scan-report.yml @@ -1,10 +1,17 @@ # Runs in the base repository context so it can comment on PRs from forks. # Triggered after Build Skill Artifacts completes; downloads scan artifacts # and upserts a single "Skill Security Scan Results" PR comment. +# +# `workflow_run` is required for that base-repo write access; the trade-off it +# flags is a privileged workflow trusting event data from an untrusted run. +# This workflow never checks out or executes the triggering run's code, and +# the only value it takes from it (the PR number, read from an artifact) is +# used solely to target the comment, so a bad value means a comment lands on +# the wrong PR, not privilege escalation. name: Skill Scan Report on: - workflow_run: + workflow_run: # zizmor: ignore[dangerous-triggers] workflows: ["Build Skill Artifacts"] types: [completed] diff --git a/.github/workflows/skill-version-check.yml b/.github/workflows/skill-version-check.yml index 3fb1ec5b..31b836ec 100644 --- a/.github/workflows/skill-version-check.yml +++ b/.github/workflows/skill-version-check.yml @@ -72,8 +72,8 @@ jobs: runs-on: ubuntu-latest # Only apply the auto-fix for the Renovate bot. if: > - github.actor == 'renovate[bot]' || - github.actor == 'dependabot[bot]' + github.event.pull_request.user.login == 'renovate[bot]' || + github.event.pull_request.user.login == 'dependabot[bot]' # No GITHUB_TOKEN access — the push uses a GitHub App installation token # (see the "Generate GitHub App token" step below). Going through the App # is required because commits made with the default GITHUB_TOKEN do not @@ -104,6 +104,9 @@ jobs: # Use the head ref directly so we can push to it. ref: ${{ github.event.pull_request.head.ref }} token: ${{ steps.app-token.outputs.token }} + # This job pushes a commit at the end (see "Commit version bumps" + # below), so the checkout credential must stay persisted. + persist-credentials: true - name: Set up Go uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0