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

@iden-q/scanner-cli

v0.7.1

Published

Command-line post-quantum cryptography exposure scanner — scan files, folders, and domains from your terminal or CI.

Readme

@iden-q/scanner-cli

Command-line post-quantum cryptography exposure scanner, for DevOps, platform, and security engineers who need to know what crypto is quietly shipping to prod. Point it at a file, a folder, piped stdin (e.g. a git diff), or a live domain's TLS certificate, and it reports crypto that's vulnerable to quantum attack. Built for CI pipelines (via --fail-on) as well as local dev use.

Install

Global install:

npm install -g @iden-q/scanner-cli
q-scanner scan .

No-install, via npx (the package's bin is q-scanner, not the package name):

npx -p @iden-q/scanner-cli q-scanner scan .

Usage

q-scanner — post-quantum cryptography exposure scanner

Usage:
  q-scanner scan <path>          Scan a file or folder for vulnerable crypto
  q-scanner scan --stdin         Scan piped text (e.g. git diff | q-scanner scan --stdin)
  q-scanner scan-domain <host>   Scan a domain's TLS certificate

Options:
  --format <table|json|cbom>     Output format (default: table); cbom emits a CycloneDX Cryptography Bill of Materials
  --lang <en|es>                  Output language (default: en)
  --output <path>                 Where to write the report file (default: ./q-scanner-report.<ext>, written every run)
  --fail-on <critical|high|medium|low>
                                  Exit 1 if the worst finding meets/exceeds this severity
  --connect-mesh                  Emit anonymous CBOM telemetry to the iden-q mesh (scan and scan-domain;
                                  standalone by default). Never affects the scan result or exit code.
  --mesh-key <clientId:apiKey>    Mesh API key inline; or set IDENQ_MESH_CLIENT_ID + IDENQ_MESH_API_KEY (preferred in CI)
  --mesh-url <url>                Mesh base URL; or IDENQ_MESH_URL. Required to emit — there is no default target.
  -h, --help                     Show this help

Output defaults to English; pass --lang es for Spanish (finding locations, error messages, and regulatory notes). Colored, animated output is used automatically on an interactive terminal (respects NO_COLOR); it's plain text — and quiet, no spinner frames — when piped or run in CI.

Every run also writes the report to disk (in the requested --format) so it can be picked up by report tooling without remembering to redirect stdout — to ./q-scanner-report.<txt|json|cbom.json> by default, or wherever --output <path> points.

Examples

Scan a folder and print a table:

q-scanner scan ./src

Scan a domain's TLS certificate as JSON:

q-scanner scan-domain example.com --format json

Gate a CI step on findings — fail the build if a diff introduces anything high severity or worse:

git diff origin/main...HEAD | q-scanner scan --stdin --fail-on high

Scan in Spanish:

q-scanner scan ./src --lang es

Emit a Cryptography Bill of Materials (CycloneDX, tagging PQC algorithms with their NIST FIPS standard — ML-KEM/FIPS 203, ML-DSA/FIPS 204, SLH-DSA/FIPS 205) to a specific path — omit --output and it still lands at ./q-scanner-report.cbom.json:

q-scanner scan ./src --format cbom --output cbom.json

Connect a CI scan to the iden-q mesh (credentials from the pipeline's secret store, never in argv):

IDENQ_MESH_CLIENT_ID=$MESH_CLIENT_ID \
IDENQ_MESH_API_KEY=$MESH_API_KEY \
IDENQ_MESH_URL=https://idenq.io \
  q-scanner scan ./src --connect-mesh

A scan-domain contributes too — the negotiated key-exchange group's class (classical / hybrid / post-quantum) and the certificate's issuer, named from its organisation:

IDENQ_MESH_CLIENT_ID=$MESH_CLIENT_ID \
IDENQ_MESH_API_KEY=$MESH_API_KEY \
IDENQ_MESH_URL=https://idenq.io \
  q-scanner scan-domain example.com --connect-mesh

Connecting to the mesh (--connect-mesh)

The scanner is standalone by default — it makes no network call and works fully offline. --connect-mesh opts a scan or a scan-domain in to emitting anonymous CBOM telemetry — the shared node/edge graph, with each key establishment classed classical, hybrid, or post-quantum — to the iden-q mesh. Nothing that identifies the machine, the host, or the code is sent — only public facts and counts. For a scan-domain the key-establishment class comes from the negotiated TLS key-exchange group (never the certificate key), and the issuer is named from its organisation.

  • Off the critical path. Emission never changes the scan's findings, output, or exit code. A mesh that is unreachable, misconfigured, or slow yields at most a warning on stderr; --fail-on still gates on the scan alone.

  • Credential — either mode the mesh accepts:

    • API key (client_credentials): clientId + secret. Inline via --mesh-key clientId:apiKey, or (preferred in CI, so the secret never appears in argv) via IDENQ_MESH_CLIENT_ID + IDENQ_MESH_API_KEY.
    • Public key (private_key_jwt): the ML-DSA-44 private JWK the console mints, in IDENQ_MESH_PRIVATE_KEY (the JWK JSON), with IDENQ_MESH_CLIENT_ID. The CLI signs a short-lived assertion per token; the private half never leaves the process and no shared secret is sent. Because it is a secret it is environment-only — there is no inline flag for it.

    Precedence: an inline --mesh-key wins; otherwise a private JWK in the environment is preferred over an API key (public-key auth is the stronger of the two).

  • Target — required, no default: --mesh-url or IDENQ_MESH_URL. Emitting is always a named target, never an accidental production write.

Both scan and scan-domain emit through the same library mapping (@iden-q/scanner-lib's buildObservation / buildProbeObservation), so a domain scan here contributes the exact same graph — and the same issuer token for the same CA — as the web scanner does.

Signing in (login) and cloud scan history (--save)

The mesh path above is anonymous machine telemetry — no person, no account. A separate, opt-in path lets a person sign in and save their scans to their own iden-q account, exactly like the web scanner. It uses the OAuth 2.0 device flow (RFC 8628): the CLI never stores a static secret, only short-lived tokens.

q-scanner login                 # prints a URL + code; approve it in the browser
q-scanner scan ./src --save     # push this scan to your cloud history
q-scanner scan-domain idenq.io --save
q-scanner history               # list your cloud history (--clear to delete it)
q-scanner whoami                # who you are, your roles, and the environment
q-scanner logout                # revoke and forget the session

How login works: the CLI asks the platform for a device_code and a short user_code, prints where to approve it, and polls while you sign in and step up with a passkey in the console. On approval it stores your person token (access + refresh) under ~/.config/q-scanner/session.json, mode 0600 — readable only by you — and enables the scanner product for your account so --save works straight away. The stored access token is refreshed automatically when it expires (within the twelve-hour refresh window); after that, login again.

  • Cloud history is one shared snapshot, the same one the web dashboard reads and writes. --save appends this scan to it (read-modify-write) rather than overwriting, so a CLI scan shows up in the web and vice versa. --save is off the critical path — a save failure is a stderr warning, never a change to findings or exit code.
  • Environment. login targets prod (https://idenq.io/api/v1) by default; point it at another environment with --api-url or IDENQ_API_URL. The token is bound to the environment it was minted for, so whoami/--save/history all use the same one.
  • This is the person axis, not the mesh. --connect-mesh (machine, anonymous, per-tenant) and login/--save (person, identified, your account) are independent — you can use either, both, or neither.

A note on the published build

The dist/ shipped to npm is obfuscated (via javascript-obfuscator) as an anti-copying deterrent. It doesn't change behavior — same inputs, same outputs, same exit codes. If you're debugging the CLI itself, build from source instead (see Developing).

Library

The detection logic lives in @iden-q/scanner-lib, a standalone package this CLI is built on. Use it directly if you want to embed the same scanning in your own tool instead of shelling out to q-scanner.

Developing

yarn install
yarn build
yarn test
yarn typecheck

Releasing

Versioning and publishing are automatic, via Changesets. If your change should ship in the next release, add a changeset before opening a PR:

yarn changeset

Follow the prompt (bump type + a short summary — this becomes the changelog entry). Merging your PR into main makes the CD workflow open or update a "Version Packages" PR that bumps package.json and CHANGELOG.md. Merging that PR publishes to npm automatically. No manual version bumps, no manual npm publish.

License

Proprietary — see LICENSE. IdenQ's decision of 2026-09-02, replacing the AGPL-3.0-or-later the CLI carried until then: no right to use, copy, modify or distribute it is granted by its presence on npm or in this repository, only by a written agreement with IdenQ.