Skip to main content

Run package installs in a phantom environment with canary credentials to detect supply-chain attacks.

Project description

ShieldPkg

Malicious npm packages steal credentials. ShieldPkg makes sure they only steal fake ones.

Supply-chain attacks like the XZ backdoor and the hundreds of typosquatting packages caught every month share one playbook: install, read ~/.aws/credentials, POST the key somewhere, and wait. ShieldPkg intercepts that playbook at the environment level — the malicious package runs, but every credential it touches is a monitored trap.


See it in action

shieldpkg demo
# Watch ShieldPkg catch a credential theft attempt in real time

shieldpkg demo plants a fake malicious npm package (evil-logger) in a temp directory, runs its postinstall script inside the phantom environment, and watches the circuit breaker kill it when the simulated canary fires. No npm network access required — works completely offline.

Pass --show-source to display the evil package's source before it runs, or --trigger-delay N to control how many seconds before the simulated canary fires (default 8).


What it does

  1. Phantom environment — creates a fake $HOME with realistic-looking .aws/credentials, .ssh/id_rsa, .npmrc, and .gitconfig. Your real home directory is never visible to the subprocess.
  2. Canary tokens — plants real AWS key pairs from canarytokens.org inside the phantom home. If a package exfiltrates them and makes even a single AWS API call, you get an alert with the source IP.
  3. Circuit breaker — polls for canary triggers while the command runs. If a token fires, the process is killed immediately and the event is logged.

Install

pip install shieldpkg

Requires Python 3.9+. Node.js and Rust/Cargo are optional (only needed for shieldpkg experiment).


Quick start

# One-time setup: create the phantom environment and plant canary credentials
shieldpkg init

# Run any package install command inside the phantom environment
shieldpkg run -- npm install some-package
shieldpkg run -- pip install some-package
shieldpkg run -- npx some-cli

# Check phantom home and canary token status
shieldpkg status

# Watch for canary alerts in real time (blocks; use a separate terminal)
shieldpkg monitor

If a canary fires during shieldpkg run, the process is killed and you see:

╔══════════════════════════════════════════════════════╗
║  THREAT DETECTED — Process killed                    ║
║                                                      ║
║  A package attempted to access your credentials.     ║
║  The process was killed before it could exfiltrate.  ║
║                                                      ║
║  Token:   abc123def456…                              ║
║  IP:      198.51.100.42                              ║
║  Channel: HTTP                                       ║
║                                                      ║
║  Your real credentials were not exposed.             ║
╚══════════════════════════════════════════════════════╝

How it works

  • Env sanitizer strips AWS_*, *_TOKEN, *_SECRET, *_PASSWORD, DATABASE_URL, and GITHUB_TOKEN from the subprocess environment before exec. The phantom $HOME is injected instead.
  • Canary polling runs on a background thread during shieldpkg run, calling canarytokens.org every 5 seconds (configurable). On trigger, SIGKILL is sent to the process group.
  • Audit log at ~/.shieldpkg/audit.log records every init, monitor start, trigger, and kill event in append-only JSON-lines format.

Commands

Command Description
shieldpkg init Create phantom home, generate canary AWS credentials
shieldpkg demo [--trigger-delay N] [--show-source] Simulate a supply-chain attack and watch the kill
shieldpkg run -- <cmd> Run <cmd> in phantom env with active monitoring
shieldpkg status Show phantom home and canary token status
shieldpkg monitor [--interval N] Poll canarytokens.org every N seconds (default 60)
shieldpkg audit [--last N] [--triggered-only] Inspect the audit log
shieldpkg experiment --packages <list> Measure JS→Rust transpilation via Strand (research)

shieldpkg experiment (research feature)

Evaluates whether Strand-Rust-Coder-14B can reliably transpile npm packages to Rust with verified behavioural equivalence. Requires Ollama running locally and cargo installed.

shieldpkg experiment --packages ms,left-pad,is-even,uuid --fuzz-inputs 500

Configuration

~/.shieldpkg/config.yaml (created automatically on first run):

monitor_interval: 5   # seconds between canary polls during shieldpkg run

What it doesn't do

  • Not a scanner — ShieldPkg does not analyse package source code or flag suspicious imports. It assumes packages will run and focuses on limiting damage.
  • Not a firewall — outbound network calls are not blocked. A malicious package can still exfiltrate the phantom credentials (that's how detection works), but the credentials it steals are traps.
  • Not a sandbox — the filesystem outside $HOME is visible. If a package targets /etc/passwd, /proc, or absolute paths to well-known credential locations, ShieldPkg won't stop it reading those files.
  • Not a replacement for npm audit — use both. ShieldPkg is a last line of defence, not a substitute for keeping dependencies up to date.

Development

git clone https://github.com/yourname/shieldpkg-core
cd shieldpkg-core
pip install -e ".[dev]"
pytest -v

Exit codes

Code Meaning
0 Command completed cleanly
1 User error (bad arguments, not initialised)
2 System error (Ollama not running, cargo not installed, etc.)

When shieldpkg run detects a threat, it exits 1 after killing the process.


Docs

Document Description
docs/how-it-works.md Phantom env, canary tokens, circuit breaker, and honest limitations
docs/faq.md Common questions about privacy, compatibility, and workflow
docs/roadmap.md Team vault, Strand Rust replacement, credential proxy, network effect

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shieldpkg-0.1.0.tar.gz (56.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shieldpkg-0.1.0-py3-none-any.whl (46.4 kB view details)

Uploaded Python 3

File details

Details for the file shieldpkg-0.1.0.tar.gz.

File metadata

  • Download URL: shieldpkg-0.1.0.tar.gz
  • Upload date:
  • Size: 56.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for shieldpkg-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3e566268d29931e5e2b5e89c69cc468c56cee5b6fcb24f9eadd8e4c246756ce0
MD5 ea81e47570a83e2a2ae6c15d3e3f9221
BLAKE2b-256 51698b98de560aed9a6fa3e49d3b7292e77a1498fa64a90548ddf39701a59bce

See more details on using hashes here.

File details

Details for the file shieldpkg-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shieldpkg-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 46.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for shieldpkg-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60ad9134618d932f97f7f0a7d1be9d37f8a1992aa922657bcc44a79eee4de344
MD5 ab6c11e9c2772c66af8b39dd6d8b1427
BLAKE2b-256 49c53d18c573d044b93902b527a5d0cc674db26b42f8a4f477bc72ecd1673461

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page