From 133666f8b81842e3e3ba5bb3a734a9e5bc30919f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 9 Jul 2026 01:28:08 +0900 Subject: [PATCH] ci: harden security-scanning workflows (least-privilege tokens + SHA-pinned actions) Resolves the OPEN Scorecard code-scanning alerts that point at workflow files by applying the secure fix directly (repo already SHA-pins other actions; these were the gaps). Token-Permissions (least-privilege GITHUB_TOKEN): - Alert #5 security-process.yml: drop top-level `security-events: write` and `actions: read`; grant `security-events: write`/`actions: read` only on the trivy-fs job that uploads SARIF. appguardrail-scan keeps `contents: read`. - Alerts #3, #4 prepare-pypi-release.yml: top-level token reduced to `contents: read`; `actions: write`/`contents: write`/`pull-requests: write` moved to the single prepare-release job (all are required by its dispatch/commit/PR steps). Pinned-Dependencies (pin actions by commit SHA): - Alert #7 security-process.yml: aquasecurity/trivy-action v0.36.0 -> ed142fd0673e97e23eac54620cfb913e5ce36c25 - Alert #8 security-process.yml: github/codeql-action/upload-sarif v4 -> 99df26d4f13ea111d4ec1a7dddef6063f76b97e9 (v4.37.0) - Alert #6 org-security-failure-collector.yml: actions/create-github-app-token v3 -> bcd2ba49218906704ab6c1aa796996da409d3eb1 (v3.2.0) These alerts auto-close on the next Scorecard run against develop. No runtime/Python code changed; workflow behaviour is unchanged. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P --- .../workflows/org-security-failure-collector.yml | 2 +- .github/workflows/prepare-pypi-release.yml | 9 ++++++--- .github/workflows/security-process.yml | 13 +++++++++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/org-security-failure-collector.yml b/.github/workflows/org-security-failure-collector.yml index c4b7667..9b7e99b 100644 --- a/.github/workflows/org-security-failure-collector.yml +++ b/.github/workflows/org-security-failure-collector.yml @@ -53,7 +53,7 @@ jobs: - name: Create org installation token if: steps.app-config.outputs.configured == 'true' id: app-token - uses: actions/create-github-app-token@v3 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ env.ORG_SECURITY_FAILURE_APP_ID }} private-key: ${{ env.ORG_SECURITY_FAILURE_APP_PRIVATE_KEY }} diff --git a/.github/workflows/prepare-pypi-release.yml b/.github/workflows/prepare-pypi-release.yml index 0725ec1..4cf80e8 100644 --- a/.github/workflows/prepare-pypi-release.yml +++ b/.github/workflows/prepare-pypi-release.yml @@ -18,14 +18,17 @@ on: default: PyPI Trusted Publishing release prepared by GitHub Actions Bot. type: string +# Least-privilege top-level token; the single job below elevates only what it needs. permissions: - actions: write - contents: write - pull-requests: write + contents: read jobs: prepare-release: runs-on: ubuntu-latest + permissions: + actions: write # dispatch security-process.yml on the release branch + contents: write # commit/push the release branch + pull-requests: write # open/update the release PR env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true RELEASE_VERSION: ${{ inputs.version }} diff --git a/.github/workflows/security-process.yml b/.github/workflows/security-process.yml index bc38d48..004f9f9 100644 --- a/.github/workflows/security-process.yml +++ b/.github/workflows/security-process.yml @@ -9,14 +9,15 @@ on: - cron: "31 4 * * 1" workflow_dispatch: +# Least-privilege top-level token; write scopes are granted per-job below. permissions: contents: read - security-events: write - actions: read jobs: appguardrail-scan: runs-on: ubuntu-latest + permissions: + contents: read env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: @@ -53,6 +54,10 @@ jobs: trivy-fs: runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + actions: read env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: @@ -60,7 +65,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Run Trivy FS scan - uses: aquasecurity/trivy-action@v0.36.0 + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: fs scan-ref: . @@ -77,7 +82,7 @@ jobs: && hashFiles('trivy-results.sarif') != '' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: sarif_file: trivy-results.sarif