Repository navigation
Conversation
Move all jobs to the Namespace profiles namespace-profile-sentry-javascript-small, namespace-profile-sentry-javascript and namespace-profile-sentry-javascript-large, by the CPU and memory that each job needs. The build.yml jobs use the cache tag sentry-javascript, so all three profiles share one cache volume. Keep node_modules, the pnpm store, the Playwright browsers and their apt packages on Namespace cache volumes instead of the GitHub cache. Every job runs pnpm install, which is a no-op when the volume matches pnpm-lock.yaml, so the dependency cache key is no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| 'aws-serverless') || github.event_name != 'pull_request' | ||
| timeout-minutes: 10 | ||
| runs-on: ubuntu-24.04 | ||
| runs-on: namespace-profile-sentry-javascript;overrides.cache-tag=sentry-javascript |
There was a problem hiding this comment.
Shared Namespace cache-tag lets PR jobs poison node_modules used by trusted builds
PR jobs and trusted develop/release jobs all mount the same Namespace cache volume via cache-tag=sentry-javascript, so a pull_request run can leave tampered node_modules that later trusted jobs reuse when pnpm install --frozen-lockfile is a no-op—compromising CI builds and release artifacts. Partition the cache by trust boundary (e.g. only develop/release write, or per-branch tags) rather than sharing one volume across all branches.
Evidence
- Hunk jobs set
runs-on: ...;overrides.cache-tag=sentry-javascript(e.g.job_build_layerat line 190, bundles/lint/tests/artifacts similarly), andbuild.ymlis triggered bypull_requestas well as push/release. - Those jobs call
./.github/actions/restore-cache→install-dependencies, which mounts workspacenode_moduleswithnamespacelabs/nscloud-cache-actionand runspnpm install --frozen-lockfile. install-dependenciesdocuments that the volume can hold another branch'snode_modulesand that install is a no-op when it matchespnpm-lock.yaml, so post-install tampering is not refreshed away.- The PR description states all
build.ymljobs share one volume for all branches with last-write-wins, including the release-onlyjob_artifactspath that restores the same cache before packaging.
Also found at 7 additional locations
.github/workflows/build.yml:829-829.github/actions/restore-cache/action.yml:12-13.github/workflows/build.yml:67-67.github/workflows/build.yml:688-771.github/actions/install-dependencies/action.yml:21-30.github/workflows/build.yml:552-592.github/actions/install-playwright/action.yml:29-35
Identified by Warden · security-review · BT2-V9Y
| uses: namespacelabs/nscloud-cache-action@v1.7.0 | ||
| with: | ||
| path: ${{ env.CACHED_DEPENDENCY_PATHS }} | ||
| key: ${{ steps.compute_lockfile_hash.outputs.hash }} | ||
| cache: pnpm | ||
| path: ${{ steps.paths.outputs.paths }} |
There was a problem hiding this comment.
Mutable Namespace cache action can run with a repository write token
The dependency-install action invokes namespacelabs/nscloud-cache-action by mutable tag in workflows whose job token has contents: write; a retagged action could use that token to modify repository contents. Pin the action to a full commit SHA.
Evidence
.github/actions/install-dependencies/action.ymlinvokesnamespacelabs/nscloud-cache-action@v1.7.0, a tag rather than an immutable commit SHA.dependabot-auto-triage.ymlandbump-size-limits.ymlcall this local action in jobs withcontents: writepermissions.- Actions can access the job's
GITHUB_TOKENthrough thegithub.tokencontext; compromised code at the mutable tag could use the write-scoped token to modify repository contents.
Also found at 3 additional locations
.github/actions/install-playwright/action.yml:30-30.github/actions/restore-cache/action.yml:13-13.github/workflows/build.yml:1206-1209
Identified by Warden · security-review · GYN-7M5
|
bugbot run |
This moves all GitHub Actions jobs to Namespace runners. It keeps node_modules, the pnpm store and the Playwright browsers on Namespace cache volumes instead of the GitHub cache, so every job runs
pnpm install --frozen-lockfileand there is no dependency cache key anymore.Runner decisions
Jobs use 3 profiles, sized from the CPU and memory peaks in
nsc instance report:-small(2 vCPU, 4 GB) for bots and checks, the default (4 vCPU, 8 GB) for E2E and light jobs,-large(8 vCPU, 16 GB) for build, lint and tests. One profile for all jobs is simpler, but slower or more expensive.Cache decisions
All
build.ymljobs share one cache volume throughcache-tag=sentry-javascript, for all branches (last write wins). Alternative: let onlydevelopwrite to it ("Protect caches from updates").