npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jwt-flight-recorder

v0.2.0

Published

JWT observability and security monitoring toolkit with safe-by-default telemetry, metrics, and alerting.

Downloads

281

Readme

jwt-flight-recorder

JWT observability and security monitoring toolkit for Node.js.

Product vision:

Know exactly why JWT auth is failing, when tokens are misused, and where security issues are happening without leaking secrets.

Product strategy summary

jwt-flight-recorder focuses on one domain only: JWT lifecycle observability.

  1. Capture decode, verify, and issue events.
  2. Redact sensitive fields by default.
  3. Turn events into telemetry (OpenTelemetry spans/events/attributes).
  4. Expose operational metrics for SRE/security workflows.
  5. Trigger rule-based alerts for suspicious auth behavior.
  6. Integrate with existing Node frameworks with minimal code changes.

Why teams use this

  1. JWT production failures are often opaque.
  2. Logging raw tokens is unsafe.
  3. Security teams need abuse signals, not just logs.
  4. SRE teams need metrics and trace correlation.
  5. Developers need wrappers that do not alter application correctness.

Features

  1. Ring-buffer recorder with bounded memory.
  2. Safe-by-default token fingerprinting.
  3. Wrapper utilities for sync and async verifier/signer functions.
  4. OpenTelemetry mapping and export queue.
  5. Built-in counters/histograms + Prometheus snapshot output.
  6. Alert rules with thresholds, windows, grouping, and cooldown.
  7. Event stream hooks with on, off, once.
  8. Framework adapters for Express, Fastify, Nest-style modules, and generic HTTP handlers.
  9. CLI incident workflows: inspect, record, metrics, alerts, tail, export-otel, doctor.

Architecture

Modules:

  1. recorder: ring buffer, event pipeline, hooks, wrapper integration.
  2. telemetry: event to OTel span/event mapping, async export queue.
  3. metrics: counters and histograms with JSON + Prometheus output.
  4. alerts: rule engine and callback dispatch.
  5. redaction: claim and field sanitization.
  6. config: options + env + JSON/YAML file loading.
  7. integrations: adapters for common Node server stacks.
  8. exporters: webhook/slack/console handlers and JSONL event exporter.

Install

npm install jwt-flight-recorder

Node.js 18+ required.

Quick start

const jwt = require("jsonwebtoken");
const {
  createJwtFlightRecorder,
  wrapJwtVerifier,
  wrapJwtSigner,
} = require("jwt-flight-recorder");

const recorder = createJwtFlightRecorder({
  capacity: 2000,
  telemetry: {
    enabled: true,
    useOpenTelemetry: true,
    sampleRate: 1,
    decodeSampleRate: 0.25,
  },
  alerts: {
    enabled: true,
    includeDefaultRules: true,
  },
});

const verify = wrapJwtVerifier((token) => jwt.verify(token, process.env.JWT_SECRET), recorder, {
  meta: () => ({ integration: "jsonwebtoken" }),
});

const sign = wrapJwtSigner((payload) => jwt.sign(payload, process.env.JWT_SECRET), recorder);

try {
  const claims = verify("<jwt>");
  const newToken = sign({ sub: "user-1" });
  console.log(claims, newToken);
} catch (error) {
  // behavior unchanged: original errors still throw
}

console.log(recorder.getMetricsSnapshot());

Public API

Core:

  1. createJwtFlightRecorder(options)
  2. wrapJwtVerifier(verifyFn, recorder, options)
  3. wrapJwtSigner(signFn, recorder, options)
  4. parseJwt(token)
  5. buildJwtContext(token, options)
  6. fingerprintToken(token, length)

Telemetry:

  1. createTelemetryExporter(options)
  2. mapEventToTelemetryAttributes(event)

Metrics:

  1. createMetricsRegistry(options)
  2. recorder.getMetricsSnapshot()
  3. recorder.getPrometheusMetrics(prefix)

Alerts:

  1. createAlertManager(options)
  2. DEFAULT_ALERT_RULES
  3. recorder.getAlertHistory(limit)
  4. recorder.evaluateAlerts(events)

Hooks:

  1. recorder.on(eventType, handler)
  2. recorder.off(eventType, handler)
  3. recorder.once(eventType, handler)
  4. recorder.emit(eventType, payload)

Redaction and safety:

  1. createRedactor(options)
  2. sanitizeClaims(payload, options)
  3. sanitizeObject(value, options)
  4. safeJsonStringify(value, options)

Config:

  1. loadRecorderConfig(options)
  2. loadConfigFile(path)
  3. loadEnvConfig(env, prefix)

Integrations:

  1. createExpressJwtObserver(options)
  2. createFastifyJwtPlugin(options)
  3. createNestJwtFlightRecorderModule(options)
  4. createNestJwtFlightRecorderProvider(options)
  5. createNestJwtObserver(options)
  6. wrapHttpJwtHandler(handler, options)

