Skip to content

ci: add CodeQL code scanning - #97

Merged
dangrondahl merged 1 commit into
mainfrom
ci/codeql
Oct 23, 2026
Merged

dangrondahl merged 1 commit into
mainfrom
ci/codeql

Conversation

@dangrondahl

Copy link
Copy Markdown
Contributor

Closes #91.

What

.github/workflows/codeql.yaml, modelled on terraform-provider-kosli's. It includes the analyze job only.

  • Languages: javascript-typescript (src/, scripts/, test/) and actions (the workflows). Both use build-mode: none, so there's no build step.
  • Queries: security-extended.
  • Triggers: PRs and pushes to main, plus a weekly re-scan (Wednesdays 05:23 UTC).
  • Concurrency: superseded PR runs are cancelled. Runs on main aren't, so the code scanning baseline always gets its SARIF.
  • Permissions: contents: read at the top level. The job adds security-events: write and actions: read.
  • Repo conventions: SHA pins with version comments and harden-runner first, as in every other workflow here. It needs no secrets, so there's no fork guard. Dependabot's actions group will keep the pins current.
  • Docs: CLAUDE.md's workflow list goes from four to five.

codeql-action is pinned to v4.39.0, the provider's pin, rather than v4.39.1. v4.39.1 is two days old, which is inside the repo's 7-day cooldown; Dependabot will offer it.

Not in this PR (per #91)

  • Kosli attestation: the provider's attest job, which needs a Kosli flow and trail for this repo.
  • Required check: making CodeQL a required check in the main ruleset. Decide that after a few runs.

Checking it

  • actionlint passes on every workflow.
  • Unlike claude-review.yaml, this workflow runs on the PR that adds it, so this PR's own checks are the first scan. Look at Security → Code scanning afterwards, and fix or dismiss with a reason anything the first full scan raises (the issue's "done when").

Nothing in CI looked for security problems in the code itself, and code
scanning wasn't set up on the repo. This adds codeql.yaml, modelled on
terraform-provider-kosli's, analyze job only:

- javascript-typescript and actions, both build-mode none, with the
  security-extended queries. The actions language matters here: the review
  workflow runs an LLM with a token in scope.
- On PRs and pushes to main, plus a weekly baseline re-scan.
- Superseded PR runs are cancelled; runs on main are not, so the baseline
  always gets its SARIF.
- SHA-pinned with version comments, harden-runner first, as everywhere
  else here. It needs no secrets, so it runs on fork PRs unguarded.

