Skip to content

DevShedLabs/DevScan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DevScan

Version License Go

A developer environment security and health scanner. Detects runtimes, inspects installed packages, and surfaces known vulnerabilities and outdated dependencies — across your global environment or a specific project.

Built with Go. Designed to be scriptable, CI-friendly, and extensible.


Install

# Latest release
go install github.com/DevShedLabs/devscan@latest

# Specific version
go install github.com/DevShedLabs/devscan@v0.1.4

Make sure ~/go/bin is on your $PATH. Add this to your shell profile (~/.zshrc, ~/.bashrc, etc.)
if it isn't already:

export PATH="$HOME/go/bin:$PATH"

Then reload your shell (source ~/.zshrc) or open a new terminal.

Once installed, keep devscan up to date with:

devscan update

Or build from source:

git clone https://github.com/DevShedLabs/devscan
cd devscan
go build -o devscan .

Commands

Command Description
devscan doctor Full scan: runtimes, packages, vulnerabilities, outdated deps
devscan audit Vulnerabilities only
devscan outdated Version drift only
devscan list Inventory of detected runtimes and packages
devscan locate Filesystem paths for every vulnerable package
devscan scan Raw JSON scan output for piping
devscan fix Suggested fix commands
devscan report Export a full report as Markdown, HTML, or JSON
devscan keyscan Scan files for exposed secrets, API keys, and tokens
devscan osv Search OSV for advisories by package name, ID, or keyword
devscan compile Compile blocklist resources into a single index
devscan update-db Fetch latest blocklist databases and recompile
devscan intercept Manage package manager shims for real-time install protection
devscan install-skill Install the Claude Code AI skill into ~/.claude/skills/
devscan update Update devscan to the latest release

Usage

All commands scan the current directory by default. Use --global to scan the entire machine instead.

# Get the version you have installed
devscan --version

# Full health report for the current project
devscan doctor

# Audit the current project for vulnerabilities
devscan audit

# Scan the whole machine (global packages)
devscan audit --global

# Filter to high severity and above
devscan audit --severity high

# Show exactly where vulnerable packages are installed
devscan locate

# Scan a specific path
devscan doctor --path ./my-app

# Scan a project and all sub-projects up to 2 levels deep
devscan doctor --path ./my-app --depth 2

# Machine-readable output
devscan doctor --format json

# CI: exit non-zero if critical vulns found
devscan audit --severity critical

Reports

Generate a shareable report in Markdown, HTML, or JSON:

# Format is inferred from the output file extension
devscan report --output report.html
devscan report --output report.md
devscan report --output scan.json

# Or specify the format explicitly (stdout)
devscan report --html
devscan report --md
devscan report --json

# Scoped to a path
devscan report --output report.html --path ./my-app

# Traverse sub-projects
devscan report --output report.html --path ./my-app --depth 2

# Clean public report (strips internal paths and package inventory)
devscan report --output security-report.md --public

Reports include:

  • System info: OS, version, chip, architecture
  • Summary cards with severity counts and scan duration
  • Runtime versions with outdated status
  • Vulnerabilities grouped by severity, with OSV advisory links, fixed-in versions, and fix commands
  • Filesystem paths for every vulnerable package installation
  • Full package inventory

Blocklists

Augment OSV vulnerability data with your own curated supply-chain blocklists. Any package matched against a blocklist is reported as critical severity alongside normal OSV findings.

Setup

The fastest way to get started is to fetch the latest databases directly from Aikido's open-source threat intelligence feed:

devscan update-db

This downloads the npm and PyPI malware databases from malware-list.aikido.dev, saves them to ~/.devscan/resources/, and compiles the index automatically. devscan update also runs this step so your databases stay current whenever you update the binary.

You can also drop your own blocklist files into ~/.devscan/resources/ and compile manually:

devscan compile

This writes ~/.devscan/devscan.json. All subsequent scans load the compiled index automatically — no flags needed, no rebuild required.

After adding or updating source files, re-run devscan compile to regenerate the index.

Supported formats

CSV — header row required, Ecosystem and Name columns required, Version optional (omit to match any version):

Ecosystem,Namespace,Name,Version,Artifact,Published,Detected
npm,,chai-utils-test,4.5.3,,,2026-06-04T00:00:00Z
pypi,,tlask,3.1.4,,,2026-06-07T15:00:00Z

JSON (generic) — ecosystem must be specified:

[
  { "ecosystem": "npm", "name": "evil-pkg", "version": "1.0.0", "reason": "MALWARE" }
]

JSON (Aikido-style) — auto-detected by the package_name field, treated as npm:

