@ppoll/npm-audit
v2.1.0
Published
Run npm or pnpm audit and fail on high/critical vulnerabilities unless explicitly accepted
Maintainers
Readme
@ppoll/npm-audit
A zero-dependency CLI tool that runs npm audit or pnpm audit and fails if there are any high or critical vulnerabilities, unless they are explicitly accepted in a configuration file. Designed for CI/CD pipelines to enforce security policies while allowing teams to acknowledge and track accepted risks.
Features
- Zero dependencies - Only uses Node.js built-in modules
- npm and pnpm support - Auto-detects the package manager from your lockfile, or force one with
--package-manager - Supply chain protection - Run before installing dependencies to audit your lock file before any potentially compromised packages are installed
- Configurable severity levels - Fail on high/critical (default) or adjust to your needs
- Accept known vulnerabilities - Document accepted risks with reasons, ownership, and expiration dates
- CI/CD ready - Works with GitHub Actions, Azure DevOps, and any CI system
Usage
The recommended way to use this tool is with npx, which downloads and runs it directly without installing:
npx @ppoll/npm-audit@latestThis will:
- Run
npm auditorpnpm auditto check for vulnerabilities - If high or critical vulnerabilities are found, check against your accepted vulnerabilities config
- Exit with code 0 if no issues or all issues are accepted
- Exit with code 1 if there are unaccepted high/critical vulnerabilities
Options
npx @ppoll/npm-audit@latest [options]
Options:
--config, -c Path to config file (default: .npm-audit-accept.json)
--level, -l Minimum severity level to fail on (default: high)
Options: low, moderate, high, critical
--package-manager, -p Package manager to audit with (default: auto-detected from lockfile)
Options: npm, pnpm
--help, -h Show help
--version, -v Show versionPackage Manager Detection
By default, the package manager is auto-detected from the lockfile present in the current directory:
pnpm-lock.yaml→ runspnpm auditpackage-lock.json→ runsnpm audit
If neither lockfile is found, or both are found (e.g. mid-migration between package managers), the tool exits with an error asking you to disambiguate with --package-manager/-p. The corresponding package manager (npm or pnpm) must be available on PATH.
Configuration
Create a .npm-audit-accept.json file in your project root to accept known vulnerabilities:
{
"acceptedVulnerabilities": [
{
"url": "https://github.com/advisories/GHSA-xxxx-xxxx-xxxx",
"reason": "No fix available, mitigated by input validation",
"acceptedBy": "[email protected]",
"acceptedAt": "2026-02-09T00:00:00.000Z",
"expiresAt": "2026-08-09T00:00:00.000Z"
}
]
}Configuration Fields
| Field | Required | Description |
| ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| url | Yes | The GitHub advisory URL (e.g., https://github.com/advisories/GHSA-xxxx-xxxx-xxxx). Stable across npm audit runs, unlike vulnerability IDs. |
| id | No | The vulnerability ID from npm audit. Deprecated (kept for reference, but not used for matching) |
| reason | Yes | Why this vulnerability is being accepted |
| acceptedBy | Yes | Who accepted this vulnerability |
| acceptedAt | Yes | When this vulnerability was accepted (ISO 8601) |
| expiresAt | No | When this acceptance expires (ISO 8601). If expired, the vulnerability will cause a failure again. |
Migrating from v1 to v2
v2.0.0 introduces a breaking change: matching is now based on advisory URLs instead of vulnerability IDs.
Why? npm audit's vulnerability IDs change between runs (same advisory different ID). Advisory URLs (GHSA-*) are stable.
Migration steps:
- Run
npx @ppoll/npm-audit@latestwith your old config - Copy the advisory URLs from the suggestion output
- Update
.npm-audit-accept.jsonto useurlas the key instead ofid
Example:
{
"acceptedVulnerabilities": [
{
"url": "https://github.com/advisories/GHSA-7r86-cg39-jmmj",
"reason": "Investigating fix availability",
"acceptedBy": "[email protected]",
"acceptedAt": "2026-03-19T00:00:00.000Z",
"expiresAt": "2026-04-19T00:00:00.000Z"
}
]
}The id field is now optional and preserved for reference, but is no longer used for matching.
CI/CD Integration
The key benefit of this tool is that npx can download and run it directly from npm before installing your project dependencies. This protects against supply chain attacks by auditing the lock file before any potentially compromised packages are installed. The examples below use npm, but the same npx @ppoll/npm-audit@latest step works unchanged in a pnpm project (with pnpm-lock.yaml present and pnpm on PATH) — the package manager is auto-detected.
GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Security audit (before install)
run: npx @ppoll/npm-audit@latest
- name: Install dependencies
run: npm ciAzure DevOps Pipelines
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
displayName: 'Install Node.js'
- script: npx @ppoll/npm-audit@latest
displayName: 'Security audit (before install)'
- script: npm ci
displayName: 'Install dependencies'With Custom Configuration
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
displayName: 'Install Node.js'
- script: npx @ppoll/npm-audit --config security/audit-exceptions.json --level critical
displayName: 'Security audit (critical only)'
- script: npm ci
displayName: 'Install dependencies'As a Separate Stage
stages:
- stage: Security
displayName: 'Security Checks'
jobs:
- job: Audit
displayName: 'NPM Audit'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
- script: npx @ppoll/npm-audit@latest
displayName: 'Run security audit'
continueOnError: false
- script: npm ci
displayName: 'Install dependencies'Example Output
When vulnerabilities are found:
🔍 Running npm audit...
⚠️ Found vulnerabilities at high level or above.
📋 Loading accepted vulnerabilities from .npm-audit-accept.json...
❌ Found 2 unaccepted vulnerabilities:
HIGH: fast-xml-parser - fast-xml-parser has RangeError DoS Numeric Entities Bug
ID: 1112708
URL: https://github.com/advisories/GHSA-37qj-frw5-hhjh
HIGH: next - Next.js self-hosted applications vulnerable to DoS
ID: 1112593
URL: https://github.com/advisories/GHSA-9g9p-9gw9-jx7f
To accept these vulnerabilities, add them to .npm-audit-accept.json:
{
"acceptedVulnerabilities": [
{
"id": 1112708,
"reason": "TODO: Add reason for accepting",
"acceptedBy": "[email protected]",
"acceptedAt": "2026-02-09T09:21:06.871Z"
},
...
]
}When all vulnerabilities are accepted:
🔍 Running npm audit...
⚠️ Found vulnerabilities at high level or above.
📋 Loading accepted vulnerabilities from .npm-audit-accept.json...
✅ All vulnerabilities are accepted in configuration.License
MIT
