Skip to content

Harden release workflows against cache poisoning#279

Merged
data-douser merged 11 commits into
mainfrom
dd/release-prep/actions
May 19, 2026
Merged

Harden release workflows against cache poisoning#279
data-douser merged 11 commits into
mainfrom
dd/release-prep/actions

Conversation

@data-douser
Copy link
Copy Markdown
Collaborator

This pull request introduces several improvements and security enhancements to our release workflows and the setup-codeql-environment GitHub Action. The main changes focus on stricter version validation, improved cache control to prevent cache-poisoning in release jobs, and updating the runner environment for consistency and future-proofing.

Outline of Changes

Key changes include:

Release workflow improvements:

  • Enforces strict version format validation (vMAJOR.MINOR.PATCH(-PRERELEASE)?) across all release workflows (release.yml, release-tag.yml, release-npm.yml, release-codeql.yml, release-vsix.yml), ensuring only valid version tags are processed. [1] [2] [3] [4] [5]
  • Sets cancel-in-progress: false for the main release workflow to prevent partial or inconsistent releases if a new workflow is triggered while another is running.
  • Switches all release jobs to run on ubuntu-24.04 for a consistent and up-to-date environment. [1] [2] [3] [4] [5] [6]

Caching and security enhancements:

  • Adds an enable-cache input to .github/actions/setup-codeql-environment/action.yml and disables all caching (including language runtimes and package managers) when running in release workflows, preventing potential cache-poisoning attacks. [1] [2] [3] [4] [5] [6] [7] [8]
  • Removes package manager cache usage in Node.js setup for release jobs. [1] [2] [3]

Other workflow improvements:

  • Improves shell quoting and safety in version parsing and publishing steps, and uses arrays for flags to avoid word-splitting issues.
  • Sets persist-credentials: false for actions/checkout in release workflows to reduce security risk. [1] [2] [3]

These changes increase the security, reliability, and maintainability of the release process.

Second hardening pass focused on release-generating workflows.

setup-codeql-environment:
- Add `enable-cache` input (default true)
- Gate gh-codeql, runtimes, and .NET package caches on it
- Gate `cache:` features on setup-node/python/java/go/ruby
- Split setup-node into with/without-cache variants

release.yml:
- cancel-in-progress: false (releases must not be cancelled
  mid-publish to avoid npm/GHCR/tag inconsistency)
- Validate version via env: var with strict regex
  ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.-]+)?$
- Pin runners to ubuntu-24.04

release-tag.yml, release-npm.yml, release-vsix.yml,
release-codeql.yml:
- Same strict regex + env: var version validation
- Pin runners to ubuntu-24.04
- Pass enable-cache: false to setup-codeql-environment
- Drop `cache: 'npm'` from inline setup-node steps
- persist-credentials: false on checkouts that do not push
  (release-tag keeps default; it pushes the tag)
- release-tag: drop unnecessary fetch-depth: 0
- release-codeql: fix unquoted ${PRERELEASE_FLAG} via bash array

Deferred to follow-up PRs:
- Move tidy/build/test out of contents:write tag job
- Add step-security/harden-runner with egress allowlist
@data-douser data-douser self-assigned this May 14, 2026
Copilot AI review requested due to automatic review settings May 14, 2026 23:34
@data-douser data-douser added the enhancement New feature or request label May 14, 2026
@data-douser data-douser requested a review from enyil as a code owner May 14, 2026 23:34
@data-douser data-douser added the dependencies Pull requests that update a dependency file label May 14, 2026
@data-douser data-douser requested a review from a team as a code owner May 14, 2026 23:34
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the repository’s release pipeline by tightening release version validation, reducing credential exposure during release checkouts, and disabling caches in release-generating paths to mitigate cache-poisoning risks. It also standardizes the release runner image to ubuntu-24.04 and improves shell safety in publishing steps.

Changes:

  • Enforce a strict release tag format (vMAJOR.MINOR.PATCH(-PRERELEASE)?) across release workflows and propagate validated outputs.
  • Add an enable-cache input to the setup-codeql-environment composite action and disable caches in release workflows.
  • Update release workflows to ubuntu-24.04, set cancel-in-progress: false on the main release workflow, and harden checkouts with persist-credentials: false where appropriate.