[
  { "package_name": "evil-pkg", "version": "1.0.0", "reason": "MALWARE" }
]

Deduplication

Packages flagged by multiple sources are merged into a single finding. The vulnerability description lists every source file that matched, e.g.:

[CRIT] chai-utils-test@4.5.3
  Malware detected
  This package appears in malwareDatabase_js.json, miasma-attack-packages.csv.
  Reason: MALWARE. Remove or replace it immediately.

Directory layout

~/.devscan/
  resources/           ← drop source files here (*.csv, *.json)
  devscan.json         ← compiled index (auto-used by all scans)
  advisories.yaml      ← global user advisories (optional)

<project>/
  .devscan/
    advisories.yaml    ← project-scoped advisories (optional, commit to repo)

User Advisories

When a security company publishes a disclosure about a compromised package, OSV.dev can take days or weeks to reflect it. User advisories let you flag a package immediately — no waiting, no recompile.

Format

Create .devscan/advisories.yaml in your project root (committed to your repo) or ~/.devscan/advisories.yaml for a global advisory that applies to all projects:

advisories:
  - ecosystem: crates.io
    package: onering
    version: "*"          # all versions
    severity: critical
    reason: "Package compromised — backdoor injected"
    reference: "https://blog.sec.com/2026/06/onering"

  - ecosystem: npm
    package: left-pad
    version: "1.2.3"      # specific version only
    severity: high
    reason: "Malicious version published"
    reference: "https://..."

version: "*" matches every installed version. A specific version (e.g. "1.2.3") matches only that exact release.

How it works

User advisories are merged on top of the compiled blocklist every time devscan runs. No recompile step needed — drop the file and rescan.

To check your system against your advisories without sending every package to OSV, use --advisories-only:

# Fast, private — no network calls to OSV
devscan audit --advisories-only

# Global scan against your custom advisories only
devscan audit --advisories-only --global

This is useful when you've just added an advisory and want to check whether the package is present on your machine, without the latency or data exposure of a full OSV scan.

Matched packages are reported as critical severity findings alongside OSV and blocklist results, and the reference URL is included in the finding description.

Install-time blocking

If you have intercept shims enabled, user advisories also block installs before the package is fetched:

╔══════════════════════════════════════════════════════════════════════╗
║                        DEVSCAN BLOCKED                               ║
╚══════════════════════════════════════════════════════════════════════╝

  [CRITICAL]   onering
               Package compromised — backdoor injected — https://blog.sec.com/2026/06/onering

  cargo add was blocked. Remove this package from your command and try again.

Scope

File location Scope
.devscan/advisories.yaml Project only — commit to share with your team
~/.devscan/advisories.yaml All projects on this machine

Both files are loaded simultaneously when present.


Key Scanning

Scan source files for exposed secrets, API keys, and tokens:

# Scan current directory
devscan keyscan

# Scan a specific path
devscan keyscan --path ./my-app

# Limit depth (useful for large monorepos)
devscan keyscan --path /Users/me/projects --depth 3

# Filter to critical only
devscan keyscan --severity critical

# Export as HTML or Markdown
devscan keyscan --path ./ --format html --output keyscan.html
devscan keyscan --path ./ --format md --output keyscan.md

# Redirect output (also enables live progress counter)
devscan keyscan --path /Users/me/projects --depth 3 > keyscan.html

Detected secret types:

Category Examples
AI providers OpenAI, Anthropic, Google AI, Groq, OpenRouter, Cohere, Replicate
Cloud AWS access/secret keys, GCP service accounts, Firebase, Azure
Source control GitHub tokens (ghp_, ghs_, gho_, github_pat_)
Payments Stripe live keys (sk_live_, pk_live_), PayPal, Braintree
Messaging Slack tokens & webhooks, Twilio, SendGrid, Mailgun
Registries npm tokens
Infrastructure Heroku, Vercel, Netlify, Render, Cloudflare, DigitalOcean
Monitoring Datadog, Sentry, New Relic
Private keys RSA, EC, DSA, OpenSSH private key headers
Database URLs Postgres, MySQL, MongoDB, Redis URLs with embedded credentials
Named vars Any <SERVICE>_KEY, <SERVICE>_TOKEN, <SERVICE>_SECRET where the service name is a known provider

Skips automatically: node_modules/, vendor/, .git/, dist/, binary files, documentation (.md, .rst, .txt), and example/template files (.example, .sample, .dist).

All matched values are redacted in output — only enough context is shown to identify the type of secret, never the full value.

Include in full reports

Add a secrets section to any devscan report:

