From 0d92cb46b040d07f4b304a1134c5de085f9ff65b Mon Sep 17 00:00:00 2001 From: Anders Myrmel Date: Wed, 5 Aug 2026 09:42:11 +0200 Subject: [PATCH] security: harden dependency installs --- .github/workflows/ci.yml | 17 ++++++++++-- .github/workflows/publish.yml | 51 ++++++++++++++++++++++++++++++----- .husky/pre-commit | 2 +- CHANGELOG.md | 16 +++++++++++ CONTRIBUTING.md | 7 ++--- package.json | 3 ++- pnpm-workspace.yaml | 9 +++++++ 7 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 pnpm-workspace.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e23909..7aa88c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [main] +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest @@ -21,13 +24,23 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 with: - version: 9 + version: 10.34.5 - name: Setup Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: "pnpm" + + - name: Get pnpm store directory + id: pnpm-store + shell: bash + run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" + + - name: Cache pnpm store + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-store.outputs.path }} + key: ${{ runner.os }}-node-${{ matrix.node-version }}-pnpm-10.34.5-${{ hashFiles('pnpm-lock.yaml') }} - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5565439..dbbcbb2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,12 +6,11 @@ on: types: [published] jobs: - publish: + build: runs-on: ubuntu-latest permissions: contents: read - id-token: write # Required for npm provenance steps: - name: Checkout code @@ -20,14 +19,23 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 with: - version: 9 + version: 10.34.5 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" - registry-url: "https://registry.npmjs.org" - cache: "pnpm" + + - name: Get pnpm store directory + id: pnpm-store + shell: bash + run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" + + - name: Cache pnpm store + uses: actions/cache@v4 + with: + path: ${{ steps.pnpm-store.outputs.path }} + key: ${{ runner.os }}-node-20-pnpm-10.34.5-${{ hashFiles('pnpm-lock.yaml') }} - name: Install dependencies run: pnpm install --frozen-lockfile @@ -38,7 +46,38 @@ jobs: - name: Build package run: pnpm run build + - name: Pack package + run: pnpm pack --pack-destination package-artifact + + - name: Upload package tarball + uses: actions/upload-artifact@v4 + with: + name: npm-package + path: package-artifact/*.tgz + if-no-files-found: error + + publish: + needs: build + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write # Required for npm provenance + + steps: + - name: Download package tarball + uses: actions/download-artifact@v4 + with: + name: npm-package + path: package-artifact + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + - name: Publish to npm - run: pnpm publish --access=public --provenance --no-git-checks + run: npm publish ./package-artifact/*.tgz --access=public --provenance --ignore-scripts env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.husky/pre-commit b/.husky/pre-commit index 2312dc5..5ee7abd 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1 @@ -npx lint-staged +pnpm exec lint-staged diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bff974..6ed5fd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to vard will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.1] - 2026-08-05 + +### Security + +- Pin pnpm 10.34.5 and enforce `strictDepBuilds` with an exact, reviewed `allowBuilds` policy. +- Deny the optional `fsevents@2.3.3` lifecycle build while allowing only the reviewed esbuild installers required by the toolchain. +- Isolate dependency installation from npm publication credentials and publish a prebuilt tarball with lifecycle scripts disabled. +- Harden CI dependency caching and frozen-lockfile installs around the exact pnpm and lockfile versions. +- Replace the pre-commit hook's `npx` invocation with the locally installed `lint-staged` binary. + +### Changed + +- Document the Corepack-based pnpm setup used by contributors. + +--- + ## [1.2.0] - 2025-11-12 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4fd8eb8..86814df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,11 +34,12 @@ Please be respectful and constructive in all interactions. We're here to build s ## Development Setup -Vard uses **pnpm** as its package manager. Make sure you have Node.js 18+ installed. +Vard uses **pnpm** as its package manager. For repository development, use Node.js 18.12 or newer. ```bash -# Install pnpm if you haven't already -npm install -g pnpm +# Enable Corepack; package.json selects pnpm 10.34.5 exactly +corepack enable +pnpm --version # Install dependencies pnpm install diff --git a/package.json b/package.json index 842f226..4d3874b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "@andersmyrmel/vard", - "version": "1.2.0", + "version": "1.2.1", + "packageManager": "pnpm@10.34.5", "description": "Lightweight prompt injection detection for LLM applications. Zod-inspired chainable API for prompt security.", "keywords": [ "prompt", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..323afde --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,9 @@ +minimumReleaseAge: 1440 +trustPolicy: no-downgrade +blockExoticSubdeps: true +strictDepBuilds: true + +allowBuilds: + esbuild@0.21.5: true + esbuild@0.25.10: true + fsevents@2.3.3: false