Files
pmg/docs/system-install.md
T
Sahilb315 cd9b45b3bc fix: triage the unwritable config dir remedy by cause
The chown hint is only correct when another account created files
inside the current user's own home. When a leaked HOME or
XDG_CONFIG_HOME points at another user's home (e.g. sudo -u on GitHub
runners), following it would chown that user's directory and brick
their pmg instead. Classify the failure against the passwd home,
which the leaked environment cannot influence, and prescribe:

- dir inside own home: restore ownership with chown
- dir outside own home: fix the leaked environment, never chown
- explicit PMG_CONFIG_DIR: make it writable

Used by both the fatal event-log error and the doctor check, and the
docs troubleshooting now carries the same two-case triage.
2026-07-14 03:56:07 +05:30

6.6 KiB

System Install (Linux)

Use system install when one machine or image should protect every user account: shared VMs, golden Docker images, and similar setups.

sudo pmg setup install --system

Requires Linux and root. Because every user's shims execute the PMG binary by its absolute path, --system validates it first: the binary must be root-owned, world-executable, and not writable by group or others, and it must sit in a root-owned directory that is not world-writable. Install PMG as root into a standard path such as /usr/local/bin; a user-local build (e.g. ~/go/bin/pmg) is rejected.

Per-user pmg setup install remains available and does not conflict with a system install.

To uninstall:

sudo pmg setup remove --system
sudo pmg setup remove --system --config-file   # also remove the system config file

Files created

Item Path
Configuration /etc/safedep/pmg/config.yml
Package-manager shims /usr/local/lib/pmg/bin
Shell PATH snippet /etc/profile.d/pmg.sh

Making shims visible on PATH

System install writes shims to /usr/local/lib/pmg/bin. Processes only use them when that directory is on PATH ahead of the real npm, pip, and other package managers.

Linux VMs and login shells

pmg setup install --system installs /etc/profile.d/pmg.sh, which prepends the shim directory for login shells.

sudo pmg setup install --system

New login sessions pick this up automatically. For an already open shell, start a new login session or run:

source /etc/profile.d/pmg.sh

Confirm with:

which npm    # should resolve under /usr/local/lib/pmg/bin
pmg setup doctor

Docker and container images

Docker RUN does not load /etc/profile.d. After system install you must set ENV PATH so build steps and the runtime container see the shims:

FROM node:22-bookworm

RUN curl -fsSL https://raw.githubusercontent.com/safedep/pmg/main/install.sh | sh \
 && pmg setup install --system

# Required: profile.d is not sourced during docker build
ENV PATH="/usr/local/lib/pmg/bin:$PATH"

# Optional: switch user; PATH from ENV still applies
RUN mkdir -p /app && chown node:node /app
WORKDIR /app
USER node
COPY --chown=node:node package*.json ./
RUN npm ci

Derived images inherit that ENV. Later RUN npm install / RUN pip install go through PMG for any USER.

If a child Dockerfile sets ENV PATH=... again, keep /usr/local/lib/pmg/bin ahead of the real npm/pip directories. Leaving it out (or behind those toolchains) drops interception.

PMG running on the Docker host cannot inspect package installations inside docker build. PMG must be installed in the image as shown above.

Configuration

The system config file is authoritative for every user. A per-user config.yml is ignored while /etc/safedep/pmg/config.yml exists.

pmg config set and pmg config edit fail under a system config. Update the file as root, or redeploy it through your image or configuration management.

Optional lockdown (global_lockdown: true) is documented in config.md.

Limitations

  • Virtualenv. After source .venv/bin/activate, bare pip uses the venv binary and skips PMG shims. Call pmg pip … explicitly.
  • Version managers. Tools like nvm, pyenv, volta, and asdf often prepend their own bin directories from shell rc files that run after /etc/profile.d. That can put real npm/pip ahead of PMG shims even when the shim directory is on PATH. Prefer putting /usr/local/lib/pmg/bin first in a durable ENV PATH / login PATH, or call pmg npm / pmg pip explicitly. pmg setup doctor warns for any supported package manager that resolves outside the shim directory.
  • No shell aliases. System install only installs PATH shims. There is no ~/.pmg.rc alias layer.
  • Config changes. pmg config set and pmg config edit are unavailable while the system config is active. Edit /etc/safedep/pmg/config.yml as root, or redeploy the file.
  • Custom sandbox policy_templates. Relative paths in the system config resolve under each user's config directory, not /etc/safedep/pmg. Prefer absolute paths.
  • pmg sandbox allow. Blocked when the system config sets global_lockdown: true.

User data directories

Shared policy lives under /etc/safedep/pmg. Runtime data stays per user:

Data Default location
Event logs ~/.config/safedep/pmg/logs/
Cloud sync state ~/.config/safedep/pmg/cloud-sync.db
Cache ~/.cache/safedep/pmg/
Sandbox overlays ~/.config/safedep/pmg/sandbox/overlays/
Persistent CA keypair ~/.config/safedep/pmg/ca-cert.pem, ca-key.pem

You can relocate these with PMG_CONFIG_DIR and PMG_CACHE_DIR.

The invoking user must be able to write their config directory. PMG records an event log there on each run and fails the command if it cannot (unless event logging is disabled in config).

In Docker images, avoid creating /home/<user>/.config/safedep as root during the build. Either fix ownership for the runtime user, or set PMG_CONFIG_DIR to a writable location.

If every pmg command fails with permission denied on the event log, check where the reported path points:

  • Inside your own home: a root run created it as root (preserved HOME: sudo -E, su without -, images that set ENV HOME before dropping root). Restore ownership: sudo chown -R $(id -un) ~/.config/safedep
  • Inside another user's home: your environment leaked that user's HOME or XDG_CONFIG_HOME (e.g. sudo -u <user> on GitHub-hosted runners). Fix the environment (export XDG_CONFIG_HOME="$HOME/.config"). Do not chown another user's directory; that bricks their pmg instead.

The error message and pmg setup doctor print the fix matching your case.

For cloud sync, enable cloud in the system config and provide credentials (SAFEDEP_API_KEY and SAFEDEP_TENANT_ID, or a keychain login on developer machines).

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 enough.

To install a persistent CA into the OS trust store, use a separate command:

pmg setup cert install --system

Run that as your normal user. Details are in cert.md.