devscan report --html --include-keys --output report.html
devscan report --md --include-keys
devscan report --json --include-keys --output report.json

Flags

--format string      Output format: table|json|compact (default "table")
--severity string    Filter by severity: critical|high|medium|low
--ecosystem string   Filter by ecosystem: npm|pypi|packagist|crates.io|go
--global             Scan global packages (machine-wide)
--project            Scan current project directory (default)
--path string        Explicit project path to scan
--depth int          Traverse subdirectories up to this depth (0 = path only)
--no-color           Disable color output
--no-cache           Bypass cache and force a fresh advisory lookup
--advisories-only    Match only user advisories and blocklists — skip OSV network lookup
--public             Removes data not needed for public view, eg. repo
-o, --output string  Write report to file (report command only)

Fix Commands

When a fix is available, devscan generates the exact command to run:

Ecosystem Example
npm npm install pkg@^1.2.3
pypi pip install --upgrade pkg>=1.2.3
packagist composer require vendor/pkg:^1.2.3
crates.io cargo update -p pkg --precise 1.2.3
go go get module@v1.2.3
gem gem update pkg

Exit Codes

Code Meaning
0 Clean
1 General error
2 Vulnerabilities found
3 Critical vulnerabilities found
4 Outdated packages found

Useful for CI pipelines:

- name: Security scan
  run: devscan audit --severity high

Intercept

Intercept wraps npm, pip, cargo, and bun with shims that check every explicit package install against your compiled blocklist before the package is fetched — before any postInstall hook can execute.

Most supply-chain attacks run malicious code during installation via post-install hooks, and use tools like Bun and Rust to do further damage on the machine. Intercept stops them at the gate.

How it works

When enabled, devscan writes symlinks into ~/.devscan/shims/:

~/.devscan/shims/npm      →  devscan binary
~/.devscan/shims/pnpm     →  devscan binary
~/.devscan/shims/bun      →  devscan binary
~/.devscan/shims/pip      →  devscan binary
~/.devscan/shims/pip3     →  devscan binary
~/.devscan/shims/cargo    →  devscan binary
~/.devscan/shims/go       →  devscan binary
~/.devscan/shims/composer →  devscan binary

The shims directory sits at the front of your PATH. When you run npm install evil-pkg, the shim runs first, checks the package against your compiled blocklist, and either blocks with a warning or transparently execs the real binary. Non-install commands (npm run, cargo build, etc.) are passed through instantly with zero overhead.

Setup

# 1. Compile your blocklists (required — shims check the compiled index)
devscan compile

# 2. Enable shims and patch your shell profile
devscan intercept enable

# 3. Reload your shell
source ~/.zshrc

Re-run devscan intercept enable any time to sync shims — it is safe to run repeatedly and will add any missing shims without affecting existing ones.

Commands

# Enable shims and patch shell profile
devscan intercept enable

# Disable and clean up
devscan intercept disable

# Check which shims are active and whether the shims dir is on PATH
devscan intercept status

What a blocked install looks like

╔══════════════════════════════════════════════════════════════════════╗
║                        DEVSCAN BLOCKED                               ║
╚══════════════════════════════════════════════════════════════════════╝

  [MALWARE]    chai-utils-test@4.5.3
               Found in: malwareDatabase_js.json

  npm install was blocked. Remove this package from your command and try again.
  Run `devscan audit` for a full vulnerability report.

The warning is printed to stderr in red so it stands out from the surrounding install output. The process exits 1, preventing the install from proceeding.

Keeping shims current

devscan update automatically rewrites shims to point at the new binary. If a new package manager is added in a future release, re-run devscan intercept enable to write the new shims — it is idempotent and safe to run at any time.

Both explicit installs and lockfile installs are scanned. Lockfile commands (npm ci, bun install, composer install, composer update, go get) read the lock file from the current directory and check every pinned package before the real command runs.

Supported package managers

Manager Command intercept
npm npm install, npm i, npm add, npm ci (lockfile)
pnpm pnpm add, pnpm install (lockfile)
bun bun add, bun install (lockfile)
pip pip install, pip3 install
cargo cargo add, cargo install
go go get, go install, go.sum (lockfile)
composer composer require, composer install, composer update (lockfile)
code / code-insiders code --install-extension, code-insiders --install-extension

IDE Protection

VS Code extensions are an increasingly common attack surface. Malicious publishers clone popular extension names, slip through the marketplace review process, and execute arbitrary code on install or activation. devscan addresses this in two ways: auditing what you already have installed, and blocking malicious extensions before they land.

Scan installed extensions

