---
name: dependency-cve-audit
description: Audit locked npm dependencies against OSV advisories and emit exact-version CVE evidence.
source:
  type: cli-tool
  command: node
  args:
    - run.mjs
runx:
  tags:
    - security
    - dependencies
    - osv
links:
  source: https://github.com/RYDE-PLAY/runx-dependency-cve-audit-skill
  advisory_source: https://osv.dev
---

## What this skill does

This skill audits a Node.js project's committed `package-lock.json` for known
vulnerabilities in npm dependencies. It extracts exact installed package
versions, queries the OSV API for each exact `{ ecosystem, package, version }`
tuple, and emits a machine-checkable evidence packet plus a concise Markdown
report.

The skill is read-only. It does not install dependencies, execute target code,
modify repositories, open issues, submit advisories, or claim that a package is
safe when OSV returns no matching record. A zero-finding result means only that
OSV did not return advisories for the exact versions scanned under the selected
scope.

## When to use this skill

Use this skill when an agent needs a reproducible dependency vulnerability
snapshot for a public Node.js project, release candidate, benchmark fixture, or
security review packet. It is appropriate when the lockfile is public or has
been explicitly cleared for disclosure to OSV, and when the review needs exact
installed-version evidence rather than semver range guesses.

The skill is especially useful before triage, upgrade planning, advisory
drafting, or reviewer handoff because it preserves the lockfile SHA-256, the
scan policy, the OSV query tuple for every finding, and references for each
advisory.

## When not to use this skill

Do not use this skill for private lockfiles unless the package names, versions,
and lockfile URL/path are approved for disclosure to the advisory source. Do not
use it as a full application security review, source-code audit, exploitability
assessment, SBOM generator, package installer, or automated remediation tool.

Do not use the output as proof that a project is vulnerability-free. The result
depends on OSV coverage at run time, the selected dependency scope, and the
contents of the supplied lockfile.

## Procedure

1. Read `package_lock_path` or `package_lock_url`.
2. Record byte length and SHA-256 for the lockfile input.
3. Extract exact installed package versions from the lockfile.
4. Limit the scan to the declared `scan_scope` and `include_dev` policy.
5. Query OSV only with exact npm package names and exact installed versions.
6. Keep only vulnerabilities returned by OSV for that exact version query.
7. Emit `dependency.cve.audit.result.v1` with findings, query evidence, and validation.
8. Write `evidence.json` and `report.md` when `output_dir` is provided.

## Edge cases and stop conditions

Return `needs_input` when neither `package_lock_path` nor `package_lock_url` is
provided. Return `needs_more_evidence` when the target repository or immutable
reference is missing and the audit is intended for publication. Return
`refused` when the caller asks the skill to install packages, execute target
code, read private repository contents without an explicit grant, publish an
advisory, or mutate the target repository.

Stop with an error when the lockfile cannot be read, when the URL is not HTTPS,
when the lockfile is not valid JSON, or when it does not contain a `packages`
object.

For local paths and output paths, the resolved path must stay inside the skill
directory. This prevents the runner from reading or writing unrelated workspace
files.

If an OSV request fails, stop instead of returning a partial success packet. If
`scan_scope` is `direct`, skip direct dependencies whose installed package entry
is missing from `packages`; do not invent versions from semver declarations.

The output is evidence for dependency triage, not an authorization to publish a
security advisory or mutate a repository. Any later issue filing, advisory
publication, or remediation PR needs its own authority gate and receipt.

## Output schema

The primary output is `dependency_cve_audit_result`, with schema
`dependency.cve.audit.result.v1`:

```json
{
  "schema": "dependency.cve.audit.result.v1",
  "data": {
    "target": {
      "name": "string | null",
      "repo": "string | null",
      "ref": "string | null"
    },
    "source": {
      "kind": "file | url",
      "ref": "string",
      "bytes": 0,
      "sha256": "hex"
    },
    "scanner": {
      "name": "dependency-cve-audit",
      "version": "0.1.1",
      "advisory_source": "OSV.dev v1 query API",
      "advisory_endpoint": "https://api.osv.dev/v1/query"
    },
    "policy": {
      "ecosystem": "npm",
      "scan_scope": "direct | all",
      "include_dev": false,
      "target_code_executed": false,
      "target_packages_installed": false,
      "finding_rule": "string"
    },
    "summary": {
      "dependencies_scanned": 0,
      "packages_with_findings": 0,
      "findings": 0
    },
    "dependencies": [],
    "findings": [],
    "validation": {
      "valid": true,
      "every_finding_has_exact_version": true,
      "every_finding_has_reference": true,
      "every_finding_has_advisory_id": true,
      "zero_false_hit_control": "string"
    }
  }
}
```

When `output_dir` is provided, the runner also writes `evidence.json` and
`report.md` inside that directory and returns their relative paths in
`data.artifacts`.

## Worked example

The harness scans OWASP NodeGoat at commit
`c5cb68a7084e4ae7dcc60e6a98768720a81841e8` using the committed
`package-lock.json`:

```bash
runx skill "$PWD" \
  --input target_name="OWASP NodeGoat" \
  --input target_repo=https://github.com/OWASP/NodeGoat \
  --input target_ref=c5cb68a7084e4ae7dcc60e6a98768720a81841e8 \
  --input package_lock_url=https://raw.githubusercontent.com/OWASP/NodeGoat/c5cb68a7084e4ae7dcc60e6a98768720a81841e8/package-lock.json \
  --input scan_scope=direct \
  --input include_dev=false \
  --input output_dir=artifacts/nodegoat \
  --json
```

Expected evidence shape:

- `source.sha256` records the fetched lockfile hash.
- `summary.dependencies_scanned` is the number of direct production npm
  dependencies found in the lockfile.
- Each finding contains the exact installed version, OSV advisory id, aliases,
  fixed versions when listed, affected ranges, and references.
- `validation.valid` is true only when every finding includes an exact version,
  advisory id, and at least one reference.

## Inputs

- `target_name`: human-readable project name.
- `target_repo`: source repository URL.
- `target_ref`: immutable commit or release reference.
- `package_lock_path`: local path to a `package-lock.json`.
- `package_lock_url`: public URL for a `package-lock.json`.
- `scan_scope`: `direct` or `all`; defaults to `direct`.
- `include_dev`: include dev dependencies when true; defaults to false.
- `output_dir`: optional directory for `evidence.json` and `report.md`.

## Outputs

- `dependency_cve_audit_result`: complete packet.
- `evidence_json`: same evidence as machine-checkable JSON.
- `report_md`: concise report with exact version findings and references.
