v11y-check
v0.18.1
Published
Wrap audit-ci with a richer config model, typed JSON source of truth, and sync workflow
Downloads
2,076
Maintainers
Readme
v11y-check
Wraps audit-ci with a richer config model, typed JSON source of truth, and a sync workflow that automates allowlist management.
Installation
Requires Node.js 24 or later.
pnpm add -D v11y-checkThe package is v11y-check; the bin is v11y. The package also ships v11y-check as a bin alias, so pnpm exec v11y-check and npx v11y-check continue to work.
Quick start
# Run a vulnerability check with sensible defaults (no config needed)
npx v11y-check check
# Scaffold a starter config and GitHub Actions workflow
npx v11y-check init
# Sync allowlists with current findings
npx v11y-check sync
# Raw audit-ci passthrough
npx v11y-check --rawNo config file is required. When .config/v11y-check.config.json is absent, the tool uses built-in defaults: severityThreshold: 'moderate' for dev, severityThreshold: 'low' for prod, and empty allowlists.
Configuration
The source-of-truth config lives at .config/v11y-check.config.json:
{
"$schema": "https://github.com/williamthorsen/node-monorepo-tools/raw/v11y-check-v<version>/packages/v11y-check/schemas/config.json",
"dev": {
"severityThreshold": "moderate",
"allowlist": [
{
"addedAt": "2026-04-15T09:30:00.000Z",
"id": "GHSA-1234-5678-abcd",
"path": "lodash",
"reason": "Accepted risk: no user input reaches this path",
"url": "https://github.com/advisories/GHSA-1234-5678-abcd"
}
]
},
"prod": {
"severityThreshold": "low",
"allowlist": []
}
}Fields
$schema(optional) — JSON Schema URL for editor autocomplete and validation. Automatically included byinitandsync.dev/prod— Scope-specific settings:severityThreshold(optional) — Fail on advisories at or above this severity. Valid values:'low','moderate','high','critical'. When omitted, audit-ci uses its own defaults.allowlist— Typed advisory entries withid,path,url, and optionalreasonandaddedAt.addedAtis an ISO 8601 UTC datetime (e.g.,2026-04-15T09:30:00.000Z) populated automatically byv11y syncon new entries; existing entries retain whatever value they had. OlderYYYY-MM-DDvalues are still accepted.
Output style
The V11Y_CHECK_OUTPUT_STYLE environment variable sets the style for every command, init included: rich marks each finding with an emoji, such as ❌ or ✅, and plain prints a word in its place, such as FAIL or PASS, which a reader of a log can search for. auto, the default, defers to detection. Any other value is a usage error that exits with code 1.
Detection decides stdout and stderr separately. A stream is plain when CI is set to anything other than an empty string or false, when the stream is not a terminal, or when TERM is linux; otherwise it is rich. --json output contains no emoji in either style.
CLI reference
Usage: v11y [options]
v11y <command> [options]
Commands:
check (default) Grouped vulnerability check with severity indicators
sync Synchronize allowlists with current audit findings
init Scaffold a starter config file and GitHub Actions workflow
Scope options:
--dev Target dev dependencies only
--prod Target production dependencies only
Other options:
--config <path> Path to config file (default: .config/v11y-check.config.json)
--json Output results as JSON
--raw Run raw audit-ci passthrough
--verbose, -v Show detailed per-vulnerability output
--help, -h Show this help message
--version, -V Show version number
Environment:
V11Y_CHECK_OUTPUT_STYLE
Output style: auto (default), plain, or rich. auto prints plain,
without emoji, when CI is set or the stream is not a terminal.Init options
--dry-run, -n Preview changes without writing files
--force, -f Overwrite an existing workflow (an existing config is never overwritten)JSON output shape
--json emits one object per requested scope plus a top-level summary block:
{
"prod": { "allowed": [...], "belowThreshold": [...], "stale": [...], "unallowed": [...] },
"dev": { "allowed": [...], "belowThreshold": [...], "stale": [...], "unallowed": [...] },
"summary": { "status": "vulnerabilities-found", "count": 3 }
}summary.status is the highest-severity finding category present across the requested scopes. Below-threshold findings never affect it.
| status | When |
| ---------------------------- | ------------------------------------------------- |
| vulnerabilities-found | At least one unallowed advisory |
| suppressed-vulnerabilities | No unallowed; at least one allowlisted advisory |
| stale-overrides | No advisories; at least one stale allowlist entry |
| none | No findings |
summary.count is the total across the requested scopes for the active category. It is 0 when status is none.
Scaffolded GitHub Actions workflow
v11y init scaffolds .github/workflows/audit.yaml alongside the config file. The workflow is a thin caller that delegates to the versioned reusable workflow published at williamthorsen/node-monorepo-tools/.github/workflows/audit.reusable.yaml@workflow/audit-v1, so your repository tracks the reusable workflow at a stable version tag.
The scaffolded workflow triggers on pull requests to main/next, on a daily schedule, and on manual workflow_dispatch. Commit the file into your repository so the caller runs in CI. If the reusable workflow's caller-side requirements change (for example, the tag bumps), re-run v11y init --force to refresh the file.
The reusable workflow installs pnpm with pnpm/setup, which installs pnpm 11 or newer only and reads the version from your devEngines.packageManager or packageManager field. A repository pinned below that cannot run it.
Readiness checks
v11y-check publishes a readyup kit that checks a consuming repo against the release it has installed: that v11y-check is a devDependency at or above the current version, that audit-ci configs sit under .config/audit-ci/, and that .github/workflows/audit.yaml matches the template this package scaffolds. The kit ships inside the package, so it checks against the version you installed rather than whatever a repository ref happens to point at.
Add readyup as a devDependency, then name v11y-check in its config:
// .config/readyup.config.ts
import { defineRdyConfig } from 'readyup';
export default defineRdyConfig({
packages: ['v11y-check'],
});rdy run --packages # every kit each listed package publishes
rdy run --from npm:v11y-check # v11y-check's kit alone, without the config entry
rdy list --from npm:v11y-check # what v11y-check publishes--packages is the form that survives v11y-check publishing further kits. Every form needs readyup 0.23 or later, and v11y-check as a direct devDependency: a strict pnpm layout links nothing else into the project, so a transitive copy is unreachable.
The kit is no longer reachable through rdy run --from github:williamthorsen/node-monorepo-tools. Repos still using that form should switch to one of the invocations above.
Migration from v0.3
v0.4 introduces breaking changes to the config schema:
outDirremoved. Intermediate audit-ci files are now written to a temp directory and cleaned up automatically. RemoveoutDirfrom your config.- Severity booleans replaced by
severityThreshold. Replace"moderate": truewith"severityThreshold": "moderate","high": truewith"severityThreshold": "high", etc. Only one threshold per scope is supported. generatesubcommand removed. Thev11y generatecommand no longer exists. Flat audit-ci configs are now managed internally.- Config is optional. All commands now work without a config file, using built-in defaults.
To migrate an existing config:
- Remove the
outDirfield. - Replace severity booleans with
severityThresholdin each scope. - Optionally add a
$schemafield set tohttps://github.com/williamthorsen/node-monorepo-tools/raw/v11y-check-v<version>/packages/v11y-check/schemas/config.json, with<version>replaced by the installed v11y-check version. - Delete any generated
audit-ci.*.jsonfiles that were in your config directory.