devscan automatically enumerates extensions across all VS Code-family editors on your machine:

  • VS Code~/.vscode/extensions/
  • VS Code Insiders~/.vscode-insiders/extensions/
  • Cursor~/.cursor/extensions/
  • VSCodium~/.vscode-oss/extensions/

Extensions from all detected editors are merged and deduplicated. Run a full audit:

# Audit all installed extensions across every VS Code variant
devscan audit --global --ecosystem vscode

# List every installed extension with version and path
devscan list --global --ecosystem vscode

# Full health check including extensions
devscan doctor --global

Extensions are checked against OSV.dev (using the VSCode ecosystem) and your local blocklists — the same pipeline used for npm, pip, and cargo packages. OSV's VSCode ecosystem is valid but sparsely populated today; blocklists are the primary coverage layer for now. Any finding is reported with severity, advisory ID or blocklist source, and the extension path.

Block malicious extensions at install time

When intercept shims are enabled, code --install-extension is intercepted before the extension is fetched:

# 1. Add known-bad publishers/extensions to your blocklist
#    (see Blocklists section for format)

# 2. Compile the blocklist
devscan compile

# 3. Enable shims — writes shims for `code`, `code-insiders`, and `codium`
devscan intercept enable

# 4. Reload your shell
source ~/.zshrc

After that, any attempt to install a blocklisted extension via the CLI is stopped:

╔══════════════════════════════════════════════════════════════════════╗
║                        DEVSCAN BLOCKED                               ║
╚══════════════════════════════════════════════════════════════════════╝

  [CRITICAL]   malicious-publisher.fake-copilot
               Found in: vscode-blocklist.csv

  code --install-extension was blocked. Remove this extension from your command and try again.

Blocklist format for extensions

Add a CSV to ~/.devscan/resources/ with Ecosystem set to vscode and Name as publisher.extensionname:

Ecosystem,Name,Version,Reason
vscode,malicious-publisher.fake-copilot,,MALWARE
vscode,badactor.crypto-stealer,1.0.0,MALWARE

Omit Version to block all versions of that extension. Then recompile:

devscan compile

GUI installs

The VS Code Extensions panel does not invoke the code binary, so shims cannot intercept GUI installs. devscan's post-install audit (devscan audit --global --ecosystem vscode) is the defence for that path — run it after installing extensions from the marketplace, or schedule it in CI.


OSV Search

Search OSV.dev for advisories directly from the terminal — faster and more scriptable than the OSV web UI.

By package name

# All advisories for a package (all ecosystems)
devscan osv --package axios

# Scoped to a specific ecosystem
devscan osv --package axios --ecosystem npm

# Only advisories affecting a specific version
devscan osv --package axios --version 1.2.3
devscan osv --package requests --ecosystem pypi --version 2.28.0

By advisory ID

Direct lookup by CVE, GHSA, RUSTSEC, PYSEC, or any OSV ID:

devscan osv CVE-2024-1234
devscan osv GHSA-xxxx-yyyy-zzzz
devscan osv RUSTSEC-2024-0001

Free text / keyword search

Searches for the term as a package name across all ecosystems, then filters results where the term appears in the advisory ID, summary, details, or package name:

devscan osv "onering"
devscan osv "prototype pollution" --ecosystem npm

Detail mode

By default results show a one-line summary per advisory. Use --detail to expand full advisory text, all affected version ranges, and references:

devscan osv --package lodash --detail
devscan osv CVE-2024-1234 --detail

Saving reports

Output can be saved as HTML, Markdown, or JSON — format is inferred from the file extension:

devscan osv --package axios --output report.html
devscan osv --package axios --output report.md
devscan osv --package axios --output report.json

# Or specify format explicitly
devscan osv --package axios --html
devscan osv --package axios --json
devscan osv --package axios --md

# Detail mode in a saved report
devscan osv --package axios --detail --output report.html

Supported ecosystems

Pass the short name — devscan maps it to the OSV ecosystem name automatically:

Flag value OSV ecosystem
npm npm
pypi PyPI
cargo, crates.io, rust crates.io
go Go
gem, ruby RubyGems
composer, packagist, php Packagist

Cache

Network results are cached locally to keep scans fast.

Data TTL Location (macOS)
Vulnerability advisories (OSV.dev) 1 hour ~/Library/Caches/devscan/
Runtime latest versions 7 days ~/Library/Caches/devscan/versions/

On Linux: ~/.cache/devscan/ · On Windows: %LocalAppData%\devscan\

Force a fresh lookup at any time:

devscan doctor --no-cache

Config File

Place .devscan.json in your project root or home directory:

