In CI, PMG is non-interactive: flagged packages are always blocked, never prompted. For local development use the wrapped commands (
pmg npm install) covered in the PMG quickstart.Use the SafeDep PMG action
Run thesafedep/pmg action in server-mode, then add a final pmg proxy stop step to enforce the result.
Use
safedep/[email protected] or a later release tag. The v1 tag points at an older action without the enforce, enforce-* and expose-to-job-network inputs. GitHub warns about an unknown input and runs the job without it, so a job on v1 with enforce: true runs without kernel enforcement.pmg proxy stop --fail-on-violation step is what fails the job on a block and flushes the final events to the cloud. Without it the proxy keeps running and events still sync in the background, but the job won’t fail on a violation and the most recent events may be missed. The if: always() ensures it runs even when an earlier step fails.
PMG blocks malicious packages using SafeDep’s free community intelligence with or without credentials. Add the optional api-key and tenant-id to connect the run to SafeDep Cloud, so block events sync to Endpoint Hub before the runner is destroyed.
Example workflow
A full workflow that installs dependencies through PMG on every pull request:install-dependencies.yml
Enforce in the kernel
Proxy variables are a request that a process can ignore. A step that runsenv -i, uses sudo, or calls an HTTP client of its own bypasses the proxy. Add enforce: true to make the Linux kernel route every process on the runner through PMG. Add enforce-namespaces: redirect to route the containers that steps start, such as docker run and docker build.
sudo and uses the PMG_BIN and PMG_PROXY_STATE variables the action exports. Enforcement needs passwordless sudo on the runner. GitHub hosted Ubuntu runners have it.
The runner is not exempt. Its connections to GitHub go through the proxy, which passes them through with the real certificate. Set timeout-minutes on every enforced job. If the daemon stops serving but keeps running, the runner cannot report, and the job hangs until GitHub cancels it.
The enforce-ports, enforce-exempt-users, enforce-exempt-executables, enforce-skip-destinations, and enforce-namespaces inputs set the policy without a config file. Each list adds to the config’s list. See the action reference for the input table. A redirected container must trust the PMG CA through PMG_CA_BUNDLE. See Kernel Enforcement on Linux for the policy keys, container trust, and what enforcement does not cover.
Job containers and Docker actions
In a job with a job container (jobs.<job_id>.container), the action and the proxy run inside that container, and run: steps reach the proxy at 127.0.0.1. A Docker action or a docker:// step runs in a different container on the job network, where 127.0.0.1 is its own loopback, so its connection to the proxy fails. Set expose-to-job-network to bind the proxy to the job container’s address on the job network:
/github/home in the job container and in Docker actions, so the exported CA path is valid in both. The action fails when the job has no job container, and it warns when HOME, XDG_CONFIG_HOME, or PMG_CONFIG_DIR moves the CA outside /github/home.
Kernel enforcement does not apply inside a job container, because no daemon runs on the runner host. expose-to-job-network applies to server mode without enforce.
Use raw commands
To wire the proxy up directly without the action:Kernel Enforcement on Linux
Route every process and container on the runner through PMG.
PMG
How PMG blocks malicious packages at install time.
Malicious Package
How SafeDep detects malicious packages.

