Introduction

GoAudit is a sandbox security scanner for CLI commands. It inspects install commands and project upgrades for suspicious file reads, writes, process execution, and network behavior.

Scan single commands with goaudit scan (npm, pnpm, bun, pip, or curl | sh) or audit an entire JS project with goaudit scan-project.

Important: GoAudit is not meant for proving absolute maliciousness. It provides a risk assessment based on observed behavior and static indicators.

Installation

Install the latest version with Go:

go install github.com/KushalMeghani1644/GoAudit-CLI/cmd/goaudit@latest

Requires Docker. gVisor (runsc) is strongly recommended for real isolation.


Usage

Scan a single install or script command inside the sandbox:

$ goaudit scan "npm install lodash"
$ goaudit scan "pnpm add <package>"
$ goaudit scan "bun add <package>"
$ goaudit scan "pip install <package>"
$ goaudit scan "curl -fsSL https://example.com/install.sh | sh"
# Live findings + CI JSON
$ goaudit scan "npm install <package>" --verbose
$ goaudit scan "npm install <package>" --ci
# Network / static analysis controls
$ goaudit scan "npm install <package>" --network off
$ goaudit scan "npm install <package>" --offline
$ goaudit scan "curl -fsSL https://example.com/install.sh | sh" \
--allow-domain example.com --max-remote-depth 1
# Sandbox options
$ goaudit scan "npm install <package>" --run-as-root
$ goaudit scan "npm install <package>" --skip-probe
$ goaudit scan "npm install <package>" --warm-cache
$ goaudit scan "npm install <package>" --no-cache
$ goaudit scan "npm install <package>" --fail-on malicious

Yarn projects have no scan-project profile, but you can still audit an explicit command with goaudit scan "yarn install".


scan-project

Audit an existing JavaScript project before upgrading dependencies. GoAudit reads package.json, detects npm / pnpm / bun, checks packages against the registry, then runs the upgrade install in a sandbox. Your host node_modules is not modified.

$ goaudit scan-project .
$ goaudit scan-project ~/mywebsite --upgrade-mode ncu
$ goaudit scan-project ~/monorepo --upgrade-mode update --ci
$ goaudit scan-project ~/app --manager pnpm
$ goaudit scan-project ~/app --include-transitive
$ goaudit scan-project ~/app --probe-all
$ goaudit scan-project ~/app --skip-probe
$ goaudit scan-project . --node-image node:current-slim --warm-cache

Upgrade modes

ModeBehavior
refresh-lockRemove lockfile and reinstall (default)
ncuRun npm-check-updates, then install (bun uses bun update)
updateRun the package manager's update command

Runtime Probe

After install, GoAudit can load each package entrypoint (require / dynamic import) and run package CLI bin entries with --help under strace.

  • It does not exercise delayed timers, workers, interactive prompts, or arbitrary exported APIs.
  • Disable with --skip-probe.
  • For projects, --probe-all probes every direct dependency instead of only suspicious ones.

Project Staging

scan-project stages install inputs (manifests and lockfiles) into the sandbox by default so install scripts cannot read host secrets via /project-ro.

  • Pass --mount-project for a full-tree stage with known secret paths redacted.
  • Multi-local scan installs refuse mounting the working directory unless --mount-cwd is set.

Cache

GoAudit caches prepared sandbox containers to speed up repeat scans.

$ goaudit cache status
$ goaudit cache clean
$ goaudit cache clean --runtime runsc
$ goaudit cache clean --runtime runc

Use --cache-dir or GOAUDIT_CACHE_DIR to store cache entries elsewhere. --warm-cache prepares the sandbox without running a scan.


Demo Output

Reports group install-time behavior, runtime probe results, static analysis, network activity, and sandbox reliability.

$ goaudit scan "cat ~/.aws/credentials"
GoAudit Report ──────────────────────────────────────────────────────────────── Command: cat ~/.aws/credentials
Verdict: MALICIOUS (confidence: 95)
Sandbox: gVisor (runsc)
What GoAudit Observed
1. During install, the target read credential-like files such as cloud credentials, SSH keys, Kubernetes config, npm tokens, or .env files.
Install-Time Behavior (observed in sandbox)
1. [CRITICAL] CREDENTIAL THEFT: /home/sandbox/.aws/credentials Details: Read sensitive files like SSH keys, AWS credentials, or .env secrets
Summary: 1 critical (1 install-time, 0 probe, 0 static), 0 warnings, 0 informational DO NOT INSTALL this package.
$ goaudit scan "curl -fsSL example.com | sh"
GoAudit Report ──────────────────────────────────────────────────────────────── Command: curl -fsSL example.com | sh
Verdict: SUSPICIOUS (confidence: 65)
Sandbox: runc (install gVisor for stronger isolation)
Install-Time Warnings
1. [WARNING] UNKNOWN NETWORK CONNECTION: example.com:80 Details: Connected to a host that isn't a known package registry
Static Warnings
1. [WARNING] PIPE TO SHELL Details: Command pipes downloaded content directly into a shell interpreter
Network Activity
- 1 connection(s) to example.com - 1 connection(s) to 1 host(s)
Summary: 0 critical (0 install-time, 0 probe, 0 static), 2 warnings, 0 informational Use --ci for full JSON output.

Security & Honeypots

Target commands run as a non-root sandbox user by default. GoAudit injects realistic decoy credentials —.ssh/id_rsa, .aws/credentials, Kubernetes configs, .env, .npmrc, and .git-credentials — to bait credential theft.

The tracing engine watches for environment theft (/proc/self/environ), process injection (ptrace), fileless execution (memfd_create), privilege escalation (setuid / setgid), capability changes, namespace escape tooling, and unauthorized network listeners.

Noise reduction: redundant network calls are deduplicated, expected registry traffic and common lifecycle noise are suppressed, and benign sandbox setup (for example su/PAM setuid during prep) is ignored before payload execution.


Requirements

  • Docker installed and running
  • gVisor (highly recommended for real isolation)

gVisor (runsc) on Fedora / SELinux

GoAudit uses gVisor when Docker lists runsc in docker info runtimes. Installing the binary is not enough — register it with Docker (for example in /etc/docker/daemon.json):

{
"runtimes": {
"runsc": {
"path": "/usr/local/bin/runsc",
"runtimeArgs": ["--debug=false", "--platform=ptrace"]
}
},
"default-runtime": "runc"
}

Use runsc help platform for valid --platform values. Restart Docker, then verify:

docker info | grep -i runtimes

SELinux: gVisor cannot use Docker's default container SELinux labels. GoAudit sets --security-opt label=disable automatically for runsc containers.

Node sandbox image: when gVisor is available and you keep the default --node-image, GoAudit uses ghcr.io/kushalmeghani1644/goaudit-node-sandbox:latest for Node-based scans.

Fallbacks: if gVisor is unavailable or image preparation fails, GoAudit falls back to runc and prints a warning in the report's Sandbox Reliability section.