{
  "ignore": ["left-pad"],
  "severity_threshold": "medium",
  "ecosystems": ["npm", "pypi"],
  "auto_fix": false
}

Supported Ecosystems

Ecosystem Runtime Packages Vulnerabilities
Node.js / npm ✓ via OSV.dev
Bun ✓ (via npm) ✓ via OSV.dev
Python / pip ✓ via OSV.dev
PHP / Composer ✓ via OSV.dev
Rust / Cargo ✓ via OSV.dev
Go modules ✓ (project) ✓ via OSV.dev
Ruby / Gem ✓ via OSV.dev
Homebrew ✓ via OSV.dev
VS Code extensions ✓ (blocklist only) ✓ via local blocklists; OSV VSCode ecosystem exists but has no data yet
Git

Vulnerability data is sourced from OSV.dev — an open, community-driven vulnerability database covering npm, PyPI, Go, crates.io, Packagist, RubyGems, and more.

Large scans (1000+ packages) are automatically chunked into batches to stay within OSV API limits.


Claude Code Integration

devscan ships a Claude Code skill that lets AI agents run devscan against any project — auditing vulnerabilities, scanning for secrets, checking outdated packages, and generating reports.

Install the skill once:

devscan install-skill

This copies the skill into ~/.claude/skills/run-devscan/, making /run-devscan available in every project in every Claude Code session.

Once installed, Claude can run commands like:

audit this project for vulnerabilities
scan for exposed secrets
check for outdated dependencies
generate an HTML report
look up GHSA-29mw-wpgm-hmr9

The skill source lives at cmd/skills/run-devscan/ and is embedded directly in the binary — no separate download needed.


Architecture

devscan/
  cmd/                  # CLI commands (Cobra)
  internal/
    detectors/          # Runtime detection (node, bun, python, git, php, rust, go)
    inspectors/         # Package inspection (npm, pip, composer, cargo, gomod, vscode extensions)
    advisory/           # Vulnerability lookups (OSV.dev + local blocklists) with 1hr cache
    intercept/          # Package manager shims — pre-install supply-chain blocking
    intercept/managers/ # Per-manager argument parsing (npm, pip, cargo, bun)
    versions/           # Runtime latest-version checks with 7-day cache
    keyscanner/         # Secret and API key detection (file-based pattern scanning)
    sysinfo/            # OS, chip, and architecture detection
    traverse/           # Sub-project discovery by manifest files
    output/             # Terminal renderers (table, JSON, compact)
    report/             # Export renderers (Markdown, HTML, JSON)
    schema/             # Shared types

The JSON output schema is the central contract. The CLI, and future TUI and GUI layers, are all thin wrappers on top of it.


Roadmap

  • Runtime latest-version checks — Go, Node, Bun, Python, PHP, Rust, Git
  • Fix commands for all supported ecosystems
  • Sub-project traversal with --depth
  • Filesystem paths for vulnerable packages
  • System info in reports (OS, chip, arch)
  • HTML and Markdown report export
  • Ruby / gem support
  • Homebrew package inspection
  • Secret and API key scanning (devscan keyscan)
  • --include-keys flag to add secrets section to full reports
  • Local blocklist support — CSV and JSON supply-chain attack databases (~/.devscan/resources/)
  • devscan compile to merge blocklists into a fast single index
  • devscan update-db to fetch latest databases from Aikido Intel and recompile
  • Pre-install intercept shims for npm, pip, cargo, bun, go, composer (devscan intercept)
  • Intercept: lockfile scanning for npm ci, bun install, composer install/update, go get
  • User advisories — flag compromised packages immediately via .devscan/advisories.yaml without waiting for OSV
  • devscan osv — search OSV by package name, version, advisory ID, or keyword; export as HTML/Markdown/JSON
  • Claude Code skill — devscan install-skill installs /run-devscan into ~/.claude/skills/ for AI-assisted scanning in any project
  • VS Code extension scanning — audit installed extensions across VS Code, Insiders, Cursor, and Codium against OSV (VSCode ecosystem) and local blocklists
  • VS Code extension intercept — code --install-extension shim blocks malicious extensions before install
  • System package managers — dpkg (Debian/Ubuntu), rpm (Fedora/RHEL), apk (Alpine)
  • Baseline diff (--compare baseline.json)
  • CI summary output (GitHub Actions annotations)
  • --ignore flag to suppress known/accepted advisories

License

MIT

About

A developer environment security and health scanner. Detects runtimes, inspects installed packages, and surfaces known vulnerabilities and outdated dependencies, across your global environment or a specific project.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors