chore(repo): supply-chain and CI/CD hardening [PLT-103649]#688
Conversation
Dependency License Review
License distribution
Excluded packages
|
There was a problem hiding this comment.
Pull request overview
Enforces reproducible dependency installs for Apollo Vertex by freezing the lockfile during installs in both CI registry checks and Vercel deployments, reducing “works on my machine” drift and unexpected dependency resolutions.
Changes:
- Update Vercel install command to
pnpm install --frozen-lockfile. - Update the Apollo Vertex registry check workflow to install with
--frozen-lockfile.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| apps/apollo-vertex/vercel.json | Enforces frozen-lockfile installs during Vercel builds for deterministic deploys. |
| .github/workflows/apollo-vertex-registry-check.yml | Enforces frozen-lockfile installs in CI to fail fast on lockfile drift. |
c1521af to
95930c5
Compare
bryan-uipath
left a comment
There was a problem hiding this comment.
Thanks @CalinaCristian for the hardening here
875432f to
77abb7d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 36 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
.github/workflows/apollo-vertex-registry-check.yml:154
- This step runs
pnpm dlx tsx@4.20.6, buttsxis already pinned in root devDependencies. If possible, install deps in this job and usepnpm exec tsx ...so the executed binary is lockfile-controlled and covered by your audits; keepdlxonly if you intentionally want an ephemeral install here.
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_NPM_REGISTRY_TOKEN }}
COMPONENTS: ${{ matrix.components }}
BASE_APP_PATH: ${{ runner.temp }}/base-app
run: pnpm dlx tsx@4.20.6 ${{ github.workspace }}/.github/scripts/test-registry/test-registry.ts
77abb7d to
a2cb9c3
Compare
275a0f0 to
cf69579
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 36 changed files in this pull request and generated 10 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (7)
.github/workflows/pr-checks.yml:18
- This workflow sets non-empty top-level
permissions:(contents: read). The hardening guidance added in this PR requirespermissions: {}at workflow level and per-job minimal grants. Consider switching to deny-all at the workflow level and moving required permissions to each job.
This issue also appears on line 36 of the same file.
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
.github/workflows/pr-checks.yml:47
Install Node dependenciespassessecrets.GH_NPM_REGISTRY_TOKENon apull_requestworkflow without a fork guard. On fork PRs this secret will be unavailable and the job will likely fail during install. Addif: github.event.pull_request.head.repo.fork == falseto jobs that require this secret, or make the composite action gracefully handle fork PRs (e.g., optional token + skip GitHub Packages auth when empty).
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install Node dependencies
uses: ./.github/actions/install-node-deps
with:
registry-token: ${{ secrets.GH_NPM_REGISTRY_TOKEN }}
.github/workflows/commit-lint.yml:13
- This workflow lacks a workflow-level
permissions: {}deny-all block (it only sets job permissions). If the repo standard is deny-all at the workflow level, addpermissions: {}and keepcontents: readonly at the job level.
This issue also appears in the following locations of the same file:
- line 7
- line 25
name: Commit Lint
on:
pull_request:
types: [opened, edited, synchronize, reopened]
jobs:
commitlint:
name: Validate Commit Messages
runs-on: ubuntu-latest
permissions:
contents: read
steps:
.github/workflows/commit-lint.yml:24
- This job runs on
pull_requestbut installs dependencies usingsecrets.GH_NPM_REGISTRY_TOKENwithout a fork guard. Fork PRs won’t have this secret and the workflow will likely fail. Addif: github.event.pull_request.head.repo.fork == falseto the job or adjust install so it can run without secrets for forks.
jobs:
commitlint:
name: Validate Commit Messages
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install Node dependencies
uses: ./.github/actions/install-node-deps
with:
registry-token: ${{ secrets.GH_NPM_REGISTRY_TOKEN }}
.github/workflows/commit-lint.yml:30
commitlintis a repo devDependency, but this step runs it vianpx, which can introduce non-determinism and extra network behavior. Preferpnpm exec commitlint ...to ensure the pinned workspace version is used.
- name: Validate commit messages
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: npx commitlint --from "${BASE_SHA}" --to "${HEAD_SHA}" --verbose
.github/workflows/dev-cleanup.yml:23
- This workflow has no workflow-level
permissions: {}deny-all block. If deny-all is the repo standard, addpermissions: {}at the workflow level and keep the current job permissions as the minimal grants.
jobs:
cleanup:
name: Cleanup Dev Packages
runs-on: ubuntu-latest
# Skip fork PRs — cleanup uses publish-scoped tokens; fork PRs must not receive them.
if: github.event.pull_request.head.repo.fork == false
permissions:
contents: read
pull-requests: write
issues: write
.github/workflows/vercel-deploy.yml:139
- This job sets up pnpm and caches the pnpm store, but the workflow never runs
pnpm install(or any other command that would benefit from the store cache). Consider removing the pnpm setup/cache steps to reduce runtime, or add/justify the pnpm usage if it’s needed for the deploy flow.
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '22'
- name: Setup pnpm
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> "$GITHUB_OUTPUT"
- name: Setup pnpm cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
cf69579 to
9980bdc
Compare
9980bdc to
da0298e
Compare
da0298e to
076068b
Compare
076068b to
60a2424
Compare
60a2424 to
1532fff
Compare
What
pnpm install --frozen-lockfileenforced in all CI jobs and allvercel.jsoninstalls. Extracted into a reusableinstall-node-depscomposite action.minimumReleaseAge: 20160inpnpm-workspace.yaml. Temporary exemptions go inminimumReleaseAgeExcludewith a version annotation; a new weekly workflow (prune-release-age-exemptions) auto-PRs their removal once they age out.dependency-review-actionblocks high+ severity advisories on every PR.GH_NPM_REGISTRY_TOKEN/NPM_AUTH_TOKENmoved from workflow-levelenv:to step-level only.persist-credentials: falseon all checkouts that don't need to push.permissions: {}deny-all default added at workflow level across all workflows; each job grants only the minimum it needs..github/,pnpm-workspace.yaml,pnpm-lock.yaml,scripts/, andapps/apollo-vertex/(co-owned by both teams).pnpm.onlyBuiltDependenciesallowlist restricts lifecycle scripts toesbuild,@biomejs/biome, andsharp(optional native dep of Next.js for image optimisation).harden-github-actionClaude skill and.github/copilot-instructions.mdadded to keep these patterns consistent going forward.