Show a summary per file
File Description
.github/workflows/release.yml Tightens version resolution/validation, adjusts concurrency cancellation behavior, and moves to ubuntu-24.04.
.github/workflows/release-tag.yml Enforces strict version validation and disables environment caches during tag creation.
.github/workflows/release-npm.yml Enforces strict version validation, hardens checkout credentials, removes npm caching, and moves to ubuntu-24.04.
.github/workflows/release-codeql.yml Enforces strict version validation, disables caches via the shared action, improves publish argument handling, and moves to ubuntu-24.04.
.github/workflows/release-vsix.yml Enforces strict version validation, hardens checkout credentials, removes npm caching, and moves to ubuntu-24.04.
.github/actions/setup-codeql-environment/action.yml Introduces enable-cache input and gates all restore/save cache steps (including package manager caches) behind it.

Copilot's findings

  • Files reviewed: 6/6 changed files
  • Comments generated: 5

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release-tag.yml Outdated
Comment thread .github/workflows/release-npm.yml
Comment thread .github/workflows/release-codeql.yml
Comment thread .github/workflows/release-vsix.yml
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new

Copilot AI review requested due to automatic review settings May 18, 2026 01:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 02:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread server/scripts/run-query-unit-tests.sh
Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 02:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Comment thread .github/workflows/release.yml
Uses "git check-ref-format" for defense-in-depth check of
input tags (values). Resolves review comments for PR #279.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 10/10 changed files
  • Comments generated: 3

Comment thread CHANGELOG.md Outdated
Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Comment thread .github/actions/setup-codeql-environment/action.yml Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 03:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 10/10 changed files
  • Comments generated: 1

Comment thread .github/workflows/release-tag.yml
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 03:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 10/10 changed files
  • Comments generated: 0 new

