From 129b4c8aef40e5766e25b61d4776a7ab93dff145 Mon Sep 17 00:00:00 2001 From: hasansezertasan Date: Thu, 23 Jul 2026 19:10:08 +0300 Subject: [PATCH 1/2] ci: adopt zizmor and harden GitHub Actions workflows Add zizmor (as a pre-commit hook, which runs in the existing validate CI job) to statically analyze GitHub Actions, and resolve every finding it reports: - Pin all third-party and first-party actions to full commit SHAs (unpinned-uses), with the version tag kept as a trailing comment. - Set persist-credentials: false on every checkout (artipacked). - Add top-level 'permissions: {}' with least-privilege per-job grants (excessive-permissions). - Disable uv caching on the release-triggered docs and publish workflows (cache-poisoning). - Replace the archived sonarsource/sonarcloud-github-action@master with SonarSource/sonarqube-scan-action, pinned to v6 (v4-v5 are vulnerable to argument injection, GHSA-5xq9-5g24-4g6f) and add SONAR_HOST_URL for SonarQube Cloud. - Bump github/codeql-action from the retired v2 to v3. - Add a 7-day dependabot cooldown (dependabot-cooldown), mirroring the uv exclude-newer policy. Closes #22 --- .github/dependabot.yaml | 4 ++++ .github/workflows/ci.yaml | 38 +++++++++++++++++++++++++--------- .github/workflows/codeql.yml | 10 ++++++--- .github/workflows/docs.yaml | 12 +++++++---- .github/workflows/publish.yaml | 12 +++++++---- .github/workflows/test.yaml | 12 ++++++++--- .pre-commit-config.yaml | 4 ++++ 7 files changed, 68 insertions(+), 24 deletions(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 1230149..3419030 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -4,3 +4,7 @@ updates: directory: "/" schedule: interval: "daily" + # Wait a week before proposing a newly-published version, mirroring the uv + # `exclude-newer` policy. Reduces exposure to compromised fresh releases. + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d46a283..79d2d97 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,13 +6,19 @@ on: branches: - main +permissions: {} + jobs: validate: runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.11" @@ -21,7 +27,7 @@ jobs: - name: Load cached Pre-Commit Dependencies id: cached-pre-commit-dependencies - uses: actions/cache@v3 + uses: actions/cache@6f8efc29b200d32929f49075959781ed54ec270c # v3 with: path: ~/.cache/pre-commit/ key: pre-commit-|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }} @@ -33,6 +39,8 @@ jobs: run: pre-commit run --show-diff-on-failure --color=always --all-files test: + permissions: + contents: read strategy: fail-fast: true matrix: @@ -43,6 +51,8 @@ jobs: coverage: ${{ matrix.python-version == '3.11' }} test-platform-compat: + permissions: + contents: read if: github.event_name == 'push' strategy: fail-fast: true @@ -57,22 +67,27 @@ jobs: needs: - test - validate + permissions: + contents: read if: github.event.pull_request.head.repo.fork == false && github.repository_owner == 'litestar-org' runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - name: Download Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: coverage-xml - name: Fix coverage file for sonarcloud run: sed -i "s/home\/runner\/work\/litestar\/litestar/github\/workspace/g" coverage.xml - - name: SonarCloud Scan - uses: sonarsource/sonarcloud-github-action@master + - name: SonarQube Cloud Scan + uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: https://sonarcloud.io codeql: needs: @@ -80,14 +95,17 @@ jobs: - validate runs-on: ubuntu-latest permissions: + contents: read security-events: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - name: Initialize CodeQL Without Dependencies - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 with: setup-python-dependencies: false languages: python - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ed42fa8..b56d17c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,19 +4,23 @@ on: schedule: - cron: "0 4 * * *" +permissions: {} + jobs: codeql: runs-on: ubuntu-latest permissions: + contents: read security-events: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: ref: "main" + persist-credentials: false - name: Initialize CodeQL With Dependencies - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@4187e74d05793876e9989daffde9c3e66b4acd07 # v3 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index a058908..7db7f88 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -4,19 +4,23 @@ on: release: types: [published] +permissions: {} + jobs: docs: permissions: contents: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@v8.3.2 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: python-version: "3.11" - enable-cache: true + enable-cache: false - name: Install dependencies run: uv sync --all-groups @@ -28,6 +32,6 @@ jobs: run: uv run python tools/build_docs.py docs-build - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4 + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 with: folder: docs-build diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 02c74ce..3b59037 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -4,6 +4,8 @@ on: release: types: [published] +permissions: {} + jobs: publish-release: runs-on: ubuntu-latest @@ -11,16 +13,18 @@ jobs: id-token: write steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@v8.3.2 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: python-version: "3.11" - enable-cache: true + enable-cache: false - name: Build package distributions run: uv build - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # release/v1 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index aaa8d46..2c0f054 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -15,19 +15,25 @@ on: type: string default: "ubuntu-latest" +permissions: {} + jobs: test: runs-on: ${{ inputs.os }} timeout-minutes: 10 + permissions: + contents: read defaults: run: shell: bash steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@v8.3.2 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: python-version: ${{ inputs.python-version }} enable-cache: true @@ -43,7 +49,7 @@ jobs: if: inputs.coverage run: uv run pytest docs/examples tests --cov=project_template --cov-report=xml - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: inputs.coverage with: name: coverage-xml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a1fa0b..b1b384d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,10 @@ repos: rev: 0.11.31 hooks: - id: uv-lock + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.28.0 + hooks: + - id: zizmor - repo: https://github.com/charliermarsh/ruff-pre-commit rev: "v0.0.290" hooks: From 303a4d93c97f210ff4113ea0ec9352bd31d435cb Mon Sep 17 00:00:00 2001 From: hasansezertasan Date: Thu, 23 Jul 2026 19:14:41 +0300 Subject: [PATCH 2/2] ci: add dedicated zizmor workflow with Advanced Security Add .github/workflows/zizmor.yml using zizmorcore/zizmor-action to upload zizmor findings as SARIF to the GitHub Security tab for stateful, incremental triage. Complements the blocking pre-commit hook, which provides the hard CI gate and local developer feedback. Refs #22 --- .github/workflows/zizmor.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..c54d5b3 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,25 @@ +name: GitHub Actions Security Analysis + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: {} + +jobs: + zizmor: + runs-on: ubuntu-latest + permissions: + security-events: write # upload SARIF results to the Security tab + contents: read # only needed for private or internal repos + actions: read # only needed for private or internal repos + steps: + - name: Checkout repository + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + + - name: Run zizmor 🌈 + uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0