Skip to content

ci: integrate SafeDep PMG into GitHub Actions workflows - #35

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

ci: integrate SafeDep PMG into GitHub Actions workflows#35
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
Collaborator

What

Integrate SafeDep PMG (Package Manager Guard) into the repo's GitHub Actions so CI package installs are routed through PMG's persistent proxy, which blocks malicious packages before any code runs.

PMG step lifecycle added to each job (per the SafeDep doc)

  1. permissions: contents: read block
  2. uses: safedep/pmg@v1 with server-mode: true, placed after checkout, before install/build steps
  3. Existing steps run unchanged (installs intercepted automatically)
  4. Final pmg proxy stop --fail-on-violation with if: always() — fails the job on a block and flushes events

Delta from the doc: uses secrets PMG_PUBLIC_REPOS_TOKEN (api-key) and PMG_TENANT_ID (tenant-id) instead of SAFEDEP_API_KEY / SAFEDEP_TENANT_ID.

Jobs integrated (6)

Workflow Job Note
crud_app.yaml irc Docker build
ingressroute_configurator.yaml irc Docker build
secret_cloner.yaml secc Docker build
sqs_app.yaml irc Docker build
sqs_configurator.yaml sqsc Docker build
semgrep.yaml semgrep Uses razorpay/checkout-action; PMG placed right after it

Jobs skipped (1)

Workflow Job Reason
genesis.yml Analysis Calls a reusable workflow (uses: razorpay/genesis/.github/workflows/quality-checks.yml@master + secrets: inherit). Such a job cannot contain steps: or a job-level permissions block, so PMG can't be added without breaking it. Left untouched.

Scope guarantees

  • Purely additive: verified that with the PMG steps removed, all 6 files are identical to the originals — no existing step reordered, renamed, or modified; no on:/name/metadata changes.
  • No new files added. genesis.yml has zero diff.
  • All 7 workflow files parse as valid YAML; all integrated jobs pass structural checks (perms present, start-after-checkout, stop-last with if: always()).

Notes / recommendations

  • Secrets required before green runs: add repo/org secrets PMG_PUBLIC_REPOS_TOKEN and PMG_TENANT_ID. (PMG still blocks via community intelligence without them; the with: values just resolve empty and cloud sync won't occur until set.)
  • Effectiveness caveat: PMG is genuinely effective in semgrep.yaml (installs on the runner). In the 5 Docker-build jobs, installs happen inside docker build (Buildkit) and don't route through the runner proxy env, so PMG is present-but-nominal there. Making it effective for those would require installing PMG inside the Dockerfiles (system-install) — a separate, out-of-scope change. Added everywhere as requested; harmless where nominal.
  • Standalone pmg-test.yml: not added (recommended). Nothing installs packages on the runner in a way a test workflow would meaningfully exercise, so it would add no real value for this repo today. Worth revisiting if PMG is later added inside the Dockerfiles.

Discussion thread: Slack

Route CI package installs through SafeDep PMG's persistent proxy to block
malicious packages before they run.

Per job, following the SafeDep PMG GitHub Actions doc:
- add permissions: contents: read
- start PMG in server-mode after checkout (safedep/pmg@v1)
- enforce policy with 'pmg proxy stop --fail-on-violation' (if: always())

Uses secrets PMG_PUBLIC_REPOS_TOKEN (api-key) and PMG_TENANT_ID (tenant-id).

Applied to: crud_app, ingressroute_configurator, secret_cloner, sqs_app,
sqs_configurator, semgrep.
Skipped genesis.yml (Analysis job) - it calls a reusable workflow, which
cannot contain steps or a job-level permissions block.
@semgrep-code-razorpay

Copy link
Copy Markdown

Semgrep found 6 github-actions-mutable-action-tag findings:

  • .github/workflows/sqs_configurator.yaml
  • .github/workflows/sqs_app.yaml
  • .github/workflows/semgrep.yaml
  • .github/workflows/secret_cloner.yaml
  • .github/workflows/ingressroute_configurator.yaml
  • .github/workflows/crud_app.yaml

GitHub Actions step uses a mutable tag or branch reference. Tags and branch names can be silently repointed by the action owner, enabling supply-chain attacks — as seen in the trivy-action and kics-github-action compromises. Pin the reference to a full 40-character commit SHA instead, e.g. uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608.

⚪️ This finding does not block your pull request.
Ignore this finding from github-actions-mutable-action-tag

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: 75 lines added, none removed or modified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread .github/workflows/pmg-test.yml Outdated
runs-on: ubuntu-latest
steps:
- name: Setup PMG proxy
uses: safedep/pmg@v1

@semgrep-code-razorpay semgrep-code-razorpay Bot Aug 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub Actions step uses a mutable tag or branch reference. Tags and branch names can be silently repointed by the action owner, enabling supply-chain attacks — as seen in the trivy-action and kics-github-action compromises. Pin the reference to a full 40-character commit SHA instead, e.g. uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608.

🧼 Removed in commit fcbd981 🧼

Comment thread .github/workflows/pmg-test.yml Outdated
runs-on: ubuntu-latest
steps:
- name: Setup PMG proxy
uses: safedep/pmg@v1

@semgrep-code-razorpay semgrep-code-razorpay Bot Aug 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub Actions step uses a mutable tag or branch reference. Tags and branch names can be silently repointed by the action owner, enabling supply-chain attacks — as seen in the trivy-action and kics-github-action compromises. Pin the reference to a full 40-character commit SHA instead, e.g. uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608.

🧹 Removed in commit fcbd981 🧹

Comment thread .github/workflows/pmg-test.yml Outdated
Comment on lines +47 to +53
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

@semgrep-code-razorpay semgrep-code-razorpay Bot Aug 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A run: step pipes the output of curl or wget directly into a shell interpreter. This is the "curl | bash" install pattern — if the remote server is compromised or the URL is hijacked, an attacker can execute arbitrary code in your CI runner. Consider downloading the file first, verifying its checksum or signature, and then executing it.

🎉 Removed in commit fcbd981 🎉

Comment thread .github/workflows/pmg-test.yml Outdated
Comment on lines +21 to +27
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

@semgrep-code-razorpay semgrep-code-razorpay Bot Aug 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A run: step pipes the output of curl or wget directly into a shell interpreter. This is the "curl | bash" install pattern — if the remote server is compromised or the URL is hijacked, an attacker can execute arbitrary code in your CI runner. Consider downloading the file first, verifying its checksum or signature, and then executing it.

🧁 Removed in commit fcbd981 🧁

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