Argus scans packages before they land in your environment, blocking malicious install-time code, hardcoded secrets, and dangerous execution paths in packages installed by humans or AI agents.
Modern AI-agent and MCP ecosystems encourage installing packages from the internet with a single command. Manifest checks tell you the package is what its author published — they don't tell you what the code actually does.
Argus extracts the package, walks every source file, and runs language-aware rules. Chain it with && in front of any package manager: critical findings exit 1, the install never runs.
Seven primitives that compose into a single CLI. Each one earns its place — no telemetry, no cloud round-trip, no opinion about your package manager.
Every rule has a defined pattern and severity. Add your own by extending the scanner — the rule sets are plain Go, not a DSL.
Argus is a thin layer in front of your package manager. Each stage is one file in pkg/scanner or cmd/argus — easy to audit, easy to extend.
Argus receives a source — a directory, a .tar.gz, .tgz, .zip, .whl, .crate, or .gem — and stages it in a temp work directory.
Archive extraction runs sanitisePath() on every entry, rejecting zip-slip path traversal. A 100 MiB per-file cap stops zip bombs. Nested archives are auto-extracted up to two levels deep, so payloads hidden in vendored bundles still get scanned.
fs.WalkDir visits every recognised source file and dispatches to the right scanner. package.json lifecycle hooks are also inspected for malicious code.
Go files go to the AST scanner (parse → walk → match dangerous selectors). Python, JS/TS, Ruby, Rust and shell go through their regex rule packs. Every file also gets a Shannon-entropy pass on assignments to catch hidden secrets. package.json lifecycle scripts (install, postinstall, preinstall, and variants) are scanned for exec, eval, and network calls.
Findings are grouped by file and printed to stderr with snippets, ordered by severity.
CRITICAL is rendered with an amber badge; WARNING is dimmed. The line number is exact — for Go, it comes from the AST node; for the regex scanners, from the matching source line.
On a TTY, CRITICAL findings prompt [y/N] before exit. Answering y exits 0. In CI (non-TTY), Argus auto-declines and exits 1.
Whether stdout is a terminal determines the behaviour. Interactive users can override a CRITICAL finding; CI cannot. The blocking default is consistent — a package with CRITICAL findings will not install unattended.
Clean → exit 0. CRITICAL + declined → exit 1. No interactive branch in CI.
The scan model is pipe-friendly. Your shell, Makefile, or CI step uses the exit code. The --json flag (v0.1.2) emits structured findings on stdout for programmatic consumers.
type Severity string
const (
Critical Severity = "CRITICAL"
Warning Severity = "WARNING"
)
type Finding struct {
File string // path relative to scanned package root
Line int // 1-based line number
Rule string // human-readable rule name
Snippet string // offending source line, trimmed
Severity Severity
}
type Scanner interface {
Scan(path string, content []byte) ([]Finding, error)
}Argus runs as a single statically-linked executable. Drop it on your PATH and chain it in front of your installs.
One tap, one install, on your PATH. macOS and Linuxbrew users.
brew tap argusgate/tap brew install argus # Start a temporary protected session argus shell # Or enable persistent shims argus shim install
argus scan <source> # exit 0 on clean, exit 1 on critical findings
argus scan ./pkg && pip install ./pkg argus scan ./pkg && npm install ./pkg argus scan ./pkg.tar.gz && go install ./pkg/... argus scan ./pkg --json | jq '.findings[]' # programmatic output
Coding agents do not always remember to run security tools before installing dependencies. Argus closes that gap by adding optional interception layers around normal package-manager commands.
argus shell starts a protected subshell with Argus shims first on PATH. The safest way to try interception — it does not modify shell profiles.
argus shell npm install lodash pip install requests
Persistent shims place Argus wrappers earlier on PATH. Developers and agents keep using normal package-manager commands; Argus scans before delegating to the real binary.
argus shim install
Adds a checkpoint before Bash commands. Uses Claude Code's PreToolUse hook for Bash and routes suspicious install commands through Argus.
argus hook install claude
argus doctor shows which package managers are protected, which real binaries the shims delegate to, and whether the Claude Code hook is installed.
argus doctor
A documented evasion. Argus is honest about its coverage boundary so you can layer defences appropriately. Taint-flow analysis, planned for v2, would close this gap.
python -m pip, direct downloads, curl | sh, custom install scripts, or deliberate PATH changes. For stronger enforcement, run Argus in CI as a backup gate and review dependency changes before merge.