Skip to content

ci: integrate SafeDep PMG malicious-package protection - #484

Open
vanshika-verma-rzp wants to merge 3 commits into
masterfrom
integrate-safedep-pmg
Open

vanshika-verma-rzp wants to merge 3 commits into
masterfrom
integrate-safedep-pmg

Conversation

@vanshika-verma-rzp

@vanshika-verma-rzp vanshika-verma-rzp commented Aug 25, 2026

Copy link
Copy Markdown

Summary

Integrates SafeDep PMG (safedep/pmg@v1) into every job across all GitHub Actions workflows to block malicious npm/composer/bundler/pip packages before they install on CI runners.

Follows SafeDep's GitHub Action doc step lifecycle, with two intentional deltas:

  • api-key: ${{ secrets.PMG_PUBLIC_REPOS_TOKEN }} (instead of the doc's SAFEDEP_API_KEY)
  • tenant-id: ${{ secrets.PMG_TENANT_ID }} (instead of SAFEDEP_TENANT_ID)

PMG step lifecycle applied per job

  1. uses: safedep/pmg@v1 placed after the setup-* toolchain step, before install/run steps (per doc: shims must land in front of the real toolchains).
  2. Existing install steps left untouched (intercepted via HTTP_PROXY automatically).
  3. Trailing pmg cloud sync --timeout 60s with if: always() to flush audit events.
  4. Minimal permissions: contents: read block per job.

Coverage — 9/9 jobs, 0 skipped

Workflow Job(s) Placed after
NPM_Publish.yml release setup-node
Ruby_Gem_Publish.yml release setup-ruby
scraper.yml scraper, php, release-notes setup-ruby / setup-php
tests.yml node, php, ruby, go setup-node / setup-php / setup-ruby / setup-go

No reusable-workflow (job-level uses:) jobs exist, and every runner is ubuntu-latest — PMG's only supported platform.

New: verification workflow

.github/workflows/pmg-test.yml — a standalone smoke test that asserts PMG blocks the safedep-test-pkg@0.1.3 package (a benign package flagged as malicious in SafeDep's DB for testing). Job fails if the malicious install is not blocked.

Notes / caveats

  • Ruby_Gem_Publish.yml: already had permissions: write-all, left untouched (it satisfies PMG's contents: read need); this is the one job without a new permissions block, intentionally.
  • Ruby jobs with bundler-cache: true: setup-ruby runs its cached bundle install before PMG loads (inherent to the doc's placement rule). PMG still covers the explicit bundle install / gem build / gem push steps that follow.
  • go and release-notes jobs don't install packages on the runner, so PMG is effectively a no-op there — added anyway for uniform coverage. Harmless.

Action required before merge

Add repo secrets under Settings → Secrets → Actions:

  • PMG_PUBLIC_REPOS_TOKEN
  • PMG_TENANT_ID

(Without them PMG still blocks malware + applies cooldown; only cloud audit sync becomes a no-op.)

Verification

  • YAML parse: all 5 workflows OK
  • actionlint: no warnings on any PMG line (pre-existing warnings on old action pins are untouched)
  • Diff: 127 insertions, 0 deletions — no existing step reordered/renamed/modified; exactly one new file added.

Discussion thread: Slack

vanshika-verma-rzp and others added 3 commits August 25, 2026 12:34
Add SafeDep PMG (safedep/pmg@v1) to every job across all GitHub Actions
workflows to block malicious npm/composer/bundler/pip packages before they
install on CI runners.

Per SafeDep's GitHub Action doc, PMG is placed after each setup-* toolchain
step and before install/run steps, with a trailing 'pmg cloud sync' step
(if: always()) to flush audit events, and a minimal 'contents: read'
permissions block per job.

Secrets used: PMG_PUBLIC_REPOS_TOKEN (api-key), PMG_TENANT_ID (tenant-id).

Workflows updated (9 jobs, 0 skipped):
- NPM_Publish.yml (release)
- Ruby_Gem_Publish.yml (release; existing write-all perms left untouched)
- scraper.yml (scraper, php, release-notes)
- tests.yml (node, php, ruby, go)

New:
- pmg-test.yml: smoke test asserting PMG blocks the safedep-test-pkg
  malicious test package on the runner.
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: 135 lines added, none removed or modified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant