Skip to main content
Use a system-wide install when one machine or image should protect every user account: shared VMs, CI runners, and golden Docker images. On Linux and Windows, it installs PATH shims for all users and an authoritative managed config, so any user’s npm install or pip install is checked before it runs.
For a single developer machine, use the per-user setup in the Quickstart. For a macOS, Linux, or Windows fleet, deploy through your MDM. For a Kubernetes workload, use the Kubernetes guide. Per-user and system-wide installs can coexist.

Requirements

  • Linux or Windows. Run as root on Linux, or as an administrator on Windows. Windows requires Windows 10 or 11. The release is x86-64, with ARM64 using emulation.
  • PMG in a system path. On Linux, use a root-owned path such as /usr/local/bin, executable by all users. On Windows, the binary must be %ProgramFiles%\safedep\pmg\pmg.exe. A user-local binary is rejected.

What gets created

System install uses PATH shims only. It does not create the ~/.pmg.rc alias layer that per-user setup installs on macOS and Linux.

Windows machines

  1. Download and extract pmg_Windows_x86_64.zip from a v0.29.0 or later release. Earlier versions do not support Windows system install.
  2. Open PowerShell as administrator in the extracted directory, then install:
  3. Open a new terminal as your normal user and verify:
npm should resolve under %ProgramFiles%\safedep\pmg\bin, and PMG must block the test package. System install puts shims ahead of machine-wide Node.js installations. A per-user install cannot do that. System install sets the required ownership and permissions. Run it before editing the managed config as administrator. See the system-install reference for permission requirements and troubleshooting. For fleets, the Windows MDM scripts perform these steps and deploy your config. For shell and interception limits, see Windows coverage.

Docker images

PMG must be installed inside the image: PMG on the Docker host cannot see installs that run during docker build. The easiest path is to copy the PMG binary from the published PMG container image into your application image. Compared to a Linux VM, a Dockerfile needs two adjustments:
  1. No sudo. RUN steps execute as root. If your base image switches to a non-root USER, add USER root before the install step and switch back after.
  2. Set PATH with ENV. RUN steps do not source /etc/profile.d, so add the shim directory to PATH explicitly.
Every RUN npm install or RUN pip install after the ENV PATH line now goes through PMG, and the running container inherits the protection, for any USER. Derived images inherit it too.
If your build environment cannot pull from GHCR, install PMG with curl -fsSL https://raw.githubusercontent.com/safedep/pmg/main/install.sh | sh before running pmg setup install --system.
If a later stage sets ENV PATH again, keep /usr/local/lib/pmg/bin ahead of the real npm/pip directories. Dropping it, or ordering it behind the toolchain, turns interception off without any error.

Linux VMs

  1. Place PMG in a system path. Not installed yet? The install script places it in /usr/local/bin, prompting for sudo for the copy:
    Already installed in a user location? Copy it over:
    PMG rejects a binary in a user location (~/.local/bin, ~/go/bin), since any single user could modify it. The install script also picks ~/.local/bin when that is on your PATH. If it did, use the copy command above.
  2. Install system-wide:
  3. Activate the PATH. The install writes /etc/profile.d/pmg.sh, which prepends the shim directory for login shells. New login sessions pick it up. For an already-open shell:
On a multi-user host where you do not trust every member of the directory’s group, tighten the install directory: sudo chmod g-w /usr/local/bin. Debian and Ubuntu ship it group-writable for the staff group (empty by default).

Verify

On Linux, run in a VM shell or inside a container (docker run --rm -it <image> sh):
Then prove the protection end to end with a known test package. PMG must block it:

Configuration

The system config file is authoritative for every user. PMG ignores a per-user config.yml while the managed config is active: /etc/safedep/pmg/config.yml on Linux or %PROGRAMDATA%\safedep\pmg\config.yml on Windows. pmg config set and pmg config edit are disabled under a system config. Edit the file as root on Linux or as an administrator on Windows, or redeploy it through your image or configuration management.
Edit the managed config in place. On Windows, an editor that replaces the file drops the PMG security descriptor. PMG keeps enforcing the file, but the next pmg setup install --system fails with does not carry the PMG security descriptor.A YAML error in the file has no visible effect on the endpoint. PMG cannot read the file, so it keeps the config locked but uses its built-in defaults in place of your settings. Package blocking still works, so the machine looks protected while your policy no longer applies. After every edit, run pmg config get <key> to confirm your setting survived.
On Linux, runtime data (event logs, cloud-sync state, cache) stays per user under ~/.config/safedep/pmg and ~/.cache/safedep/pmg. The invoking user must be able to write their own config directory. Relocate it with PMG_CONFIG_DIR / PMG_CACHE_DIR if needed.
On Windows, per-user config is under %APPDATA%\safedep\pmg. Event logs, cache, and runtime data are under %LOCALAPPDATA%\safedep\pmg.

Cloud sync

Cloud sync reports install events to your SafeDep Cloud tenant, where they appear in Package Guard. To set it up, enable cloud sync and provide your tenant ID and API key from SafeDep Cloud through the SAFEDEP_API_KEY and SAFEDEP_TENANT_ID environment variables.

In a Docker image

Enable sync and set a stable endpoint name before your install steps. Use this setting for containers that run outside Kubernetes.
Do not set PMG_CLOUD_ENDPOINT_ID in an image that runs on Kubernetes. PMG derives a stable Kubernetes workload identity when this value is not set. See PMG in Kubernetes.
Containers report a generated hostname per run, so without PMG_CLOUD_ENDPOINT_ID every run registers as a new endpoint. A stable name is what you will recognize in Endpoint Hub. The credentials exist only where you run docker, as shell exports or CI secrets. They never go in the Dockerfile.
Never bake credentials into an image with ENV SAFEDEP_API_KEY=.... ENV values persist in the image metadata, and anyone who pulls the image can read them.
In the running container, pass them through at start:
Compose environment: entries and Kubernetes Secret references work the same way. If the container is short-lived, a CI job for example, run pmg cloud sync before it exits so buffered events are not destroyed with it.
For reproducible builds, pin PMG to a release tag from the published PMG container image.
During docker build, install steps need no credentials: PMG buffers each event locally. Deliver the buffer in one final RUN step, with the credentials mounted as BuildKit secrets. Mount them directly as environment variables so PMG can use its standard SAFEDEP_API_KEY and SAFEDEP_TENANT_ID credential resolver:
Each --secret reads the variable exported where you run the build:
A blocked package fails its RUN step: later steps never run, including the final sync, so a failed build uploads nothing. The block itself shows in the build output.
Build it with the credentials exported in your shell:

On a shared VM

On Linux, enable sync in /etc/safedep/pmg/config.yml as root:
Then put the credential values in a root-owned snippet such as /etc/profile.d/safedep-cloud.sh, so every login shell exports them:
Users who should sync with their own key can set the same variables in their own shell profile instead. One shared key does not blur the picture: every synced event records which OS user ran the install. It does mean every user on the host can read the key. Installs that ran before the credentials were in place are not lost: PMG buffers those events per user and delivers them on the next sync that finds credentials. Auto-sync cadence, manual sync, and viewing events are covered in Package Guard. The full set of cloud keys is in the PMG configuration reference.

On Windows

As administrator, set cloud.enabled: true in %PROGRAMDATA%\safedep\pmg\config.yml. Each user can then run these commands in their own session:
For managed fleets, use the MDM deployment guides. Supplying credentials alone does not enable sync in the managed config.

Certificates

System install does not set up a MITM certificate authority. For npm and pip on Linux, PMG’s default ephemeral CA and environment-variable injection are sufficient. To install a persistent CA into the OS trust store, run pmg setup cert install --system as your normal user. PATH shims protect the commands that go through them. To route every process on a Linux host through PMG, including processes that never read PATH or proxy variables, see Kernel Enforcement on Linux. It needs the same command as root: sudo pmg setup cert install --system.

Uninstall

On Windows, run from an administrator terminal:
This removes machine shims and their PATH entry. It leaves the binary, its PATH entry, and per-user data. For complete fleet removal, use the MDM uninstaller. On Linux:
This leaves the PMG binary in place. To remove it too, run sudo rm /usr/local/bin/pmg, or uninstall it through your package manager if you installed it that way.

Troubleshooting

Try running pmg setup doctor first. The cases below apply to Linux. For Windows, see Windows coverage.
Version managers like nvm, pyenv, volta, and asdf prepend their own bin directories from rc files that run after /etc/profile.d, putting the real npm/pip ahead of the shims.
  • Keep /usr/local/lib/pmg/bin first in a durable ENV PATH or login PATH
  • Or call pmg npm / pmg pip directly
After source .venv/bin/activate, bare pip uses the venv binary and skips the shims. Call pmg pip inside the venv.
Another account created or owns your config directory. Check the path in the error message.If the path is inside your own home, a root run created it as root. This happens with su without - (prefer sudo or su -) and with images that set ENV HOME before dropping root. Restore ownership:
If the path is inside another user’s home, your environment leaked that user’s HOME or XDG_CONFIG_HOME (common with sudo -u on CI runners). Fix the environment. Do not chown another user’s directory, that breaks PMG for them.

System Install Reference

Full reference in the PMG repo: binary validation rules, user data directories, and limitations.

PMG

How PMG blocks malicious packages at install time.