Skip to content

CLI Reference

cyb3rjerry edited this page May 23, 2026 · 1 revision

CLI Reference

Every fangs subcommand with flags + examples. Source: cmd/fangs-cli/internal/cli/.

Global flags

fangs [global flags] <subcommand> [args]
Flag Default Purpose
-storage sqlite sqlite | postgres
-sqlite-path var/lib/fangs/fangs.db sqlite DB path
-postgres-dsn postgres DSN; also reads $FANGS_PG_DSN
-json false machine-readable JSON instead of tables

fangs package

Manage the watcher's watch list.

fangs package add <name> [flags]

Validate against npm registry, refuse duplicates, add to watch list, queue an immediate scan of current latest version.

fangs package add axios
# → validated; added; kickoff scan queued: run_id=18b2089cca…

fangs package add axios
# → fangs: package "axios" is already watched (added 2026-05-22T01:23:45Z)

fangs package add typo-name-xyz
# → fangs: package add: "typo-name-xyz" not found on registry.npmjs.org

Flags:

Flag Default Purpose
-orchestrator URL http://127.0.0.1:8443 orchestrator URL for the kickoff scan
-runner ID (server picks) target runner id
-skip-initial-scan false don't queue a kickoff scan
-skip-registry-validate false trust the package name without checking
-duration 60s 60s max sandbox duration for the kickoff

fangs package list

Packages that have at least one run — the post-scan summary view. Empty when no scans have happened yet.

fangs package watched

Current watch list with last_checked_at + last_seen_version from the watcher.

fangs package remove <name>

Remove from the watch list. Does not delete existing runs.

fangs run

fangs run list [-package P] [-limit N]

Recent runs, newest first.

fangs run show <run_id_prefix>

Run header + event-type breakdown + deviation summary. Prefix-match on the run id (git-style short ids).

fangs deviation

fangs deviation list [flags]

Flag Purpose
-package P filter to one package
-severity S filter by severity
-run-id R filter to one run
-limit N cap rows (default 100)

fangs deviation show <id_prefix>

Full deviation detail + the evidence event payload.

fangs baseline

fangs baseline list -package P

Baseline fingerprints for a package — the rolling memory of "what this package normally does."

fangs baseline promote <run_id_prefix>

Re-extract the run's fingerprints (with current allowlist applied), merge into baseline, mark is_baseline=true, clear deviation rows.

fangs release

fangs release list -package P [-limit N]

Releases the watcher has observed for a package.

fangs notifier

fangs notifier add [flags]

Required:

Flag Purpose
-name N unique identifier
-url U webhook URL (https:// or loopback http://)
-template T slack | discord | generic

Optional:

Flag Purpose
-secret-env ENV env var holding HMAC secret (generic only)
-min-severity S only fire on runs with max severity ≥ S
-headers JSON extra request headers as JSON object
-enabled=false disable without removing

fangs notifier list

Configured targets with their template + enabled state + HMAC binding.

fangs notifier remove <name>

Delete a target. CASCADE-removes its notifications audit rows.

fangs notifier test <name>

Fire a synthetic payload. Verifies URL + reachability. No HMAC even when secret_env is set.

fangs notifier history -run R

Delivery attempts for one run. Use after a Slack message is missing to see if FANGS tried to send it.

fangs allow

fangs allow add [flags]

Required:

Flag Purpose
-kind K cidr | path | sni
-value V the rule value

Optional:

Flag Purpose
-package P scope to a specific package (omit = global)
-note N free-form comment
fangs allow add -kind cidr -value 10.0.0.0/8 -note "internal"
fangs allow add -kind sni -value telemetry.example -package axios
fangs allow add -kind path -value /opt/vendor/ -package my-pkg

fangs allow list [-package P]

All entries, optionally narrowed. Config-managed entries have cfg…-prefixed IDs.

fangs allow remove <id_prefix>

Delete an entry. Config-managed entries return on next orchestrator restart unless the YAML is also edited.

fangs scan

fangs scan submit -package P -version V [flags]

Validate package@version exists on the registry, then POST /v1/scans to the orchestrator.

Flag Default Purpose
-package P required npm package name
-version V required exact version (no range)
-orchestrator URL http://127.0.0.1:8443 orchestrator base URL
-runner ID hostname target runner
-duration 60s 60s max sandbox duration
-skip-registry-validate false bypass registry check

fangs pending

fangs pending [flags]

Runs awaiting an operator decision (≥1 deviation, not yet promoted). Sorted by max severity desc, then last-detected desc.

Flag Purpose
-package P filter to one package
-min-severity S filter by run max-severity threshold
-limit N cap rows

Output includes the literal fangs baseline promote … command for each row — paste-friendly.

$ fangs pending
SEVERITY  RUN          PACKAGE  VERSION  FINDINGS  DETECTED  PROMOTE
critical  18b2089cca…  axios    1.7.8    2         5m ago    fangs baseline promote 18b2089cca…
medium    18b209af00…  lodash   4.18.2   1         12m ago   fangs baseline promote 18b209af00…

2 runs awaiting review.

Storage backend selection

The CLI talks directly to the storage backend the orchestrator uses (not the HTTP API), except for scan submit and the kickoff inside package add which POST /v1/scans.

If your orchestrator runs against Postgres, the CLI needs the same DSN:

# Same shell where the orchestrator runs:
export FANGS_PG_DSN="postgres://fangs:secret@db.internal/fangs?sslmode=verify-full"

fangs -storage postgres run list
# or just:
fangs -storage postgres pending

A future improvement is a "CLI-via-HTTP" mode where every subcommand goes through the orchestrator's HTTP surface. For now most subcommands require direct DB access — which means CLI + orchestrator on the same host or same DB cluster.

Exit codes

Code Meaning
0 success
1 error (printed to stderr with fangs: prefix)
2 flag parse error (from stdlib flag package)

The CLI doesn't distinguish "not found" from "validation error" via exit code — the message in stderr is the canonical signal.

Clone this wiki locally