npm.io
1.0.0 • Published 3d agoCLI

vc-expiry-watch

Licence
MIT
Version
1.0.0
Deps
0
Size
28 kB
Vulns
0
Weekly
0

vc-expiry-watch

Monitor issued Verifiable Credentials for expiry, structural drift, and revocation, entirely offline. CI

Verifiable Credentials rarely carry a live pipeline that watches them after issuance. Wallets, verifiers, and back-office systems accumulate JSON-LD and JWT-VC credentials whose expirationDate quietly slips into the past, or whose issuer revokes them via a status list nobody is polling. vc-expiry-watch is a small, offline-first CLI and library that ingests local Verifiable Credential files and reports:

  • Expiry status — expired, expiring soon (configurable window), or valid
  • Structural validity — required VC fields present and well-formed
  • Revocation status — checked against a locally-provided revocation or status-list fixture (no live network calls required)

Usage

vc-expiry-watch <path> [options]
node bin/vc-expiry-watch.js examples/credentials --recursive --revocation-list examples/demo-revocation-list.json

vc-expiry-watch scanning a directory of demo credentials and printing a table report with valid, upcoming, expired, and revoked statuses

Structural validation

Every credential is checked for the required Verifiable Credential fields: @context, type, issuer, credentialSubject, and issuanceDate. Missing fields are reported as structural errors, independent of expiry status.

Revocation checks

Revocation is checked against a locally-provided fixture in one of two formats:

  • Simple list{ "revoked": ["<credential id>", ...] }
  • StatusList2021 — a StatusList2021Credential with a base64-encoded encodedList bitstring, referenced by a credential's credentialStatus.statusListIndex

No live network calls are made when checking revocation; the list is always read from a local file via --revocation-list <path>.

JWT-VC support

In addition to JSON-LD credentials, .jwt files containing a JWT-VC (a signed JWT whose payload has a vc claim, or an unwrapped VC-shaped payload) are auto-detected and decoded. No signature verification is performed — this tool only inspects structure, expiry (expirationDate or numeric exp), and revocation status, all against local data.

Exit codes for CI

vc-expiry-watch exits 0 when every scanned credential is valid (or merely upcoming), and exits 1 if any credential is expired, revoked, or structurally invalid — making it easy to wire into a CI pipeline as a credential-health gate.

Fetching a remote status list (optional, untested live)

src/lib/fetchStatusList.js is a thin wrapper around the global fetch API for pulling a real StatusList2021Credential from a live HTTPS endpoint. It is deliberately not covered by the automated test suite or CI, since those only ever touch local fixture files. Wire its result into checkRevocation yourself if you need live status-list checks.

Config file

Place a .vcexpiryrc.json in your working directory to set defaults:

{
  "days": 45,
  "revocationList": "./revocation-list.json",
  "format": "json",
  "recursive": true
}

Any CLI flag you pass explicitly overrides the matching config value.

Troubleshooting

  • "Cannot read file" — the path passed doesn't exist or isn't readable.
  • "Malformed JSON" — the .json credential file isn't valid JSON.
  • "Malformed JWT" — the .jwt file isn't a well-formed 3-part JWT.
  • "Unrecognized revocation list format" — the file passed to --revocation-list is neither a { "revoked": [...] } list nor a StatusList2021Credential with an encodedList.

Output formats

--format table (default), --format json, and --format csv are all supported, and can be combined with --output <file> to write the report to disk instead of stdout.

Examples
vc-expiry-watch ./credentials --recursive --format json
vc-expiry-watch ./credentials --recursive --format csv --output report.csv
vc-expiry-watch ./credentials --revocation-list ./revocation-list.json

Issuer validation

issuer is accepted either as a DID string (any did:<method>:...), an HTTPS URL, or an object with an id in one of those forms. Anything else is reported as a structural error.

CLI reference

Flag Description
--days <n> Days threshold for "upcoming" expiry (default 30)
--revocation-list <path> Local revocation/status list fixture
--recursive Scan directories recursively
--format <table|json|csv> Output format (default table)
--output <file> Write report to a file instead of stdout
--verbose Print extra diagnostic info
--help Show usage
--version Show version
Revocation list format comparison
Format Shape Lookup key
simple { "revoked": ["<id>", ...] } credential id
statuslist2021 StatusList2021Credential with encodedList credentialStatus.statusListIndex

The format is auto-detected from the file passed to --revocation-list; no separate flag is needed.

Status priority

When a credential trips more than one check at once, the report shows a single, prioritized status: revoked > invalid (structural) > expired > upcoming > no-expiry > valid. A revoked credential is always reported as revoked, even if it has also expired.

FAQ

Does this verify cryptographic signatures? No. It only checks expiry, structure, and revocation against local data. Pair it with a real VC verification library for signature checks.

Does it call any live network endpoints during tests? No. All tests run against local fixture files. fetchStatusList.js is the one optional exception, and it is never exercised by the test suite.

What happens if I point it at a directory with no .json/.jwt files? The CLI exits with an error and a non-zero status code.

Architecture

bin/vc-expiry-watch.js   -> thin executable, delegates to src/cli.js
src/cli.js               -> argument parsing, option resolution, output
src/index.js             -> programmatic library API
src/lib/parse.js         -> JSON-LD / JWT-VC loading and format detection
src/lib/structure.js     -> required-field + issuer + type validation
src/lib/expiry.js        -> expirationDate / exp-claim status logic
src/lib/revocation.js    -> simple-list / StatusList2021 revocation checks
src/lib/scan.js          -> file/directory resolution
src/lib/report.js        -> combines the above into one prioritized status
src/lib/formatters/*     -> table / json / csv rendering

Acknowledgments

Built against the W3C Verifiable Credentials Data Model, the W3C DID Core specification, and the StatusList2021 revocation mechanism. This project is an independent utility and is not affiliated with the W3C.

Tags

verifiable-credentials did digital-identity w3c cli

License

MIT — see LICENSE.

Keywords