@data-douser data-douser deployed to release-tag May 18, 2026 17:24 — with GitHub Actions Active
@data-douser data-douser deployed to release-codeql May 18, 2026 17:31 — with GitHub Actions Active
@data-douser data-douser deployed to release-vsix May 18, 2026 17:31 — with GitHub Actions Active
@data-douser data-douser merged commit 3fe5254 into main May 19, 2026
36 of 37 checks passed
@data-douser data-douser deleted the dd/release-prep/actions branch May 19, 2026 15:27
data-douser added a commit that referenced this pull request May 19, 2026
Replace placeholder NNN PR references with the actual PR number, now
that the bundled-customizations entries sit in the [Unreleased] section
alongside the supply-chain hardening work from #279.
data-douser added a commit that referenced this pull request May 20, 2026
…y-developer, codeql-workshop-author) (#281)

* Initial plan

* feat(vscode): ship portable built-in custom agents with user-extensible packaging

- Add codeql-query-developer and codeql-workshop-author .agent.md files
- Add bundle-customizations.js script with overlay support
- Add AgentRegistrar class managing chat.agentFilesLocations registration
- Add bundle:customizations npm script; update vscode:prepublish and clean
- Add codeql-mcp.agents.enabled and additionalAgentDirs settings
- Add codeql-mcp.showAgentsStatus command
- Add contributes.chatAgents, chatPromptFiles, chatSkills static declarations
- Add Vitest unit tests for bundler and AgentRegistrar
- Add Mocha integration test suite for agents
- Add team-customizations example overlay
- Update README.md with Built-in Custom Agents section
- Update CHANGELOG.md [Unreleased] with new VS Code Extension features

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* Ignore generated customizations bundle outputs (agents/, prompts/, skills/, manifest)

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* Fix overlay manifest path for nested files; use project-local .tmp/ in tests

Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>

* Lint fixes for extensions/vscode/**/*.md

* Remove "model" from .github/agents/*.md

* fix(vscode): drop broken AgentRegistrar; contribute agents declaratively

Switch to `contributes.chatAgents` (declarative) only — the same channel
GitHub.copilot-chat resolves its own Plan/Ask/Explore agents through.

Changes:
- Remove `src/customizations/agent-registrar.ts` and its unit tests.
- Drop `codeql-mcp.agents.enabled` and `codeql-mcp.additionalAgentDirs`
  settings (unsupported; users set `chat.agentFilesLocations` to a
  workspace-relative path directly).
- Repurpose `codeql-mcp.showAgentsStatus` to report agents from
  `contributes.chatAgents` in the manifest.
- Add red→green integration tests: assert no absolute path leaks into
  `chat.agentFilesLocations`; assert `contributes.chatAgents` lists both
  bundled agents and that each referenced file exists on disk.
- Remove stale toggle/`additionalAgentDirs` integration tests.
- Update README + CHANGELOG to reflect declarative-only registration.
- Strip `model: Claude Opus 4.6 (copilot)` from the two `.github/prompts/`
  files that still set it (no static model in any agent or prompt).

Tests: 185/185 unit, 78/78 integration, lint clean.

* Fix extension agent packaging

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>

* chore: replace whitelist/blacklist terminology with allowlist/denylist

Across the VS Code extension bundler and the server-side CLI executor,
rename "whitelist" to "allowlist" (and follow the same convention for any
future "blacklist" → "denylist") in:

- Doc comments and header descriptions
- JSDoc and inline comments
- Identifiers:
  - bundle-customizations.js:
    promptWhitelist → promptAllowlist
    skillWhitelist  → skillAllowlist
- Error messages
- Test descriptions and comments

Files updated:
- extensions/vscode/customizations/bundle-customizations.config.js
- extensions/vscode/scripts/bundle-customizations.js
- extensions/vscode/test/customizations/bundle-customizations.test.ts
- server/src/lib/cli-executor.ts
- server/test/src/lib/cli-executor.test.ts

Out of scope (untouched):
- server/dist/*.js.map (generated; will pick up new strings on next build)
- server/ql/rust/**/*.testproj/**/rust/library/core/**.rs (vendored Rust
  stdlib test fixtures)
- .codeql/ql-mcp/query-logs/** (gitignored runtime logs)
- client/gh-ql-mcp-client (compiled binary)

Tests: 186/186 vscode unit, 78/78 server cli-executor unit, lint clean.
No behavior changes.

* docs(changelog): link bundled VS Code extension entries to PR #281

Replace placeholder NNN PR references with the actual PR number, now
that the bundled-customizations entries sit in the [Unreleased] section
alongside the supply-chain hardening work from #279.

* Address PR #281 review: doc accuracy + faster link-validity test

- README: tighten the 'Extending at Build Time' intro so the framing
  matches the limitation documented just below (manifest patch is
  required for net-new contributions; overlays only override or extend
  the already-contributed list).
- agents.integration.test.ts: rewrite the obsolete file header. It used
  to claim the tests verify chat.agentFilesLocations is 'updated
  correctly', but the suite now asserts the extension does NOT write
  the bundled-agents path there (VS Code rejects absolute paths).
- bundle-customizations.test.ts: the 'real source tree' link-validity
  test now copies only the allowlisted prompts and skill directories
  (read from the actual bundler config) instead of the entire
  server/src/prompts/ and .github/skills/ trees. Run time on this test
  drops from ~1.2s to ~0.7s and the I/O is bounded by the allowlist
  rather than by the size of the example workshop fixtures.

Tests: 186 unit (all pass); integration noWorkspace 83/83 exit 0.

* Address PR #281 review #4322045254

- extension.ts: extract `readBundledAgentsStatus(context)` helper that
  reads the manifest from `context.extensionUri.fsPath` directly,
  removing the previous `context.extension.id` dependency.
  `showAgentsStatus` now calls the helper, and the same helper is
  exposed on `ExtensionApi.getBundledAgentsStatus()` for test
  introspection.
- agents.integration.test.ts (TDD): new test asserts the extension API
  exposes `getBundledAgentsStatus()` and that it returns both bundled
  agent paths (`ql-mcp-ext-query-developer.agent.md`,
  `ql-mcp-ext-workshop-author.agent.md`) plus a `bundledDir` resolved
  via `extensionUri`. Red against the previous code, green after the
  helper extraction.
- CHANGELOG.md: reorder `[Unreleased]` sections to match the repo's
  changelog guidance (`Highlights` -> `Added` -> `Changed` -> `Fixed`
  -> `Security` -> `Dependencies`). The new `Added > VS Code Extension`
  bullets now sit immediately after `Highlights`.

Tests: 186 unit (vitest); integration noWorkspace 84, singleFolder 86,
multiRoot 89; all exit 0.

* feat(vscode): drop bundled prompts; expand MCP-prompt references in agents

Workflow prompts now ship exclusively via the `ql-mcp` MCP server's
`prompts/list` and surface as slash commands in Copilot Chat. The four
bundled `ql-mcp-ext-*` `.prompt.md` files duplicated content the server
already exposes under canonical IDs (`/ql_tdd_basic`, etc.), creating
two slash commands for the same workflow. Bundled agents and skills are
unchanged in form; only their prose changes to reference a richer
palette of MCP slash IDs.

Changes:
- bundle-customizations.config.js: `prompts` allowlist is now empty.
  Header doc explains why and notes the array is kept for future
  reversibility.
- bundle-customizations.js: prompts copy loop is preserved but gated
  on a non-empty allowlist; the `prompts/` target dir is only created
  when at least one prompt would be copied.
- package.json: drop `contributes.chatPromptFiles` entirely.
- customizations/agents/ql-mcp-ext-query-developer.agent.md: split the
  old 'Bundled Skills and Prompts' section into 'Bundled Skills' (2
  bullets) and 'MCP Prompts' (7 bullets) referencing canonical slash
  IDs. Adds `/ql_lsp_iterative_development`, `/explain_codeql_query`,
  `/document_codeql_query`, `/data_extension_development` to the
  workflow palette.
- customizations/agents/ql-mcp-ext-workshop-author.agent.md: same
  split. The MCP Prompts list now has 5 bullets, adding
  `/explain_codeql_query` and `/document_codeql_query`.
- README.md 'Built-in Custom Agents': describes agents + skills only;
  a single sentence points users at the MCP-served slash commands.
- CHANGELOG.md [Unreleased]: rename the 'Bundled prompts and skills'
  bullet to 'Bundled skills'; add a 'Changed > VS Code Extension'
  bullet that explains the prompts-via-MCP migration.

TDD (new integration tests in agents.integration.test.ts):
- 'package.json does NOT contribute chatPromptFiles' — asserts
  `contributes.chatPromptFiles` is absent or empty.
- 'Bundled prompts/ directory is not produced by the bundler' —
  asserts `<extensionPath>/prompts/` does not exist.
- 'Every MCP prompt slash ID referenced by shipped agents maps to a
  real MCP prompt' — scans each agent's body for `/<id>` tokens,
  asserts each is in the 15-ID set registered by
  server/src/prompts/workflow-prompts.ts, and asserts each agent
  references at least one.

All three failed against the previous tip and pass now.

Also: bundled-markdown-links.integration.test.ts splits its
'required' vs 'optional' bundled-dir lists so the absence of the
`prompts/` dir no longer trips the vacuous-pass guard.

Tests: 186 unit (vitest); integration noWorkspace 87, singleFolder 89,
multiRoot 92; all exit 0.

* Address PR #281 review #4323697978

- src/extension.ts: extend `ExtensionApi` to include `environmentBuilder`
  and `serverManager`. The activate() return value was always shaped
  this way (the bridge/workspace integration tests rely on these
  hooks), but the type only listed `mcpProvider` and
  `getBundledAgentsStatus`, which is an excess-property violation
  under TS strict checks. Document both as part of the public
  contract.
- test/suite/extension.integration.test.ts: new TDD assertion that the
  runtime `ExtensionApi` exposes `mcpProvider`,
  `environmentBuilder`, `serverManager`, and a callable
  `getBundledAgentsStatus`. Guards against any future drift between
  the declared interface and the returned shape.
- README.md "Adding Your Own Agents at Runtime": clarify exactly which
  path forms `chat.agentFilesLocations` accepts (workspace-relative
  and home-relative `~/foo` form) and which it rejects (absolute,
  drive-letter, backslash separators, glob characters). Resolves the
  reviewer's complaint that `~/.copilot/agents` was listed as a
  workspace-relative example.
- CHANGELOG.md `[Unreleased]` Highlights: condense the second
  supply-chain hardening bullet to a brief lead-in that points at the
  Security section, eliminating the duplicate prose previously
  flagged by repo changelog rules (no entry repeated across multiple
  sections).

Tests: 186 unit (vitest); integration noWorkspace 88, singleFolder 90,
multiRoot 93; all exit 0.

The three remaining unresolved reviewer comments
(`extension.ts:85`, `cli-executor.ts:35`, `.github/agents/...:4`) all
concern the PR description text on GitHub claiming a narrower scope
than the actual diff. The code is consistent; the PR description
should be updated via the GitHub UI.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>

* Remove unused `basename` import from VS Code customization bundler script (#282)

---------

Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
Co-authored-by: Nathan Randall <data-douser@github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants