Define policy once, enforce it everywhere.
safe-pkgs loads typed config from global and project scopes, merges values deterministically, and sanitizes invalid thresholds back to secure defaults.
Global + project overlay
Typed config
Safe defaults
Load order
1. Global config
SAFE_PKGS_CONFIG_PATH if set, otherwise ~/.config/safe-pkgs/config.toml.
2. Project override
SAFE_PKGS_PROJECT_CONFIG_PATH if set, otherwise ./.safe-pkgs.toml.
Project values overlay global values.
Full schema
| Key | Type | Default | Behavior |
|---|---|---|---|
min_version_age_days |
integer | 7 |
Versions newer than this raise risk. <= 0 is reset to default. |
min_weekly_downloads |
integer | 50 |
Packages below this threshold raise risk. |
max_risk |
enum | medium |
low \| medium \| high \| critical. Above this threshold means deny. |
allowlist.packages |
string[] | [] |
Package entries that should be explicitly allowed. |
denylist.packages |
string[] | [] |
Package entries that should be explicitly denied. |
denylist.publishers |
string[] | [] |
Publisher identities to deny. |
staleness.warn_major_versions_behind |
integer | 2 |
Major-version gap warning threshold. 0 resets to default. |
staleness.warn_minor_versions_behind |
integer | 3 |
Minor-version gap warning threshold. 0 resets to default. |
staleness.warn_age_days |
integer | 365 |
Warn if release age exceeds this value. <= 0 resets to default. |
staleness.ignore_for |
string[] | [] |
Package/version patterns excluded from staleness warnings. |
cache.ttl_minutes |
integer | 30 |
Cache TTL in minutes. 0 resets to default. |
Merge rules
Scalar fields
Later sources overwrite earlier values (for example max_risk and numeric thresholds).
List fields
Lists are appended with de-duplication, so global and project entries combine cleanly.
Invalid values
Non-positive values for positive thresholds are reset to defaults to avoid unsafe settings.
Example
min_version_age_days = 7
min_weekly_downloads = 50
max_risk = "medium"
[cache]
ttl_minutes = 30
[staleness]
warn_major_versions_behind = 2
warn_minor_versions_behind = 3
warn_age_days = 365
ignore_for = ["legacy-pkg@1.x"]
[allowlist]
packages = ["my-internal-pkg"]
[denylist]
packages = ["event-stream@3.3.6"]
publishers = ["suspicious-user-123"]
Apply changes
Config is loaded at process start. Restart safe-pkgs serve --mcp after edits.