A supply-chain firewall for AI coding agents — and the developers who run them.
Coding agents now run npm install and pip install on their own, and a
mistyped or hallucinated package name can pull in malware before anyone looks.
PkgSafe checks a package before it is installed and gives you a clear
allow / warn / block — from your terminal, your CI, or straight from your AI
agent over MCP.
PkgSafe inspects each package for:
- Malicious install hooks —
postinstallscripts that pipecurl … | shor read~/.aws/credentialsand~/.ssh. - Typosquats & "slopsquats" — names that impersonate popular packages (
axois→axios). - Known vulnerabilities — OSV advisories, and it fails safe: an unknown package is never scored as clean.
- Suspicious artifacts — the actual npm tarball and PyPI wheel/sdist contents, not just the metadata.
It runs locally as a single static binary. Nothing about your code leaves your machine.
Docs: Getting started · Full index
PkgSafe acts as a proxy/wrapper around your package managers (npm and pip) or as an MCP server for your AI agents. It intercepts command execution to run security checks before any package code runs or is written to disk.
graph TD
Start([Developer / AI Agent runs install command]) --> Intercept{PkgSafe Intercepts?}
Intercept -- CLI Aliases --> ParseCmd[Parse packages & arguments]
Intercept -- MCP Integration --> ParseCmd
ParseCmd --> IsInstall{Is command an installation?}
IsInstall -- No (e.g. npm run build) --> PassThrough[Transparent Pass-Through] --> ExecuteReal[Execute real package manager command]
IsInstall -- Yes --> CheckDeps[Scan packages: OSV, Heuristics, Policy]
CheckDeps --> Decision{Security Decision?}
Decision -- ALLOW --> ExecuteReal
Decision -- BLOCK --> Fail[Block command & log audit event]
Decision -- WARN --> Prompt{Is Interactive?}
Prompt -- Yes --> AskUser[Prompt for confirmation y/N]
Prompt -- No --> Fail
AskUser -- Yes --> ExecuteReal
AskUser -- No --> Fail
- Pre-Install Interception: Unlike traditional Software Composition Analysis (SCA) or vulnerability scanners that run post-install or post-commit, PkgSafe blocks risky operations before dependencies can run setup hook scripts (
preinstall,postinstall), shielding developer host environments. - Transparent Pass-Through: Administration, test, and build commands (like
npm run buildornpm test) are automatically ignored and passed through to the real package manager, ensuring zero disruption to normal developer workflows. - AI Agent Guardrails: Integrates natively as a Model Context Protocol (MCP) server with Cursor, Claude Code, and other AI agents to block malicious, suspicious, or hallucinated packages before they are executed.
- Local-First Privacy: Runs as a standalone Go binary using a local sqlite cache. Your code, policies, and files never leave your machine.
Homebrew (macOS & Linux):
brew install sairintechnologycom/pkgsafe/pkgsafeOne-line installer (macOS, Linux, any shell):
curl -fsSL https://github.com/sairintechnologycom/pkgsafe/releases/latest/download/install.sh | bashConfirm it's working:
pkgsafe doctorWorks on macOS and Linux (Intel & Apple Silicon) and Windows.
Other install methods & verifying the download
Upgrade via Homebrew:
brew upgrade pkgsafeManual download — grab a release archive for your platform:
VERSION=1.6.0
OS=darwin # linux | darwin | windows
ARCH=arm64 # amd64 | arm64
curl -LO "https://github.com/sairintechnologycom/pkgsafe/releases/download/v${VERSION}/pkgsafe_${VERSION}_${OS}_${ARCH}.tar.gz"
tar -xzf "pkgsafe_${VERSION}_${OS}_${ARCH}.tar.gz"
sudo mv pkgsafe /usr/local/bin/From source (Go 1.25+):
go install github.com/sairintechnologycom/pkgsafe/cmd/pkgsafe@latestVerify signatures. Every release ships checksums.txt with a cosign
signature, GitHub attestations, and per-archive SBOMs. To verify before
trusting a binary:
cosign verify-blob \
--certificate checksums.txt.pem --signature checksums.txt.sig \
--certificate-identity-regexp 'https://github.com/.*/pkgsafe/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
gh attestation verify "pkgsafe_${VERSION}_${OS}_${ARCH}.tar.gz" --repo sairintechnologycom/pkgsafeFull details: docs/install.md · docs/release-verification.md.
The install script honors PKGSAFE_VERSION (pin a version) and
PKGSAFE_BIN_DIR (install location, e.g. $HOME/.local/bin).
Check a package before you install it:
pkgsafe scan-npm-package axios
pkgsafe scan-pypi-package requestsWhen something's wrong, PkgSafe tells you exactly why:
$ pkgsafe scan-npm-package sketchy-pkg
Decision: BLOCK
Package: npm/sketchy-pkg@1.0.0
Risk Score: 100/100
Reasons:
- [medium +20] lifecycle_script_present: Package defines a postinstall script
- [critical +100] credential_path_reference: Lifecycle script references ~/.aws/credentials
Recommended Action: Do not install this package.
Check your whole project's dependencies:
pkgsafe scan-lockfile ./package-lock.json # npm
pkgsafe scan-python-deps ./requirements.txt # PyPI (also pyproject.toml, poetry.lock, uv.lock, Pipfile)
pkgsafe scan-go-deps ./go.mod # Go (preview)
pkgsafe scan-cargo-deps ./Cargo.lock # Cargo (preview)Install with a built-in safety check (scans first, installs only if allowed):
pkgsafe npm-install axios
pkgsafe pip install requestsUnderstand a decision in plain language:
pkgsafe explain axios # npm
pkgsafe explain-pypi requests # PyPIVisualize dependency trees with risk highlighting: Inspect your npm dependencies and easily filter out safe nodes to focus on the packages that PkgSafe flags:
pkgsafe tree package-lock.json --only-riskyVerify lockfile integrity: Audit your lockfile's package integrity and cryptographic hashes against registry and vulnerability records to detect tampering or lockfile-poisoning attacks:
pkgsafe verify package-lock.jsonPkgSafe enforces a configurable security policy. By default, it uses a sensible default policy, but you can fully customize rule severities, risk score weights, custom trusted/blocked package lists, and protected paths:
- Edit policy interactively:
pkgsafe policy edit
- Validate policy syntax:
pkgsafe policy validate ./policy.yaml
- Explain how a policy scores risk:
pkgsafe policy explain ./policy.yaml
- Audit installation history:
Review previous safety scans and decisions recorded in the local audit log:
pkgsafe history - Check system health & environment:
Confirm database status, registry connectivity, OIDC verification setup, and local package managers:
pkgsafe doctor
Modes, policy flag, and JSON output
Modes decide how strict enforcement is (add --mode to any scan):
audit— report the decision, never block.warn— (default) warn on suspicious packages, block critical ones.block— block anything at or above the block threshold.
Policy — pass --policy ./policy.yaml to tune thresholds, trusted/blocked
packages, protected credential paths, and per-rule scores. Without it, a sensible
default policy is used.
JSON — add --json for a stable machine-readable contract (same shape the
MCP tools return):
{
"ecosystem": "npm",
"package": "example-package",
"version": "1.2.3",
"decision": "warn",
"risk_score": 62,
"thresholds": { "allow_max_score": 29, "warn_max_score": 69, "block_min_score": 70 },
"reasons": [
{ "rule_id": "lifecycle_script_present", "severity": "medium", "score": 20,
"message": "Package defines a postinstall script" }
],
"recommended_action": "Review package before installing."
}PkgSafe ships an MCP server so an agent — Claude Code, Cursor, or any MCP client — must consult it before installing anything. Add it to your client config:
{
"mcpServers": {
"pkgsafe": { "command": "pkgsafe", "args": ["mcp", "serve"] }
}
}Now the agent calls validate_package_install before it installs — BLOCK
means never install, WARN means ask a human first — and can look up a real
package when it invents a name that doesn't exist.
| Tool | What it does |
|---|---|
validate_package_install / check_package |
Allow / warn / block a single package |
validate_install_command / check_install_command |
Validate every package in a full npm install … / pip install … command |
suggest_safe_alternative |
Suggest real packages for risky, unknown, or hallucinated names |
explain_package_risk / explain_policy_decision |
Explain why a package is safe, suspicious, or blocked |
score_lockfile |
Score a lockfile's direct and transitive dependencies |
review_dependency_diff |
Review all changed packages between two manifest/lockfile refs |
get_agent_guidance |
Retrieve policy-aware guidance for the current agent context |
record_agent_decision |
Append an agent install decision to the local audit log |
generate_governance_report |
Produce a summary governance report of recent decisions |
get_recent_package_decisions |
List the most recent package scan decisions from the audit log |
get_policy_evidence |
Return policy evidence for a given package or rule |
Talking to the server directly
PkgSafe speaks standard MCP: initialize, then tools/list to discover tools,
then tools/call to run one (tools are called via tools/call, not as
top-level methods):
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"validate_package_install","arguments":{"ecosystem":"npm","name":"axios","requested_by":"ai_agent"}}}Governance tools (generate_governance_report, get_recent_package_decisions,
get_policy_evidence) are also available. Run tools/list for the full schema.
Stop risky dependency changes before they merge. The action scans changed dependencies on a pull request, posts a summary comment, uploads results to Code Scanning, and fails the job on your terms:
name: Dependency gate
on: pull_request
jobs:
pkgsafe:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # PR summary comment
security-events: write # SARIF upload
steps:
- uses: actions/checkout@v4
- uses: sairintechnologycom/pkgsafe@v1.6.0
with:
mode: warn
fail-on: block # fail on any BLOCK (none | warn | block)
changed-only: true # only newly added/changed depsConfigure the lockfile/manifest, ecosystem, policy, and thresholds via inputs — see docs/github-action.md.
| Ecosystem | Support | What's checked |
|---|---|---|
| npm | Full | metadata, OSV, package-lock.json, tarball + install-hook analysis |
| PyPI | Full | metadata, OSV, requirements.txt / pyproject.toml / poetry.lock / uv.lock / Pipfile, wheel & sdist analysis |
| Go | Preview | metadata + OSV, go.mod / go.sum (no content analysis) |
| Cargo | Preview | metadata + OSV, Cargo.lock (no content analysis) |
-
It works offline. Run
pkgsafe update-db --ecosystem allonce to sync OSV advisory data into a local database, then scan with--offlineanytime. For air-gapped machines, PkgSafe can export and import signed advisory bundles — see docs/offline-intelligence-bundle.md. -
Running install scripts to observe them is opt-in — and not a sandbox.
--behavior heuristicexecutes a package's lifecycle scripts on your machine without OS isolation; only use it in a throwaway environment. On Linux,--behavior isolatedruns them inside bubblewrap namespaces with networking off. Plain scanning (the default) never executes package code. See docs/behavior-analysis.md. -
The local REST API is for you, not the network. It binds to localhost and is unauthenticated with no TLS — don't expose it on a public interface.
Start here: docs/README.md (full index) · Getting started · Commands · Policy · Troubleshooting
| Guide | Link |
|---|---|
| Install & verify | docs/install.md · docs/release-verification.md |
| CI / GitHub Action | docs/ci-cd.md · docs/github-action.md |
| AI agents (MCP) | docs/integrations/ |
| Limitations | docs/known-limitations.md |
| Offline / air-gap | docs/offline-intelligence-bundle.md |
Questions or false positives? Open a Discussion or see docs/feedback.md. Include decision, risk score, and rule IDs — never paste secrets, tokens, credentials, or private source.
Contributions welcome:
make test
make build # -> dist/pkgsafe