codeql-action is pinned to v4.39.0 (the provider's pin), not v4.39.1, which
is two days old; the repo's 7-day cooldown applies, and Dependabot's actions
group will offer it.

The Kosli attestation job and making CodeQL a required check are left for
later, as the issue says.

Closes #91
@claude

claude Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Claude finished @dangrondahl's task in 2m 14s —— View job


Review: ci: add CodeQL code scanning

  • Read PR diff and CLAUDE.md invariants
  • Check workflow against repo conventions (SHA pins, harden-runner, permissions, fork safety)
  • Verify action pins and CodeQL config correctness
  • Check CI results
  • Post review

No blocking findings. I have no inline comments to leave.

What I checked

Repo conventions (CLAUDE.md "CI & repository rules")

  • All three uses: are full SHAs with # vX.Y.Z comments, and harden-runner / actions/checkout are pinned to the same SHAs already used by ci.yml, release.yml, update-catalog.yml and claude-review.yaml — so Dependabot's grouped actions PR will move them together rather than leaving this file behind.
  • step-security/harden-runner is the first step with egress-policy: audit, matching every other job.
  • No secrets are used, so the fork guard rule (head.repo.full_name == github.repository) correctly does not apply here. Top-level permissions: contents: read with the job narrowing to security-events: write + actions: read is least-privilege and consistent with the rest of the repo.

Correctness of the CodeQL config

  • build-mode: none is right for both javascript-typescript and actions; fail-fast: false means one language failing doesn't suppress the other's SARIF.
  • category: "/language:${{ matrix.language }}" keeps the two matrix legs from overwriting each other's results — easy to get wrong, correct here.
  • The concurrency expression does what the comment claims: PR runs group on pull_request.number and cancel; push/schedule on main group on refs/heads/main with cancel-in-progress: false, so the baseline always gets uploaded. Scheduled and push runs on main queue rather than cancel, which is the behaviour you want.
  • cron: '23 5 * * 3' is Wednesday 05:23 UTC, as described.
  • Both Analyze (javascript-typescript) and Analyze (actions) pass on this PR (52s / 1m4s), which also confirms the pinned SHA resolves, security-extended resolves for both languages, and that code scanning default setup isn't enabled on the repo (it would have rejected the advanced-config SARIF).

Scope and docs

  • The diff is exactly the two files the description claims; nothing touches src/, the catalog, the three-tool design, or the org-resolution rules.
  • The CLAUDE.md edit is accurate: four → five workflows, and the summary of what codeql.yaml does matches the file (including flagging it as advisory rather than a required check).
  • Commit message and PR title are Conventional Commits (ci:), and the commit body explains the v4.39.0-vs-v4.39.1 pin choice against the 7-day cooldown — that reasoning is worth having in the history.

Two small things, neither worth blocking on: pull_request here is filtered to branches: [main] while ci.yml uses a bare pull_request:, so a PR targeting any other branch gets CI but no CodeQL; and since this runs unguarded on fork PRs, it's worth confirming on the first external contribution that the SARIF upload doesn't trip over the read-only token — if it does, the fix is a skip condition on the upload, not a fork guard on the whole job.

Nicely done overall: the comments explain the non-obvious choices (why main runs aren't cancelled, why actions: read is there, why the actions language matters given the review workflow runs an LLM with a token in scope) instead of restating the YAML.
· branch ci/codeql

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@dangrondahl
dangrondahl enabled auto-merge (squash) October 23, 2026 10:30
@dangrondahl dangrondahl mentioned this pull request Oct 23, 2026
5 tasks
@dangrondahl
dangrondahl merged commit 844fc9e into main Oct 23, 2026
8 checks passed
@dangrondahl
dangrondahl deleted the ci/codeql branch October 23, 2026 11:15
dangrondahl added a commit that referenced this pull request Oct 23, 2026
Release prep for **0.6.0**. A draft for now: it gets rebased once #97
(CodeQL) merges, then marked ready.

`npm version minor --no-git-tag-version` moves `package.json`,
`package-lock.json` and the generated `src/version.ts` together.
`manifest.json` gets the version at pack time. Nothing else changes.

## What's in 0.6.0 (since 0.5.0)

### ⚠️ Changes that affect existing setups
- **No configured org (#65).** `KOSLI_ORG` and the Desktop extension's
*Organization* setting are removed. Every org-scoped call names its org
through the execute tools' `org` input, so no request lands in an org
the caller didn't name. An existing config that still sets `KOSLI_ORG`
starts fine and logs that the value is ignored, but calls that relied on
the default are now refused until an org is given.
- **Node ≥ 22 (#38).** It was ≥ 20.

### Fixes
- **Evidence downloads work again (#88, fixes #86).** Since 16 Oct,
every `get_attestation_evidence` call failed: our token was forwarded to
the pre-signed S3 URL. Text files come back as text, and binary files
return a clear error.
- **The `.mcpb` bundle starts on Node 22.0 – 22.6 (#87).** It didn't
before.
- **No known vulnerabilities in the bundled dependencies (#96).** `npm
audit --omit=dev` is clean.

### Features
- **`org` input on the execute tools (#65).**
- **`User-Agent` carries the version (#41):**
`kosli-mcp-server/<version>`.

### Dependencies
- **Runtime:** `@modelcontextprotocol/sdk` 1.29.0 → 1.32.1 (#29, #71,
#79).
- **Dev:** TypeScript 7 (#45), with emitted output byte-identical to
5.9. vitest 5 (#93).
- **Catalog:** regenerated from the OpenAPI spec (#50, #53, #60, #69,
#78).

### Release confidence (CI only)
Typecheck of tests and scripts, a stdio smoke test against `dist/` and
the unzipped bundle (including Node 22.0.0), `mcpb validate`, and
`release.yml` publishing only after every check (#87). There's also a
phased Claude review (#90), Dependabot grouping with a 7-day cooldown,
and CodeQL (#97).

## Checked locally on this branch

- Build, typecheck, 122 tests.
- The smoke test reports `server advertises version 0.6.0`, both from
`dist/` and from the unzipped bundle.
- `kosli-mcp-server-0.6.0.mcpb`: the manifest says 0.6.0 and `mcpb
validate` passes.

## Before tagging (after merge)
- [ ] Rebase onto `main` once #97 merges, then mark ready.
- [ ] Install the 0.6.0 `.mcpb` in Claude Desktop, including an upgrade
over 0.5.0 with an org configured.
- [ ] Run `KOSLI_API_TOKEN=… KOSLI_SMOKE_ORG=<org> npm run smoke` on
`main`.
- [ ] Download one piece of evidence via `get_attestation_evidence`.
- [ ] `git tag -a v0.6.0 -m "v0.6.0" <merge commit> && git push origin
v0.6.0`. `release.yml` does the rest.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: add CodeQL code scanning

3 participants