vulkro inspect
Surface the malicious-capability shapes in a just-cloned project so a human can review them before running any of its code. This is defensive tooling: an "antivirus for source you have not run yet".
inspect projects the shipped mal_* detectors into a grouped
capability surface (credential exfiltration, install hooks, reverse
shells, obfuscation, trojan-source text, and so on) and prints each site
to review by hand.
inspect never certifies code clean
There is no clean / safe / pass / proceed state, and no zero-count reassurance. Every report carries this disclosure verbatim:
This is a static scan of code that has not run, over source an author may have crafted to evade it: it surfaces behaviors for a human to review and can never certify the code free of malicious behavior.
An empty result renders as "No known malicious-capability shapes were surfaced in 0 findings. This is not a safety guarantee." That wording is enforced by test: the renderer refuses to emit the words clean, safe, proceed, or allow in either the empty or the non-empty case.
Usage
vulkro inspect [PATH]
| Argument | Description | Default |
|---|---|---|
PATH | Path to the project root to inspect. | . |
Flags
| Flag | Description |
|---|---|
--json | Emit the machine-readable capability manifest (the CapabilityReport structure) as JSON instead of the text surface. Intended for an agent to consume before running code. The JSON always carries the non-guarantee disclosure and never a safe / clean / proceed verdict. |
How it differs from scan
Unlike vulkro scan, inspect uses the unfiltered finding
set. It deliberately ignores the vuln-scan precision floor (scan's
default --min-confidence) so that Medium-confidence shapes - for
example a committed opaque binary - are never hidden. A malware shape
that would be dropped by the confidence floor still reaches your eyes
here.
scan answers "is this code vulnerable". inspect answers "what can
this code do if I run it".
Capability groups
Each mal- evidence signal maps to one capability bucket. The surface
groups hits by bucket, sorted by count descending then label ascending.
| Capability | What it means | Signal |
|---|---|---|
| Hidden or misleading source text (trojan source) | Unicode bidi overrides, homoglyph or invisible-character tricks that make the rendered source differ from what a compiler or interpreter sees. | mal-trojan-source |
| Opens a shell or reads instance metadata (backdoor shape) | A reverse shell, an nc -e backdoor, or a cloud instance-metadata (IMDS) credential grab. | mal-reverse-shell, mal-imds |
| Reads credentials or secret files | Reads a credential store or secret file (~/.ssh, ~/.aws, keychains, token files). | mal-cred-read |
| Reads and exfiltrates credentials | Reads credentials and sends them off the machine in the same file. | mal-cred-exfil |
| Runs code from an install or build hook | Code that runs from a package or build install hook (git hook, setup.py, build.rs, Makefile fetch-pipe). | mal-install-hook |
| Obfuscated or packed source | Heavy base64 / hex blobs, dynamic decode into eval, string-array unpacking. | mal-obfuscation |
| Execution gated on environment, date, or host (logic-bomb shape) | Execution fenced behind an environment, date, hostname, or not-in-CI gate. | mal-env-gate |
| Self-propagating / worm behavior | Source that copies or re-publishes itself across packages or repos. | mal-worm |
| Reads or targets cryptocurrency wallet material | Wallet files, seed phrases, clipboard address swap. | mal-wallet |
| Fetches and runs remote code | Download-and-eval, remote module load at runtime. | mal-remote-load |
| Installs persistence on the machine | Cron, launchd, systemd, shell-rc, autostart. | mal-persist |
| Committed opaque binary the scanners cannot read | A committed native binary or executable blob the source scanners cannot read: the xz-utils blind spot. | mal-committed-binary |
| Dependency-integrity anomaly | Lockfile / manifest mismatch, integrity-hash gap. | mal-dep-integrity |
| Prompt-injection payload aimed at an AI agent | A payload aimed at an AI agent reading the repo. | mal-prompt-injection |
| Other malicious-capability shape | Any other mal- signal that does not map to a named bucket. Newly added detectors land here rather than dropping out of the surface. | any other mal-* |
Individual sites carry a MAL-* rule id parsed from the finding message
(for example MAL-EXFIL-001, MAL-HOOK-003, MAL-TROJAN-002), or the
raw mal- signal when the message has no id prefix.
Text output
The default view lists each capability group with its count, then up to
three example sites, then a ... and N more site(s) line when the group
has more. The disclosure closes the report.
Capability surface: 4 malicious-capability finding(s) across 2 capability group(s).
Each item below is a behavior to review by hand, not a verdict.
- Reads and exfiltrates credentials (3 finding(s))
MAL-EXFIL-001 at scripts/postinstall.js:12
MAL-EXFIL-001 at scripts/postinstall.js:31
MAL-EXFIL-001 at src/telemetry.js:8
- Runs code from an install or build hook (1 finding(s))
MAL-HOOK-002 at package.json:14
JSON output
--json emits the CapabilityReport structure:
| Field | Description |
|---|---|
capabilities[] | One entry per capability bucket: capability, label, count, and hits[]. |
capabilities[].hits[] | Each site: file, line (1-based), rule_id, and the verbatim finding message. |
total_findings | Total malicious-capability findings projected (the sum of all counts). |
disclosure | The non-guarantee sentence, carried on the report so every consumer renders it. |
There is no verdict field. Nothing in the JSON says safe, clean, or proceed.
Exit codes
0ran and surfaced no known malicious-capability shapes. This is not a pass and not a safety guarantee: static analysis over unrun, potentially adversarial source cannot see everything.1malicious-capability shapes were surfaced: human review is required before trusting or running this code.2error (bad path, IO failure, internal crash).
Privacy
inspect renders locally. No finding data leaves the machine.
Examples
# Review a repo you just cloned, before running its install script.
git clone https://example.com/some/repo && cd repo
vulkro inspect .
# Machine-readable manifest for an agent to read before running code.
vulkro inspect . --json > capabilities.json
From an AI agent
The same surface is exposed over MCP as the inspect_repo tool, so an
agent can check a repository before running any of its code. See
vulkro mcp.
Not to be confused with
vulkro-live inspect is a different command in the
free Vulkro Labs CLI: it answers "is this MCP server safe to add" by
resolving a server spec to its backing registry package. vulkro inspect
reviews source you already have on disk.
Related
vulkro scan- the full security pipeline, with the confidence floor applied.vulkro guard- the in-loop gate.vulkro mcp- theinspect_repoMCP tool.- Confidence model - the precision floor
that
inspectdeliberately bypasses.