From 589216c89ec701a2fe9b91caf16d15448ea7bca8 Mon Sep 17 00:00:00 2001 From: Vanshika Verma Date: Mon, 24 Aug 2026 11:49:25 +0530 Subject: [PATCH 1/4] ci: integrate SafeDep PMG package guard into all workflow jobs Route package installs through PMG's persistent proxy to auto-block malicious packages at install time across every CI job. - node.js.yml: build job - ci.yml: test job - ci.yml: publish-npm job Each job starts safedep/pmg@v1 in server-mode after checkout and ends with 'pmg proxy stop --fail-on-violation' (if: always()) to enforce the policy and flush events. --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ .github/workflows/node.js.yml | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bef8e60..cd9c0086 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,12 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v4 + # Start PMG in server mode to block malicious packages at install time + - uses: safedep/pmg@v1 + with: + server-mode: true + api-key: ${{ secrets.SAFEDEP_API_KEY }} + tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: @@ -34,6 +40,10 @@ jobs: uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} + # Enforce PMG policy and flush events + - name: Stop proxy + if: always() + run: pmg proxy stop --fail-on-violation publish-npm: if: startsWith(github.ref, 'refs/tags/v') @@ -41,6 +51,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + # Start PMG in server mode to block malicious packages at install time + - uses: safedep/pmg@v1 + with: + server-mode: true + api-key: ${{ secrets.SAFEDEP_API_KEY }} + tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} - run: sudo apt-get install -y oathtool - uses: actions/setup-node@v4 with: @@ -49,3 +65,7 @@ jobs: - run: npm ci - run: npm config set //registry.npmjs.org/:_authToken ${{secrets.NPM_TOKEN}} - run: npm publish --otp="$(oathtool -b --totp ${{secrets.NPM_SECRET_KEY}})" + # Enforce PMG policy and flush events + - name: Stop proxy + if: always() + run: pmg proxy stop --fail-on-violation diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index a653bd10..d1ebb4c7 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -21,6 +21,12 @@ jobs: steps: - uses: actions/checkout@v4 + # Start PMG in server mode to block malicious packages at install time + - uses: safedep/pmg@v1 + with: + server-mode: true + api-key: ${{ secrets.SAFEDEP_API_KEY }} + tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: @@ -29,3 +35,7 @@ jobs: - run: npm install - run: npm run build --if-present - run: npm test + # Enforce PMG policy and flush events + - name: Stop proxy + if: always() + run: pmg proxy stop --fail-on-violation From 58a141d168eff7ca229c0adf4e80da172952329f Mon Sep 17 00:00:00 2001 From: vanshika-verma-rzp Date: Mon, 24 Aug 2026 14:43:14 +0530 Subject: [PATCH 2/4] Align PMG integration: use PMG_PUBLIC_REPOS_TOKEN/PMG_TENANT_ID + add pmg-test.yml --- .github/workflows/ci.yml | 8 +++--- .github/workflows/node.js.yml | 4 +-- .github/workflows/pmg-test.yml | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/pmg-test.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd9c0086..344a7a06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: - uses: safedep/pmg@v1 with: server-mode: true - api-key: ${{ secrets.SAFEDEP_API_KEY }} - tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} + api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} + tenant-id: ${{ secrets.PMG_TENANT_ID }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: @@ -55,8 +55,8 @@ jobs: - uses: safedep/pmg@v1 with: server-mode: true - api-key: ${{ secrets.SAFEDEP_API_KEY }} - tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} + api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} + tenant-id: ${{ secrets.PMG_TENANT_ID }} - run: sudo apt-get install -y oathtool - uses: actions/setup-node@v4 with: diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index d1ebb4c7..ec90f21f 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -25,8 +25,8 @@ jobs: - uses: safedep/pmg@v1 with: server-mode: true - api-key: ${{ secrets.SAFEDEP_API_KEY }} - tenant-id: ${{ secrets.SAFEDEP_TENANT_ID }} + api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} + tenant-id: ${{ secrets.PMG_TENANT_ID }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: diff --git a/.github/workflows/pmg-test.yml b/.github/workflows/pmg-test.yml new file mode 100644 index 00000000..0f384ded --- /dev/null +++ b/.github/workflows/pmg-test.yml @@ -0,0 +1,52 @@ +name: PMG Proxy Test + +on: + workflow_dispatch: + pull_request: + push: + +jobs: + test-pmg-allows-clean-install: + name: PMG - Clean package should not be blocked + runs-on: ubuntu-latest + steps: + - name: Setup PMG proxy + uses: safedep/pmg@v1 + with: + server-mode: true + api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} + tenant-id: ${{ secrets.PMG_TENANT_ID }} + + - uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install clean package (should succeed) + run: npm install lodash + + - name: Enforce PMG policy + if: always() + run: pmg proxy stop --fail-on-violation + + test-pmg-blocks-malicious-package: + name: PMG - Malicious package should be blocked + runs-on: ubuntu-latest + steps: + - name: Setup PMG proxy + uses: safedep/pmg@v1 + with: + server-mode: true + api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} + tenant-id: ${{ secrets.PMG_TENANT_ID }} + + - uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install flagged test package (PMG should block this) + continue-on-error: true + run: npm install --no-cache --prefer-online safedep-test-pkg@0.1.3 + + - name: Enforce PMG policy (expect failure — violation recorded) + if: always() + run: pmg proxy stop --fail-on-violation From 9427ddfa9cdba8f24d956d8be7f62c498d94a6fa Mon Sep 17 00:00:00 2001 From: Vanshika Verma Date: Wed, 26 Aug 2026 01:49:37 +0530 Subject: [PATCH 3/4] Align PMG integration with the agreed standard Brings this repo onto the same integration used in ai-playbook and i18nify, with the enforcement fix from blade. - Setup step renamed to "Setup PMG proxy" and given `id: pmg-setup`, so the enforce step can tell whether setup actually ran. - Enforce step runs `--fail-on-violation` only when setup succeeded. With a bare `if: always()`, any failure before the PMG step makes GitHub skip setup while still running enforce, which then dies with `pmg: command not found` (exit 127) and buries the real error. - Removed additions that are not part of the reference integration: `permissions:` blocks, workflow comments, pinned action SHAs and non-standard step names. - Added pmg-test.yml, byte-identical to the copy in ai-playbook and i18nify, which demonstrates the proxy blocking a known-malicious package and syncing the event to SafeDep Cloud. The workflow files are now the master versions plus the two PMG steps and nothing else: 45 lines added, none removed or modified. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 30 ++++++++++++++++++++---------- .github/workflows/node.js.yml | 15 ++++++++++----- .github/workflows/pmg-test.yml | 20 ++++++++++++++------ 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 344a7a06..90a30814 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,9 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v4 - # Start PMG in server mode to block malicious packages at install time - - uses: safedep/pmg@v1 + - name: Setup PMG proxy + id: pmg-setup + uses: safedep/pmg@v1 with: server-mode: true api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} @@ -40,10 +41,14 @@ jobs: uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - # Enforce PMG policy and flush events - - name: Stop proxy + - name: Enforce PMG policy if: always() - run: pmg proxy stop --fail-on-violation + run: | + if [ "${{ steps.pmg-setup.outcome }}" = "success" ]; then + pmg proxy stop --fail-on-violation + else + pmg proxy stop || true + fi publish-npm: if: startsWith(github.ref, 'refs/tags/v') @@ -51,8 +56,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - # Start PMG in server mode to block malicious packages at install time - - uses: safedep/pmg@v1 + - name: Setup PMG proxy + id: pmg-setup + uses: safedep/pmg@v1 with: server-mode: true api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} @@ -65,7 +71,11 @@ jobs: - run: npm ci - run: npm config set //registry.npmjs.org/:_authToken ${{secrets.NPM_TOKEN}} - run: npm publish --otp="$(oathtool -b --totp ${{secrets.NPM_SECRET_KEY}})" - # Enforce PMG policy and flush events - - name: Stop proxy + - name: Enforce PMG policy if: always() - run: pmg proxy stop --fail-on-violation + run: | + if [ "${{ steps.pmg-setup.outcome }}" = "success" ]; then + pmg proxy stop --fail-on-violation + else + pmg proxy stop || true + fi diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index ec90f21f..c1c47693 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -21,8 +21,9 @@ jobs: steps: - uses: actions/checkout@v4 - # Start PMG in server mode to block malicious packages at install time - - uses: safedep/pmg@v1 + - name: Setup PMG proxy + id: pmg-setup + uses: safedep/pmg@v1 with: server-mode: true api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} @@ -35,7 +36,11 @@ jobs: - run: npm install - run: npm run build --if-present - run: npm test - # Enforce PMG policy and flush events - - name: Stop proxy + - name: Enforce PMG policy if: always() - run: pmg proxy stop --fail-on-violation + run: | + if [ "${{ steps.pmg-setup.outcome }}" = "success" ]; then + pmg proxy stop --fail-on-violation + else + pmg proxy stop || true + fi diff --git a/.github/workflows/pmg-test.yml b/.github/workflows/pmg-test.yml index 0f384ded..664eebfe 100644 --- a/.github/workflows/pmg-test.yml +++ b/.github/workflows/pmg-test.yml @@ -17,9 +17,13 @@ jobs: api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} tenant-id: ${{ secrets.PMG_TENANT_ID }} - - uses: actions/setup-node@v4 - with: - node-version: "20" + - name: Install npm via nvm + run: | + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + nvm install 20 + echo "$NVM_DIR/versions/node/$(nvm version 20)/bin" >> $GITHUB_PATH - name: Install clean package (should succeed) run: npm install lodash @@ -39,9 +43,13 @@ jobs: api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} tenant-id: ${{ secrets.PMG_TENANT_ID }} - - uses: actions/setup-node@v4 - with: - node-version: "20" + - name: Install npm via nvm + run: | + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + nvm install 20 + echo "$NVM_DIR/versions/node/$(nvm version 20)/bin" >> $GITHUB_PATH - name: Install flagged test package (PMG should block this) continue-on-error: true From d54d503dbb2dfa920e035da86b99d66fc841f86d Mon Sep 17 00:00:00 2001 From: Vanshika Verma Date: Fri, 28 Aug 2026 14:53:03 +0530 Subject: [PATCH 4/4] Remove pmg-test.yml PMG validation workflow pmg-test.yml was added alongside the PMG integration purely to prove the proxy behaves correctly inside this repository's own CI environment. It ran two jobs: one installing a known-clean package to confirm PMG does not block legitimate traffic, and one installing the deliberately-flagged safedep-test-pkg@0.1.3 to confirm the block is caught and `pmg proxy stop --fail-on-violation` fails the job as intended. That validation is now complete across every repository in this rollout, so the workflow has served its purpose. Leaving it in place would mean a permanent CI job that installs a deliberately-flagged package on every push and pull request - burning runner time and producing a red check that is expected-to-fail, which is exactly the kind of noise that trains people to ignore CI signal. The PMG integration itself is untouched. The safedep/pmg setup steps and the `pmg proxy stop --fail-on-violation` enforcement steps in this repository's real build and test workflows remain exactly as they were. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/pmg-test.yml | 60 ---------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 .github/workflows/pmg-test.yml diff --git a/.github/workflows/pmg-test.yml b/.github/workflows/pmg-test.yml deleted file mode 100644 index 664eebfe..00000000 --- a/.github/workflows/pmg-test.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: PMG Proxy Test - -on: - workflow_dispatch: - pull_request: - push: - -jobs: - test-pmg-allows-clean-install: - name: PMG - Clean package should not be blocked - runs-on: ubuntu-latest - steps: - - name: Setup PMG proxy - uses: safedep/pmg@v1 - with: - server-mode: true - api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} - tenant-id: ${{ secrets.PMG_TENANT_ID }} - - - name: Install npm via nvm - run: | - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - nvm install 20 - echo "$NVM_DIR/versions/node/$(nvm version 20)/bin" >> $GITHUB_PATH - - - name: Install clean package (should succeed) - run: npm install lodash - - - name: Enforce PMG policy - if: always() - run: pmg proxy stop --fail-on-violation - - test-pmg-blocks-malicious-package: - name: PMG - Malicious package should be blocked - runs-on: ubuntu-latest - steps: - - name: Setup PMG proxy - uses: safedep/pmg@v1 - with: - server-mode: true - api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} - tenant-id: ${{ secrets.PMG_TENANT_ID }} - - - name: Install npm via nvm - run: | - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - nvm install 20 - echo "$NVM_DIR/versions/node/$(nvm version 20)/bin" >> $GITHUB_PATH - - - name: Install flagged test package (PMG should block this) - continue-on-error: true - run: npm install --no-cache --prefer-online safedep-test-pkg@0.1.3 - - - name: Enforce PMG policy (expect failure — violation recorded) - if: always() - run: pmg proxy stop --fail-on-violation