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

@syncrona/redaction

v1.0.0

Published

Shared secret detection and redaction for SyncroNow AI (sensitive key names, secret-shaped values, stable redaction markers) used by the MCP server audit trail and the instance mirror.

Readme

@syncrona/redaction

| npm | node | license | CI | TypeScript | |:--:|:--:|:--:|:--:|:--:|

Shared secret detection and redaction for SyncroNow AI. This package is the single source of truth for the question "is this a credential?", asked by every component that persists ServiceNow data or tool traffic:

The detectors grew inside the audit trail, hardened one security review at a time. They moved here when the mirror needed them, because two copies of a secret scanner drift, and the copy nobody is actively reviewing is the one that falls behind — in the consumer that writes to a repository rather than a local log.

What lives here

Sensitive key names

  • isSensitiveKey(key) — true when a property NAME suggests credential material (password, apiKey, x-auth-token, session, passphrase, otp, …). Deliberately over-eager: it also matches keyword and monkey. A redacted key name costs a reviewer one lookup; a leaked credential costs a rotation.

Secret-shaped values

  • looksLikeSecretValue(value) — true when a VALUE looks like credential material regardless of the key it arrived under: scheme://user:pass@host and bare user:pass@host connection strings, JWTs, PEM private keys, inline Authorization headers, AWS access-key IDs, vendor-prefixed API keys (Stripe, OpenAI, GitHub, Slack, GitLab, Google) and raw 256-bit hex key material.
  • SCAN_BUDGET (8192) — the maximum length scanned in full. Fails closed: a longer value is reported as a secret without being scanned. The historical behaviour was the opposite, and padding a secret past the budget was all it took to launder it into a log in cleartext.

Stable redaction markers

  • redactValue(value) — __SYNCRONA_REDACTED__<sha256-12>.
  • REDACTION_MARKER_PREFIX, REDACTION_MARKER_HASH_CHARS.

The marker embeds a short digest of the plaintext, so the same secret yields the same marker on every sync (a mirror re-run of an unchanged instance must be byte-identical) while a rotated secret yields a different one. A constant marker would erase that history: a credential could be replaced with no diff at all.

Design notes

This module is intentionally a leaf: it depends on no other @syncrona package, only on node:crypto. A security primitive at the bottom of the dependency graph can be audited on its own and can never be made to import something that imports it back.

It is also pure and synchronous — no I/O, no clock, no configuration. The MCP server calls it while holding the audit lock and the mirror calls it once per field of every record on an instance, so the cost must be bounded and the result must be a function of the input alone.

What is not here

Field-type deny — dropping a column because sys_dictionary reports its internal_type as password/password2 — belongs to the caller, which has the schema knowledge this package deliberately does not. It is nevertheless the strongest of the three signals: measured on a real instance, a password2 column returns a 106-character ciphertext over the Table API, which no value-shape rule here would flag. Never weaken that path on the strength of this one.

False positives are a cost, not a bonus

A match redacts the whole value, so an over-eager value pattern destroys the forensic detail of the record an operator is reading. Two patterns here have already been narrowed after exactly that regression (a bare Basic/Bearer keyword matched ordinary prose; a bare user:pass@host form matched npm:[email protected]). Each carries its honest limit in a comment beside it. The corpus tests in test/ assert both directions — every rule has a true positive and a near-miss that must pass through verbatim.