Architecture¶
pkggate is a Python proxy server that intercepts package manager traffic, evaluates each request against threat intelligence and policy rules, and either forwards or blocks the request.
Request flow¶
Package Manager
|
v
pkggate proxy (HTTP server, port 8080)
|
+---> Policy Engine <--- policy.yaml (hot-reloaded)
| |
| OSV Mirror DB (SQLite)
| |
| [optional] OSV Live API
|
v
Upstream Registry (npmjs.com / pypi.org)
|
v
Package Manager (tarball / metadata)
Components¶
Proxy layer (src/pkggate/proxy/)¶
Ecosystem-specific adapters that implement the registry protocol:
- npm adapter — implements the npm registry HTTP API. Intercepts metadata responses to strip malicious versions and tarball requests for a final pre-delivery check.
- PyPI adapter — implements PEP 691 Simple Repository JSON API. Intercepts the simple index to rewrite URLs and filter versions, and the file endpoint to verify integrity.
Each adapter is a plugin point — new ecosystems (Cargo, Maven, RubyGems) can be added without touching the core.
Policy engine (src/pkggate/policy/)¶
Evaluates a request against the configured rules in config/policy.yaml. Returns (action, rule, source) — allow or block, plus which rule triggered and the advisory ID if applicable.
The policy file is watched for changes and hot-reloaded without restarting the proxy.
OSV mirror (src/pkggate/mirror/)¶
Downloads OSV advisory bundles from GCS, extracts MAL-* advisories, and stores them in a local SQLite database. A background task refreshes each ecosystem's bundle on the configured interval. Incremental updates mean only changed advisories are re-processed.
Audit logger (src/pkggate/audit/)¶
Appends a JSON Lines record to audit.log for every proxy decision.
Data flow: npm install¶
npm install expresssendsGET /expressto pkggate.- pkggate fetches
https://registry.npmjs.org/expressupstream. - For each version in the response, the policy engine checks the OSV mirror.
- Versions with
MAL-*advisories are removed from theversionsmap. - The filtered metadata is returned to
npm. npmpicks a version and requestsGET /express/-/express-4.18.2.tgz.- Policy is evaluated again (last-stop check).
- If clean, the tarball is proxied from upstream.
- Each decision is written to
audit.log.
Data flow: pip install¶
pip install requestssendsGET /simple/requests/to pkggate.- pkggate fetches the upstream Simple index.
- Policy is evaluated per file entry; denied versions are removed.
- Surviving file URLs are rewritten to point back through pkggate.
pipselects a version and requests the rewritten file URL.- pkggate re-evaluates policy, fetches the file upstream, verifies the SHA-256 hash, and streams it to
pip.
Extending pkggate¶
To add a new ecosystem adapter:
- Create a new module under
src/pkggate/proxy/. - Implement the upstream protocol (metadata + file endpoints).
- Call the policy engine for each version/file decision.
- Register the adapter's routes in the main application.
The policy engine and OSV mirror are ecosystem-agnostic — the adapter only needs to map ecosystem-specific concepts (version strings, file hashes) onto the common check(ecosystem, package, version) interface.