# Configuration PMG supports local configuration through a configuration file. To create the default configuration file, run: ```bash pmg setup install ``` To see the configuration file path and activated configuration, run: ```bash pmg setup info ``` To edit configuration file: ```bash pmg config edit ``` To get a config value (output is JSON): ```bash pmg config get paranoid pmg config get cloud.enabled ``` To set a config value: ```bash pmg config set paranoid true pmg config set dependency_cooldown.days 10 pmg config set cloud.enabled true ``` See [config template](../config/config.template.yml) for the configuration schema. ## Environment Variables Any configuration key can be overridden using environment variables, without modifying the config file. This is useful for CI/CD pipelines or temporary overrides. **Format:** `PMG_` where the key is the config key uppercased, with nested keys joined by `_`. | Config key | Environment variable | |---|---| | `paranoid` | `PMG_PARANOID` | | `proxy.install_only` | `PMG_PROXY_INSTALL_ONLY` | | `verbosity` | `PMG_VERBOSITY` | | `skip_event_logging` | `PMG_SKIP_EVENT_LOGGING` | | `sandbox.enabled` | `PMG_SANDBOX_ENABLED` | | `dependency_cooldown.enabled` | `PMG_DEPENDENCY_COOLDOWN_ENABLED` | | `cloud.enabled` | `PMG_CLOUD_ENABLED` | The legacy flat key `proxy_install_only` is still supported when the `proxy:` section does not exist in the config file. Proxy interception can no longer be disabled: PMG fails with an error when the config or environment still contains `proxy.enabled: false`, `proxy_mode: false`, `PMG_PROXY_ENABLED=false` or `PMG_PROXY_MODE=false`. See [proxy mode](proxy-mode.md). **Example:** ```bash # Enable paranoid mode without editing the config file PMG_PARANOID=true pmg npm install express # Restrict proxy to install commands only PMG_PROXY_INSTALL_ONLY=true pmg npm install express ``` **Precedence (highest to lowest):** 1. CLI flags 2. Environment variables (`PMG_*`) 3. Config file (`config.yml`) 4. Built-in defaults Under a [globally managed config](#globally-managed-configuration) with `global_lockdown` enabled, PMG disables `PMG_*` and managed-flag overrides. **Limitation** - `config set` can only update keys that are present and uncommented in the config file. If a key is commented out (e.g. `# endpoint_id: "my-machine"`) or missing entirely, `set` will return a "key not found" error. To fix this, uncomment or add the key manually via `pmg config edit`, or run `pmg setup install` to merge missing template keys into your config. ## Globally Managed Configuration For centrally managed or fleet deployments, PMG can read an OS-level **global config file**. When this file exists, it is authoritative: PMG uses it and ignores the per-user `config.yml` (the two are never merged). An administrator ships a machine-wide baseline this way, and can lock it (see [Lockdown](#lockdown)) to forbid user overrides. **Paths** (used when the file is present): | OS | Global config path | |---|---| | macOS | `/Library/Application Support/safedep/pmg/config.yml` | | Linux | `/etc/safedep/pmg/config.yml` | | Windows | `%PROGRAMDATA%\safedep\pmg\config.yml` | Check whether a global config is active with `pmg setup info`: ```bash pmg setup info # Config Source: global <- global config, overrides allowed # Config Source: global (locked) <- global config with lockdown enabled # Config Source: user <- per-user config in effect ``` ### Behaviour Whenever a global config file is present: - **It is authoritative.** PMG ignores the per-user `config.yml`. The file may be **partial**. Keys it does not set fall back to PMG's built-in defaults, not to a user's values. - **`config set` and `config edit` fail.** They return an error stating the config is globally managed. To change it, deploy an updated file at the OS path, which is root-owned and not writable by users. - **`pmg setup install` skips the per-user config.** It still creates shell aliases and shims per user. By default a user can still override the global config's values at runtime through `PMG_*` environment variables and CLI flags. Enable lockdown to forbid that. ## System Install (Linux) See [system-install.md](./system-install.md) for `pmg setup install --system`: artifacts, Docker `ENV PATH`, what works vs what differs (aliases, config edit, logs, cloud, CA, sandbox), and permissions. ### Lockdown Add `global_lockdown: true` to the global config to enforce it: ```yaml # Only meaningful in the global config file. global_lockdown: true ``` When lockdown is on: - **CLI flags that would change a managed value fail fast.** For example, `pmg --sandbox=false ...` or `pmg --paranoid ...` errors out instead of overriding policy. Governed flags: `--paranoid`, `--skip-event-log`, `--sandbox`, `--sandbox-enforce`, `--sandbox-profile`, `--sandbox-allow`, `--skip-dependency-cooldown`. Operational flags such as `--dry-run` keep working. - **`PMG_*` variables cannot change the config**, including `PMG_INSECURE_INSTALLATION` (which otherwise bypasses malicious-package blocking). PMG reads `global_lockdown` straight from the global file, so a user cannot flip it through env or CLI. If the global file exists but cannot be read or parsed, PMG fails closed and treats it as locked. `PMG_CONFIG_DIR` and `PMG_CACHE_DIR` still relocate per-user state directories (logs, cache) in any mode, but leave the managed config alone. ### Precedence | Mode | Effective order (highest to lowest) | |---|---| | No global config | CLI flags > `PMG_*` env > per-user `config.yml` > built-in defaults | | Global config, no lockdown | CLI flags > `PMG_*` env > global config > built-in defaults | | Global config, `global_lockdown: true` | global config > built-in defaults (env and managed-flag overrides refused) | ### Deploying via MDM (macOS) Scripts to install or update PMG and deploy a global config across a macOS fleet (Jamf, Mosyle, Kandji, Intune) live in [`scripts/mdm`](../scripts/mdm). Bundle a `config.yml` next to the scripts. The installer places it at the global path, and the uninstaller removes it. See the [`scripts/mdm` README](../scripts/mdm/README.md) for details.