Chain Gate is a security wrapper for package managers that blocks malicious and vulnerable packages before installation.
- Multi-ecosystem support: Works with npm, Yarn (Classic & Berry), pnpm, gem, bundler, and more
- Real-time malware detection: Uses OSSF malicious-packages database (218,000+ entries)
- Flexible policy modes: Choose between strict, warn, and permissive modes
- Transparent MITM proxy: Intercepts HTTP/HTTPS requests with automatic certificate handling
- Always up-to-date: Syncs with OSSF database on every execution (only when upstream changes)
- Efficient local storage: Uses bbolt for fast offline lookups
- CI/CD friendly: Designed for both local development and CI environments
Chain Gate uses a proxy-based architecture to intercept package manager requests:
- CLI Wrapper: Wraps package manager commands (e.g.,
chaingate npm install) - Local HTTP/HTTPS Proxy: Intercepts all package download requests
- Ecosystem Parser: Extracts package identity (ecosystem, name, version) from requests
- OSSF Malware Database: Local bbolt database synced from ossf/malicious-packages
- Policy Engine: Decides whether to allow, warn, or block based on policy
- Smart Sync: Checks GitHub HEAD on every execution, only downloads when upstream changes
go build -o chaingate ./cmd/chaingatego install ./cmd/chaingateSimply prefix your package manager command with chaingate:
# npm
chaingate -- npm install lodash
# Yarn Classic (v1) or Yarn Berry (v2+)
chaingate -- yarn add react
# pnpm
chaingate -- pnpm install express
# pip (in virtual environment)
chaingate -- pip install requests
# gem
chaingate -- gem install railsChain Gate supports three policy modes:
- strict (default): Always blocks malware
- warn: Warns about malware but allows installation
- permissive: Only logs malware detection, never blocks
# Strict mode (default)
chaingate --mode=strict npm install
# Warn mode
chaingate --mode=warn npm install
# Permissive mode
chaingate --mode=permissive npm install
# CI mode (always blocks malware regardless of mode)
chaingate --ci npm installChain Gate requires an ecosystem configuration file. By default, it looks for:
./configs/ecosystems.yaml/etc/chaingate/ecosystems.yaml
You can specify a custom location:
chaingate --ecosystems-config=/path/to/ecosystems.yaml npm install# Self-check: Verify installation and connectivity
chaingate self-check
# Print current configuration
chaingate print-configFlags:
--mode string Policy mode: strict, warn, or permissive (default "strict")
--ci Enable CI mode (always blocks malware)
--ecosystems-config string Path to ecosystems config file
--log-level string Log level: debug, info, warn, error (default "info")
--data-dir string Data directory for OSSF database (default "~/.chaingate/feeds/ossf")
--github-token string GitHub token for API rate limit (optional, can also use GITHUB_TOKEN env)
-
When you run
chaingate -- npm install lodash, Chain Gate:- Checks GitHub for OSSF malicious-packages updates (only syncs if upstream changed)
- Starts a local MITM proxy on a random port
- Generates a self-signed CA certificate (cached in
~/.chaingate/certs/) - Runs
npm install lodashwith proxy environment variables:HTTP_PROXY,HTTPS_PROXY: Proxy URLYARN_HTTPS_PROXY: Yarn-specific proxy configurationNODE_EXTRA_CA_CERTS: Path to MITM CA certificate for Node.js
- Intercepts all HTTP/HTTPS requests from the package manager
-
For each package download request:
- Intercepts the tarball download URL (e.g.,
registry.npmjs.org/lodash/-/lodash-4.17.21.tgz) - Extracts package identity (ecosystem, name, version) from the URL pattern
- Looks up package in local OSSF malware database (bbolt)
- Checks both exact version matches and semver ranges
- Applies policy to decide: allow, warn, or block
- Intercepts the tarball download URL (e.g.,
-
If blocked:
- Returns HTTP 403 Forbidden to the package manager
- Displays user-friendly error message with MAL-* IDs and details
- Package manager fails with an error
- Installation is prevented
-
If allowed or warned:
- Proxies the request to the actual registry
- Package is downloaded and installed normally
- Warnings are displayed but don't block installation
- OSSF malicious-packages: Community-maintained malware database by the Open Source Security Foundation
- Repository: github.com/ossf/malicious-packages
- Coverage: 218,000+ malicious package entries across npm, PyPI, and other ecosystems
- Format: OSV (Open Source Vulnerability) schema
- Updates: Synced from GitHub on every execution (only downloads when changed)
Chain Gate outputs structured JSON logs for easy parsing:
{
"ts": "2025-11-19T14:43:07.123Z",
"level": "info",
"event": "package_check",
"ecosystem": "npm",
"name": "safe-chain-test",
"version": "1.0.0",
"malware_findings": [
{
"id": "MAL-2025-32615",
"summary": "Malicious code in safe-chain-test (npm)",
"source": "ossf-malicious-packages"
}
],
"decision": "block",
"mode": "strict",
"ci": false,
"request_id": "uuid-..."
}0: Success (package manager succeeded)1: Tool internal error (config error, proxy failure, etc.)2: Blocked due to malware or policy violation3: Failed to query threat intelligence (depends on policy)
- npm: npm, Yarn Classic (v1.x), Yarn Berry (v2+/v4.x), pnpm
- Registries:
registry.npmjs.org,registry.yarnpkg.com - Detection: Tarball URLs with pattern matching
- Registries:
- PyPI: pip, uv, poetry
- Registries:
files.pythonhosted.org - Detection: Wheel and source distribution downloads
- Features: PEP 503 package name normalization
- Registries:
- RubyGems: gem, bundler
- Registries:
rubygems.org - Detection: Gem file downloads
- Registries:
| Package Manager | Version | Status |
|---|---|---|
| npm | 10.x | ✅ Working |
| Yarn Classic | 1.x | ✅ Working |
| Yarn Berry | 4.11.0 | ✅ Working |
| pnpm | 9.x | ✅ Working |
| pip | 24.x | ✅ Working |
| uv | 0.6.x | ✅ Working |
| poetry | 2.x | ✅ Working |
| gem | 3.x | ✅ Working |
- Yarn Berry: Requires
NODE_EXTRA_CA_CERTSfor MITM certificate trust - Cached packages: If a package is already cached locally, it won't be checked again
- pip: Requires virtual environment for proper proxy configuration
chaingate/
├── cmd/
│ └── chaingate/ # CLI entry point
├── internal/
│ ├── proxy/ # HTTP/HTTPS proxy server
│ ├── ecosystem/ # Ecosystem config and parser
│ ├── ossfmalware/ # OSSF malicious-packages client
│ ├── cache/ # Threat intelligence cache (wrapper)
│ ├── policy/ # Policy engine
│ └── logger/ # JSON logging
└── ARCHITECTURE.md # Detailed design docs
go build -o chaingate ./cmd/chaingate# Test self-check (syncs OSSF database and verifies malware detection)
./chaingate self-check
# Test detection with a package in the OSSF database
# Note: Most malicious packages are removed from registries,
# so testing requires packages still listed in OSSF database
# Test with Yarn Berry
./chaingate -- yarn add <package>
# Test with pnpm
./chaingate -- pnpm add <package>
# Test different policy modes
./chaingate --mode=strict -- npm install <package> # Blocks malware
./chaingate --mode=warn -- npm install <package> # Warns about malware
./chaingate --mode=permissive -- npm install <package> # Only logs
# Run unit tests
go test ./...This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Open Source Security Foundation (OSSF): For maintaining the malicious-packages database
- bbolt: For the reliable embedded database