From 811083fc74edb42b087d98205d841bf58081521d Mon Sep 17 00:00:00 2001 From: Kyle Cox Date: Fri, 16 Oct 2026 02:49:09 +0000 Subject: [PATCH 1/3] feat(ci): add CodeQL static analysis workflow (#298) Adds .github/workflows/codeql.yml analysing javascript-typescript with build-mode none on push and pull_request to main plus a weekly Monday schedule, using actions/checkout@v6 and github/codeql-action@v4 with least-privilege permissions. TRIAGE.md gains a Security scanning section covering Dependabot and CodeQL triage. Validated with actionlint. --- .github/workflows/codeql.yml | 53 ++++++++++++++++++++++++++++++++++++ TRIAGE.md | 9 ++++++ 2 files changed, 62 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..de58e03 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,53 @@ +name: "CodeQL" + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + # Weekly, Mondays at 06:30 UTC + - cron: "30 6 * * 1" + +permissions: + contents: read + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + # Required to upload results to code scanning + security-events: write + # Required to fetch internal or private CodeQL packs + packages: read + # Required in private repositories to read the status of Actions runs + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: javascript-typescript + # JavaScript/TypeScript is extracted directly from source, so no + # build step is needed (the Docusaurus site in website/ included). + build-mode: none + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{ matrix.language }}" diff --git a/TRIAGE.md b/TRIAGE.md index e0ce1fa..88c31b7 100644 --- a/TRIAGE.md +++ b/TRIAGE.md @@ -48,6 +48,15 @@ The [`stale.yml`](.github/workflows/stale.yml) workflow enforces the inactivity - Items labelled `pinned` or `Security` are never marked stale. - Any comment or update resets the clock. +## Security scanning + +Two automated scanners run on this repository, and their findings are triaged in the same weekly session as issues and PRs: + +- **Dependabot** (`.github/dependabot.yml`) — checks npm dependencies in `website/` and the GitHub Actions used by the workflows, weekly on Mondays. Alerts and update PRs appear under **Security → Dependabot** and as `dependencies`-labelled PRs. +- **CodeQL** (`.github/workflows/codeql.yml`) — static analysis (SAST) of the JavaScript/TypeScript sources on every push and pull request to `main`, plus a weekly scheduled run on Mondays. Results appear under **Security → Code scanning**. + +Items labelled `Security` are never marked stale (see automation above), so a scanning alert stays visible until a maintainer closes it as fixed or dismissed with a reason. + ## Roles - **Triagers**: Developer Advocates and the repository maintainers listed in [CODEOWNERS](CODEOWNERS). From b761d2a6c491dee24112dd0791c91f57fc73d7a3 Mon Sep 17 00:00:00 2001 From: IanoNjuguna Date: Sun, 18 Oct 2026 11:33:01 +0300 Subject: [PATCH 2/3] ci(codeql): constrain the run and trim the token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add a concurrency group so a newer run on the same ref cancels the one it supersedes. Without it, pushes in quick succession queue redundant analyses and an older run can finish last and publish stale check status. - Check out with persist-credentials: false. The analysis never pushes, so there is no reason to leave the GITHUB_TOKEN in .git/config for the rest of the job. - Drop the packages: read and actions: read job scopes. The CodeQL starter template marks both as required only in private repositories; this repo is public, so they widened the token for nothing. contents: read and security-events: write are what the job actually uses. TRIAGE.md also notes that CodeQL covers source only — workflow and configuration files under .github/ remain a manual review item. --- .github/workflows/codeql.yml | 11 +++++++---- TRIAGE.md | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index de58e03..3db063c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,6 +14,10 @@ on: permissions: contents: read +concurrency: + group: codeql-${{ github.ref }} + cancel-in-progress: true + jobs: analyze: name: Analyze (${{ matrix.language }}) @@ -22,10 +26,6 @@ jobs: permissions: # Required to upload results to code scanning security-events: write - # Required to fetch internal or private CodeQL packs - packages: read - # Required in private repositories to read the status of Actions runs - actions: read contents: read strategy: @@ -40,6 +40,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 + with: + # The analysis never pushes, so keep the token out of .git/config. + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v4 diff --git a/TRIAGE.md b/TRIAGE.md index 88c31b7..c4339da 100644 --- a/TRIAGE.md +++ b/TRIAGE.md @@ -53,7 +53,7 @@ The [`stale.yml`](.github/workflows/stale.yml) workflow enforces the inactivity Two automated scanners run on this repository, and their findings are triaged in the same weekly session as issues and PRs: - **Dependabot** (`.github/dependabot.yml`) — checks npm dependencies in `website/` and the GitHub Actions used by the workflows, weekly on Mondays. Alerts and update PRs appear under **Security → Dependabot** and as `dependencies`-labelled PRs. -- **CodeQL** (`.github/workflows/codeql.yml`) — static analysis (SAST) of the JavaScript/TypeScript sources on every push and pull request to `main`, plus a weekly scheduled run on Mondays. Results appear under **Security → Code scanning**. +- **CodeQL** (`.github/workflows/codeql.yml`) — static analysis (SAST) of the JavaScript/TypeScript sources on every push and pull request to `main`, plus a weekly scheduled run on Mondays. Results appear under **Security → Code scanning**. CodeQL reads source only: workflow and configuration files under `.github/` are not covered by this scan and stay a manual review item. Items labelled `Security` are never marked stale (see automation above), so a scanning alert stays visible until a maintainer closes it as fixed or dismissed with a reason. From 967955d17393b3abb000b8a7b7f47300069e595c Mon Sep 17 00:00:00 2001 From: IanoNjuguna Date: Sun, 18 Oct 2026 11:35:06 +0300 Subject: [PATCH 3/3] chore: drop the stray .claude worktree gitlinks Three paths under .claude/worktrees were committed as submodule gitlinks without any .gitmodules entry, so every `git submodule foreach` in a workflow ends in "fatal: No url found for submodule path" and exit 128. actions/checkout runs exactly that when persist-credentials is disabled, which made the CodeQL job fail on checkout once the token hardening went in. .claude/ is already gitignored, so these entries were accidental; removing them from the index leaves any local worktrees on disk untouched. --- .claude/worktrees/amazing-mendel | 1 - .claude/worktrees/determined-agnesi | 1 - .claude/worktrees/youthful-goldwasser-0b985f | 1 - 3 files changed, 3 deletions(-) delete mode 160000 .claude/worktrees/amazing-mendel delete mode 160000 .claude/worktrees/determined-agnesi delete mode 160000 .claude/worktrees/youthful-goldwasser-0b985f diff --git a/.claude/worktrees/amazing-mendel b/.claude/worktrees/amazing-mendel deleted file mode 160000 index b6bac04..0000000 --- a/.claude/worktrees/amazing-mendel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b6bac040c4ede6b797ec03de1e43244c8e10f4dd diff --git a/.claude/worktrees/determined-agnesi b/.claude/worktrees/determined-agnesi deleted file mode 160000 index 2c73fd4..0000000 --- a/.claude/worktrees/determined-agnesi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2c73fd4e30f186bedfb58bd9fdd0e39618e446df diff --git a/.claude/worktrees/youthful-goldwasser-0b985f b/.claude/worktrees/youthful-goldwasser-0b985f deleted file mode 160000 index 2c73fd4..0000000 --- a/.claude/worktrees/youthful-goldwasser-0b985f +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2c73fd4e30f186bedfb58bd9fdd0e39618e446df