Event model

Typical event fields:

  1. id, type, timestamp, outcome
  2. tokenFingerprint
  3. issuer, audience, subjectHash
  4. expiryStatus, tokenAgeSeconds
  5. errorClass, errorReason, errorMessage
  6. requestContext, requestId, traceId
  7. metadata

No raw token is present unless both:

  1. includeRawToken=true
  2. secureDebugMode=true

OpenTelemetry mapping

JWT events map to spans/events:

  1. verify events -> jwt.verify span
  2. issue events -> jwt.issue span
  3. decode events -> jwt.decode span/event (samplable)

Safe attributes include:

  1. jwt.token.fingerprint
  2. jwt.issuer
  3. jwt.subject.hash
  4. jwt.audience
  5. jwt.expiry.status
  6. jwt.error.class
  7. jwt.error.reason
  8. request and trace correlation ids

Built-in metrics

Counters:

  1. verify_success_total
  2. verify_failure_total
  3. token_issued_total
  4. decode_failure_total
  5. expired_token_total
  6. invalid_signature_total
  7. unknown_issuer_total
  8. refresh_failure_total

Histograms:

  1. auth_latency_ms
  2. token_age_seconds

Export options:

  1. JSON snapshot via API/CLI
  2. Prometheus text format via API/CLI
  3. OpenTelemetry metrics through meter integration

Alerting

Rule capabilities:

  1. threshold + time window
  2. severity levels
  3. grouping keys
  4. cooldown periods
  5. custom filter logic
  6. callback hooks

Pluggable callbacks:

  1. console
  2. webhook
  3. slack webhook
  4. custom function

Default rules include detection for:

  1. repeated verify failures
  2. expired token spikes
  3. unknown issuer activity
  4. invalid signature bursts
  5. decode error bursts
  6. suspicious token reuse
  7. issuance volume spikes

Security model

Production-safe defaults:

  1. includeRawToken=false
  2. claim redaction enabled
  3. sensitive field filtering enabled
  4. telemetry/export failures isolated from app correctness

Important warning:

parseJwt is for observability only and must never be used for trust decisions.

See SECURITY.md for detailed guidance.

Framework integrations

Express

const { createExpressJwtObserver } = require("jwt-flight-recorder");

app.use(
  createExpressJwtObserver({
    recorder,
    verifyToken: (token) => jwt.verify(token, process.env.JWT_SECRET),
    failOpen: false,
  })
);

Fastify

const { createFastifyJwtPlugin } = require("jwt-flight-recorder");

fastify.register(
  createFastifyJwtPlugin({
    recorder,
    verifyToken: (token) => jwt.verify(token, process.env.JWT_SECRET),
    failOpen: false,
  })
);

Nest-style provider/module

const {
  createNestJwtFlightRecorderModule,
  createNestJwtFlightRecorderProvider,
} = require("jwt-flight-recorder");

CLI

Inspect token safely:

jwt-flight-recorder inspect <jwt>

Record event to JSONL:

jwt-flight-recorder record <jwt> --event verify.failure --out jwt-events.jsonl

Metrics from JSONL:

jwt-flight-recorder metrics --in jwt-events.jsonl --prometheus

Evaluate alerts:

jwt-flight-recorder alerts --in jwt-events.jsonl --json

Tail stream:

jwt-flight-recorder tail --in jwt-events.jsonl

Export telemetry mapping:

jwt-flight-recorder export-otel --in jwt-events.jsonl --json

Run diagnostics:

jwt-flight-recorder doctor --config ./examples/jwt-flight-recorder.config.json

Configuration

You can configure via:

  1. JavaScript options
  2. env vars (prefix JFR_)
  3. config file (.json, .yaml, .yml)

Example file:

examples/jwt-flight-recorder.config.json

Common env vars:

  1. JFR_CAPACITY
  2. JFR_INCLUDE_RAW_TOKEN
  3. JFR_SECURE_DEBUG_MODE
  4. JFR_TELEMETRY_ENABLED
  5. JFR_OTEL_ENABLED
  6. JFR_SAMPLE_RATE
  7. JFR_DECODE_SAMPLE_RATE

Migration from 0.1.x

0.2.x keeps wrapper concepts but adds modular observability features.

Recommended migration:

  1. Replace basic recorder construction with explicit telemetry/alert config.
  2. Keep raw token logging disabled in production.
  3. Wire getMetricsSnapshot() and getAlertHistory() into dashboards.
  4. Add framework adapter where request context is needed.
  5. Enable OTel progressively and monitor exporter queue stats.

Development

npm test
npm run audit
npm run pack:check

Examples

  1. examples/express.js
  2. examples/otel.js
  3. examples/alerts.js

License

MIT