What this is for
This page explains what gw-cli discover finds on a machine and how each artifact is scored. The inventory is broad — the whole agent extension surface, not just skills — and the scoring is layered: a primary engine, plus offline augmentation passes designed to catch the evasion techniques that beat file-only scanners.
The inventory surface
discover --deep walks the machine and records every AI artifact it finds:
| Category | What it covers |
|---|
| AI tools / apps | Desktop apps, CLIs, and editor extensions — Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI, GitHub Copilot, Cline, Continue, Goose, Amazon Q, and many more. |
| Accounts | For each tool, whether the signed-in account is corporate or personal, inferred from the email domain. |
| Agent projects | Folders that carry agent configuration — skills, MCP configs, and add-ons. |
| Skills | SKILL.md skills, scored individually and grouped by project. |
| MCP servers | Registered MCP server configs. |
| Commands | Slash/command definitions. |
| Hooks | Lifecycle hooks that run shell on agent events. |
| Subagents | Delegated agents and the tools they’re granted. |
| Plugins | Packaged extensions. |
Risk levels
Every scored artifact is normalized to one of five levels, ordered lowest to highest:
| Level | Meaning |
|---|
| None | No risky patterns detected. |
| Low | Only minor findings. |
| Medium | Some risky patterns worth a review. |
| High | High-risk behavior — flagged. |
| Critical | Secret-exfiltration, destructive, or injection patterns — flagged. |
High and Critical are the flagged levels — the ones the dashboard badges and vet blocks on by default.
Scoring engines
gw-cli scores with one of two engines. It auto-detects which is available and prints the active engine in its output.
NVIDIA SkillSpector — a thorough analysis engine. When present on the machine, gw-cli uses it automatically. Install it once:curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install --python 3.12 git+https://github.com/NVIDIA/skillspector.git
gw-cli discover --deep # now scores with engine = SkillSpector
A thorough engine can emit hundreds of findings per artifact — use gw-cli vet ... --summary for a per-category digest instead of the full per-line dump. A built-in heuristic rule engine that runs with zero network and no dependencies. It deliberately over-flags — it favors false positives over misses — so it’s a safe default but noisier than SkillSpector. This is what --air-gap forces.
MCP configs are always scored by a config-aware analyzer (reliable on JSON) rather than the skill engine — it flags hardcoded secrets in env, non-TLS http:// endpoints, and shell-launch commands. Hooks and commands are scored with shell + network heuristics; subagents are flagged for overly broad tool grants.
Offline augmentation
On top of the primary engine, every scan record runs through offline augmentation passes. These counter the techniques research has shown beating file-only scanners (including SkillSpector), and they need no network:
| Code | What it catches |
|---|
IOC-KNOWN | Exact match of a disclosed campaign indicator → escalated to Critical. |
PADDING | An oversized instruction file with a low-entropy tail — a size-cap evasion trick. |
HIDDEN-UNICODE | Strips zero-width, Tag, and bidirectional codepoints, then re-scans the de-obfuscated text. |
So a hardcoded token in an MCP config, a curl … | bash hidden with invisible characters, or a known malicious indicator all surface as findings — even against an artifact crafted to slip past a plain file scan.
External-reference index
Beyond flagging suspicious links, the scanner builds a typed, persisted index of every external resource an artifact points the agent at — the durable graph the drift watcher diffs and a future network trust-scorer will enrich. Each reference records its kind (URL, repository, npm/PyPI package, release download, remote skill/instructions, paste host, wallet address), a coarse host class (vendor, code host, registry, paste, free-tier/throwaway, IP), its version spec, and whether it is pinned to an exact version/tag/commit. Only the host/package identity and version metadata are stored — never a raw URL that might carry a token.
The offline external-reference classifier turns high-signal references into findings:
| Code | What it catches |
|---|
EXT-REMOTE-SKILL | Fetches a remote SKILL.md / instructions file the agent will follow. |
EXT-PASTE | References a paste/snippet host (rentry, pastebin, glot, …). |
EXT-RELEASE | Downloads a release/binary artifact. |
EXT-LOOKALIKE | A brand-lookalike domain (edit-distance 1 from a known vendor). |
EXT-TYPOSQUAT | An npm/PyPI package that typosquats a popular one. |
Post-approval drift
An artifact that scored clean can be edited — or silently auto-updated — into something malicious after you first trusted it (a rug-pull / TOCTOU). On every scan the mutation watcher diffs the fresh record against the last-stored (approved) baseline for that path and raises drift findings:
| Code | What it catches |
|---|
DRIFT-NEW-REF | The artifact added an external reference it did not have before — a new host, package, paste, remote skill, or wallet. A new paste/remote-skill/wallet reference is High. |
DRIFT-LOST-PIN | A reference that used to be pinned to an exact version dropped its pin and now floats — the classic “install pkg@1.2.3, later float to a malicious release.” High. |
DRIFT-ESCALATION | The artifact’s overall risk rose since the baseline. |
This is the on-endpoint-detectable half of the flagship supply-chain attack (CVE-2025-54136). discover prints a one-line summary (Post-approval drift: N change(s)…) when anything drifted.
Install-lifecycle & CI-workflow analysis
The highest-severity confirmed payloads often hide in install plumbing rather than the skill body. A dedicated pass inspects each artifact’s files:
| Code | What it catches |
|---|
LIFECYCLE-FETCH-EXEC | Remote content piped into an interpreter (curl … | bash, bash -c "$(curl …)", iwr … | iex) in a script or “prerequisite” block. High. |
CI-FETCH-EXEC | The same fetch-exec inside a GitHub Actions workflow or action.yml. Critical. |
NPM-LIFECYCLE-FETCH | A preinstall / install / postinstall script in package.json that fetches remote content on install. Critical. |
CI-UNTRUSTED-CHECKOUT | A pull_request_target workflow that checks out untrusted PR code. High. |
CI-INJECTION | Untrusted ${{ github.event.* }} data interpolated into a run: shell step. High. |
INSECURE-DESERIALIZE | pickle.loads / marshal.loads / yaml.load without a safe loader. Medium. |
Metadata, posture & MCP scope
Three more offline passes catch risks that live in the declaration and environment around a skill rather than its code:
| Code | What it catches |
|---|
META-MISSING | A SKILL.md with no frontmatter, or missing the name / description identity fields the platform expects — the signature of a skill ported from another format with its metadata stripped. |
META-MISMATCH | The declared tool list omits shell execution, but the body runs shell — the manifest understates what the skill does. |
META-UNDECLARED-NET | The description discloses no network use, but the body runs egress commands (curl, wget, iwr, raw sockets). |
POSTURE-BYPASS | An agent settings file disables permission prompts (bypassPermissions) — every skill runs unattended. |
POSTURE-ALLOW-ALL | A wildcard shell allowlist (Bash(*), *) pre-approves arbitrary commands. |
POSTURE-HOOK | An auto-run lifecycle hook pipes a download into a shell, evals, elevates, or deletes recursively. |
MCP-EXFIL | A filesystem MCP server granted a root of /, ~, or a whole home directory — broad read paired with the agent’s network reach is the minimum exfiltration kit. |
OWASP Agentic Skills Top 10
Every rule Guardway raises is tagged with the OWASP Agentic Skills Top 10 item it detects (AST01–AST10), and the CLI + dashboards compute a compliance level per machine from those findings. Guardway has detection-side coverage of all ten items — it detects and reports; it never blocks or sandboxes.
| Item | What it covers | Example rules |
|---|
| AST01 Malicious Skills | credential stealers, reverse shells, injection | NET1, E1, COMBO, PI1, SH1, IOC-KNOWN |
| AST02 Supply Chain | typosquats, look-alikes, unsigned releases | EXT-TYPOSQUAT, EXT-LOOKALIKE, RP*, CI-* |
| AST03 Over-Privilege | over-broad skill / MCP scope | MCP1, MCP-EXFIL, CRED, LP* |
| AST04 Insecure Metadata | understated / mismatched manifests | META-MISMATCH, META-UNDECLARED-NET |
| AST05 External Instructions | mutable remote content the skill follows | EXT-REMOTE-SKILL, EXT-PASTE |
| AST06 Weak Isolation | no sandbox / bypassed prompts | POSTURE-BYPASS, POSTURE-ALLOW-ALL, MCP-SHELL |
| AST07 Update Drift | silent post-approval mutation | DRIFT-NEW-REF, DRIFT-LOST-PIN, DRIFT-ESCALATION |
| AST08 Scanner Evasion | padding, hidden unicode, obfuscation | PADDING, HIDDEN-UNICODE, OB1 |
| AST09 Governance | no inventory / approval / audit | GOV-UNAPPROVED (see below) |
| AST10 Cross-Platform Reuse | ported skill missing its metadata | META-MISSING |
Compliance scoring
Each item is scored from the findings present on the machine:
| Status | Meaning |
|---|
| PASS | no finding maps to this item |
| ATTENTION | only minor findings map (severity < 25) |
| FAIL | at least one serious finding maps (severity ≥ 25) |
A machine’s compliance % = (PASS = 1 · ATTENTION = 0.5 · FAIL = 0) across the ten items ÷ 10. gw-cli scan prints each finding’s AST tag (e.g. META-UNDECLARED-NET … (AST04)); the local dashboard shows an OWASP panel; the Guardway console rolls it up across the fleet.
AST vs ASI — two different OWASP frameworks. The endpoint side (this CLI) maps to the Agentic Skills Top 10 (AST) — threats in installed skills at rest. The platform Agents page maps to the Agentic Security Initiative (ASI) — threats in a running agent. They are complementary, not the same list: AST07 Update Drift and AST09 Governance have no runtime equivalent; ASI06 Memory Poisoning and ASI10 Rogue Agents have no static-skill equivalent. AST is the risk at rest (the leading indicator); ASI is the live exploitation — e.g. an over-privileged skill (AST03) is what a running agent later abuses (ASI03).
Governance (AST09)
Inventory only governs if new arrivals are surfaced. Run gw-cli approve after reviewing a discover run to record the current skills, commands, subagents, and MCP configs as the approved baseline (path + content hash → <data-dir>/approved.json). From then on discover flags anything new or changed outside that baseline:
| Code | What it catches |
|---|
GOV-UNAPPROVED | An artifact that appeared or changed outside the approval flow — even if its content scans clean, because nobody approved it. |
Governance is opt-in and local — no baseline file, no findings. Until you run approve, AST09 reads as ATTENTION (“no approval baseline”); a baseline with no violations makes it PASS.
Vet verdicts
gw-cli vet collapses an artifact’s overall risk into a single headline verdict word plus one-line advice. The mapping:
| Overall risk | Verdict | Advice |
|---|
| Critical / High | DO NOT INSTALL | High-risk behavior found. Do not install without a careful manual review. |
| Medium | REVIEW FIRST | Some risky patterns found. Review the flagged artifacts before installing. |
| Low | LIKELY OK | Only minor findings. Skim the flagged lines, then it’s likely safe. |
| None | CLEAN | No risky patterns detected. Still review the code before granting access. |
The process exits non-zero at or above --fail-on (default high), so you can gate an install:
gw-cli vet owner/repo && echo "clone + install…" # only proceeds if the vet passed
Limits
- The built-in engine over-flags by design; install SkillSpector for production-grade scoring.
- Detection is static — it inspects files, it does not execute them. Drift detection catches the local mutation of an approved artifact (the on-endpoint half of a TOCTOU/rug-pull); confirming that a remote URL’s served content has flipped, or judging live runtime intent, requires the network and is out of scope for on-endpoint static analysis.
- Drift needs a baseline: the first scan of an artifact establishes it, so drift findings appear from the second scan onward. Keep the inventory fresh (see
schedule) so the baseline stays current.
- On Windows, some app-config paths (e.g. the Claude desktop app under
%APPDATA%) are still being added; Claude Code and project-folder artifacts are covered today.