From 7b618955f8b76ccdd04b71547f27a98d6435624a Mon Sep 17 00:00:00 2001 From: forkwright Date: Mon, 24 Aug 2026 20:09:55 -0500 Subject: [PATCH] ci(security): add CodeQL static analysis CodeQL ran in three of twelve fleet repos. This repo was not one of them, so nothing read its source for injection, unsafe patterns or over-broad workflow permissions -- cargo audit, cargo deny and OSV all read the dependency list rather than the code. Two jobs, matching the fleet form: analyze-actions scans the workflow definitions themselves -- untrusted input reaching a run block, permissions wider than needed, unpinned references. Applies to any repo with workflows. analyze-rust scans the crate source. Copied from aletheia rather than from workflow/templates/ci/codeql.yml, which is the stalest copy of this file in the fleet (kanon#3644). The template carries no timeout-minutes on either job -- so a hung CodeQL run reaches GitHub's six-hour default -- pins an older actions/checkout, and sets `permissions: {}` where aletheia states an explicit default-deny with its reasoning attached. Sourcing eight repos from the template would have planted those three regressions everywhere at once. Asserted before writing that every job carries a timeout, because that is the specific thing the template is missing and the specific thing nobody notices until a job has been running for six hours. Free on a public repository, and scheduled weekly rather than per-PR so it adds no latency to the merge path. Gate-Passed: kanon 0.13.0 +stages:fmt,check,clippy,nextest,lint sha:a0863c73cab7a4320a7a15aff6dd882b68971fa5 --- .github/workflows/codeql.yml | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..a2c74d7 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ + + +name: CodeQL + +on: + push: + branches: [main] + schedule: + - cron: "0 14 * * 3" # Wednesday 08:00 CST + +# PROJECT: explicit top-level default deny; job-level permissions grant only what's needed +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + analyze-actions: + name: Analyze (actions) + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + security-events: write + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false # PROJECT: security hardening — never expose token to steps + - name: Initialize CodeQL + uses: github/codeql-action/init@dd677812177e0c29f9c970a6c58d8607ae1bfefd # v4 + with: + languages: actions + queries: +security-extended + - name: Autobuild + uses: github/codeql-action/autobuild@dd677812177e0c29f9c970a6c58d8607ae1bfefd # v4 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@dd677812177e0c29f9c970a6c58d8607ae1bfefd # v4 + with: + category: /language:actions