Runtime security for developers who ship with AI.
Your AI coding assistant can read your SSH keys, leak your AWS credentials, and run up a $10,000 API bill before you notice. Sanctum watches for all of it -- silently, in the background, without slowing you down.
curl -fsSL https://raw.githubusercontent.com/postrv/sanctum-oss/main/scripts/install.sh | sh
sanctum init
# That's it. The daemon starts with your shell.In one week (March 24--31, 2026), three major supply chain attacks hit the ecosystems developers use every day:
- LiteLLM (March 24) -- Compromised PyPI credentials injected a malicious
.pthfile into Python'ssite-packages. Every time the interpreter started -- evenpython3 --version-- it ran attacker code that stole SSH keys, cloud tokens, and.envfiles. (CVE-2026-33634, CVSS 9.4) - Telnyx Python SDK (March 27) -- Malicious PyPI versions used audio steganography (payload hidden in WAV files) for credential theft. Same threat actor (TeamPCP) leveraging CI/CD secrets stolen from an earlier Trivy compromise.
- Axios (March 31) -- Maintainer account takeover on npm. Two malicious versions of the most popular HTTP client (~100M weekly downloads) added a phantom dependency whose
postinstallscript deployed a cross-platform RAT. Live for under 3 hours, but the blast radius was enormous. (GHSA-fw8c-xr5c-95f9)
These attacks worked because nothing was watching at the moment code ran.
Sanctum watches.
Monitors every Python site-packages directory for new or modified .pth files. Each line is classified as benign (import-only), suspicious (dynamic code), or critical (exec/eval/network). Critical files are quarantined immediately and replaced with empty stubs.
When a .pth file appears, Sanctum traces the process lineage to determine who created it. pip install creating a .pth? Expected. Python startup silently writing new .pth files? That's the attack.
$ sanctum review
Quarantined items (1 total):
------------------------------------------------------------------------
ID: a1b2c3d4
Original: /usr/lib/python3/site-packages/evil-package.pth
Reason: CRITICAL: exec(open('/tmp/.payload').read())
Quarantined: 2026-03-28 14:23:01
------------------------------------------------------------------------
Actions:
sanctum review --approve <ID> — restore file to original location
sanctum review --delete <ID> — permanently remove quarantined file
AI coding assistants hallucinate package names. Sanctum checks every npm install, pip install, go get, cargo add, and brew install command against the real registry before execution. Non-existent packages are blocked -- stopping typosquatting and AI-hallucinated package installs before they run.
Beyond existence checks, Sanctum enforces install-time safety across ecosystems:
| Ecosystem | Protection |
|---|---|
| npm | Blocks installs without --ignore-scripts (the axios attack vector) |
| pip | Warns/blocks installs without --only-binary :all: (prevents setup.py execution) |
| Cargo | Warns when new crates with build.rs are downloaded at compile time |
| Homebrew | Verifies official formulae/casks, warns on untrusted taps and Brewfiles, blocks direct URL/path formula installs |
| Docker | Warns on :latest/untagged images, untrusted registries, and unsafe Dockerfile patterns |
Shell-aware command splitting detects chained commands (cd /tmp && npm install evil) that would otherwise bypass detection.
Scans all content passing through AI tool hooks against 37 credential patterns -- OpenAI, Anthropic, AWS, GitHub, Stripe, Slack, GCP, Azure, Docker Hub, Vault, and more. Catches secrets before they leave your machine, not after they're in a training set.
Also runs Shannon entropy analysis to detect high-entropy strings that look like secrets, even when they don't match a known pattern.
$ echo '{"command": "cat ~/.aws/credentials"}' | sanctum hook pre-bash
{"decision":"block","reason":"Reads sensitive credential path: ~/.aws/credentials"}
Tracks per-provider, per-session, and daily spend across OpenAI, Anthropic, and Google APIs. Set budget thresholds, get alerts at configurable percentages, restrict which models each provider can use.
$ sanctum budget
Provider Session Spend Session Limit Daily Spend Daily Limit
openai $8.20 $30.00 $12.40 $100.00
anthropic $4.20 $20.00 $4.20 $100.00
Monitors access to ~/.ssh, ~/.aws/credentials, ~/.kube/config, and other sensitive paths. When an unexpected process touches your credentials, you'll know.
Detects outbound connections on unusual ports, to blocklisted destinations, or from unexpected processes. Uses configurable rules-based detection with safe port allowlists and process allowlists.
Tracks cumulative bytes sent per destination host within a sliding time window. Configurable thresholds trigger warnings (default 5MB) or blocks (default 20MB) with desktop notifications and audit logging. Alert suppression prevents notification floods, and a 10K host cap bounds memory usage.
Sanctum provides pre- and post-tool hooks for Claude Code:
sanctum hooks install claudeThis installs five hook handlers:
| Hook | What it does |
|---|---|
pre-bash |
Blocks credential access, env var exfiltration, slopsquatting, dangerous package-manager patterns, Docker image safety |
pre-write |
Prevents writes to sensitive paths, detects credential injection, Dockerfile linting |
pre-read |
Blocks reads of SSH keys, cloud credentials, private keys |
pre-mcp |
Enforces MCP tool policies, audits all invocations |
post-bash |
Scans command output for leaked credentials, cargo build.rs warnings, extracts API spend |
A malicious repo config cannot disable these protections -- Sanctum enforces a security floor that project-local configs cannot lower.
sanctum init # Set up Sanctum in your project
sanctum status # Daemon status (works offline too)
sanctum doctor # Health check your installation
sanctum scan # Scan project for credential exposure
sanctum review # Review quarantined threats
sanctum run -- <cmd> # Run a command with protections active
sanctum config # View config (--edit to modify, --recommended for defaults)
sanctum audit # Threat event log (--last 24h, --level critical, --json)
sanctum fix list # Unresolved threats (--category, --level, --json)
sanctum fix resolve <id> # Remediate a threat (--action restore|delete|dismiss)
sanctum fix all --yes # Batch-remediate all unresolved threats
sanctum budget # View current spend
sanctum budget set # Set session/daily limits
sanctum budget extend # Extend session budget
sanctum budget reset # Reset counters
sanctum hook <action> # Hook handler (called by Claude Code, not you)
sanctum hooks install claude # Install Claude Code hooks
sanctum hooks remove claude # Remove Claude Code hooks
sanctum daemon start|stop|restart
sanctum proxy start|status # stop: terminate the proxy process manually# .sanctum/config.toml
[sentinel]
watch_pth = true
watch_credentials = true
watch_network = false # network anomaly detection (opt-in)
pth_response = "quarantine" # quarantine | alert | log
# [sentinel.cargo]
# allowlist = ["my-internal-crate"]
# warn_build_scripts = true # warn on new crate downloads (build.rs risk)
# [sentinel.pip]
# warn_source_installs = true # warn about setup.py execution risk
# require_binary_only = false # set true to block pip without --only-binary :all:
[sentinel.homebrew]
trusted_taps = ["homebrew/core", "homebrew/cask", "homebrew/services", "homebrew/bundle"]
warn_untrusted_taps = true # warn on brew tap or owner/repo/formula outside trusted_taps
warn_no_quarantine = true # warn on cask --no-quarantine
block_external_formula_installs = true
warn_brewfile = true # warn on brew bundle/Brewfile installs
[ai_firewall]
redact_credentials = true
claude_hooks = true
mcp_audit = true
check_package_existence = true # slopsquatting detection (npm, pip, go, cargo, brew)
[[ai_firewall.mcp_rules]]
tool = "filesystem_write"
restricted_paths = ["/etc/*", "/usr/*", "~/.ssh/*"]
[ai_firewall.docker]
trusted_registries = ["docker.io", "ghcr.io", "gcr.io", "public.ecr.aws", "registry.k8s.io"]
warn_latest = true # warn on :latest or untagged images
[budgets]
default_session = "$50"
default_daily = "$200"
alert_at_percent = 75
[budgets.providers.openai]
session = "$30"
daily = "$100"
allowed_models = ["gpt-5.4", "gpt-5.4-mini"][sentinel.network]
exfiltration_warn_bytes = 5242880 # 5MB — desktop notification
exfiltration_block_bytes = 20971520 # 20MB — block + audit event
exfiltration_window_secs = 60 # sliding window (1-3600s)[[ai_firewall.mcp_cel_rules]]
expression = 'tool_name == "filesystem_write" && paths.exists(p, p.startsWith("/etc"))'
action = "deny"
[[ai_firewall.mcp_cel_rules]]
expression = 'payload_size > 1048576'
action = "warn"CEL expressions are non-Turing-complete and have no side effects. Available context variables: tool_name (string), paths (list of strings), payload_size (int).
Generate a recommended starting config with sanctum config --recommended.
Full configuration reference: see sanctum config --recommended for annotated defaults.
git clone https://github.com/postrv/sanctum-oss
cd sanctum-oss
cargo build --release
# Binaries: target/release/sanctum, target/release/sanctum-daemonRequires Rust 1.94.0+ (pinned in rust-toolchain.toml).
curl -fsSL https://raw.githubusercontent.com/postrv/sanctum-oss/main/scripts/install.sh | shThe installer verifies SHA-256 checksums (mandatory) and Sigstore signatures (if cosign is installed). See SECURITY.md for the verification model.
# Add to your ~/.zshrc (or ~/.bashrc, ~/.config/fish/config.fish):
eval "$(sanctum init --shell zsh)"
# Install Claude Code hooks:
sanctum hooks install claudeSee the Getting Started guide for a complete walkthrough.
Sanctum runs as a background daemon that starts with your shell. The daemon watches the filesystem, monitors processes, and serves an IPC socket for the CLI and hook handlers.
Claude Code Your shell
| |
[pre-bash hook] [shell hook]
| |
sanctum hook ----IPC----> sanctum-daemon
| | |
.pth watch | credential watch
|
network monitor
The CLI is stateless -- it talks to the daemon over a Unix socket. Hook handlers are fast (single IPC round-trip) so they don't slow down your AI coding session.
Sanctum composes with nono.sh for kernel-level sandboxing:
# nono: kernel sandbox + phantom proxy
# sanctum: runtime monitoring + AI firewall + budget control
nono run --profile claude-code -- claudeSanctum does not require nono. Each tool provides independent value.
8 crates, ~51,000 lines of Rust, 6 ecosystem integrations (npm, pip, Go, Cargo, Homebrew, Docker):
| Crate | Purpose |
|---|---|
sanctum-cli |
CLI interface -- 14 commands via clap |
sanctum-daemon |
Background daemon, IPC server (14 commands), event loop |
sanctum-sentinel |
.pth monitoring, quarantine, credential watching, network anomaly detection |
sanctum-firewall |
Credential redaction (37 patterns), Shannon entropy, MCP policy engine, slopsquatting detection (5 registries), package-manager safety checks |
sanctum-budget |
Spend tracking, 3 provider parsers (OpenAI, Anthropic, Google) |
sanctum-proxy |
HTTP budget proxy with body limits, credential redaction, budget enforcement, SSRF prevention, and usage extraction |
sanctum-types |
Shared types, config schema, threat model, platform paths |
sanctum-notify |
Cross-platform desktop notifications (macOS + Linux) |
Sanctum is a security tool. It holds itself to a higher standard than the code it protects.
Compile-time guarantees (enforced by workspace lints -- not conventions, compiler errors):
- Zero
unsafecode - No
unwrap(),expect(), orpanic!()outside tests - No
print!()/println!()/eprint!()-- all output goes through structured channels
Testing:
- 2,000+ tests (unit, integration, end-to-end, loom concurrency)
- 9 Kani bounded model checking proofs (panic-freedom, state machine correctness, overflow safety)
- 2 fuzz targets on security-critical parsers (CI runs 30s per target on PRs, 2.5h nightly)
- 9 property-based tests verifying core invariants across random inputs
- 0 clippy warnings (pedantic + nursery lints enabled)
Supply chain:
- All dependencies audited and version-pinned (344 crates in Cargo.lock)
cargo-denyenforces license policy and advisory database checks in CI- Sigstore-signed release binaries with SBOM and Rekor transparency log
- Reproducible builds verified in CI (build twice, compare SHA-256)
Documentation:
- SECURITY.md -- Vulnerability reporting and security guarantees
- THREAT_MODEL.md -- What Sanctum does and doesn't protect against
- ARCHITECTURE.md -- Design decisions with security rationale
- DEPENDENCY_AUDIT.md -- Every dependency justified
Sanctum is open source under the MIT license. Contributions are welcome.
Before submitting a PR, ensure:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features # must be 0 warnings
cargo test --all --all-features # must passThe workspace lint configuration is strict by design. If clippy complains, fix the code -- don't suppress the lint.
MIT -- see LICENSE.