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

node-pki-signer

v0.3.5

Published

Fast in-process X.509 signing for PKIaaS.io and IoT HSM: software keys, PKCS#11, Google Cloud KMS, post-quantum, with OpenSSL fallback

Readme

node-pki-signer

Fast, in-process X.509 signing for PKIaaS.io and the IoT HSM agent.

It signs certificates with software keys, PKCS#11 tokens (YubiKey, SoftHSM) and Google Cloud KMS, including post-quantum keys (ML-DSA, SLH-DSA). Anything it can't do natively falls back to OpenSSL, so new algorithms work as soon as OpenSSL supports them.

Status: early development (0.x): the API may still change. PKIaaS.io runs it in shadow mode (ADR 0004) before it signs there.

Usage

createSigner is a drop-in for node-openssl-cert2's x509.CASignCSR: same parameters, same callback. It signs natively when the CA's signature algorithm is on the allowlist for a backend that can reach the key (src/allowlist.ts, ADR 0003) and hands the whole request to node-openssl-cert2 otherwise:

| Key | Backends, preferred first | Allowlisted | |---|---|---| | key (PEM) | node:crypto, then openssl dgst | every CA key type and hash | | pkcs11: { uri, pin, modulePath } | pkcs11js, then openssl dgst with pkcs11-provider | RSA and ECDSA | | kms: { keyVersion } | the Google Cloud KMS API | RSA with SHA-256 (tested against a real KMS key) |

Non-software signatures are verified against the CA certificate before the certificate is returned. pkcs11js and @google-cloud/kms are optional peer dependencies, loaded only when needed: install them beside this package to sign with PKCS#11 tokens (npm install pkcs11js) or Google Cloud KMS (npm install @google-cloud/kms). Without them, those keys go to OpenSSL.

const { createSigner } = require('node-pki-signer');

const signer = createSigner({
  // optional: the openssl binary for the fallback
  binpath: '/usr/bin/openssl',
  // optional: algorithms that always go to OpenSSL, or true for all of them
  forceOpenSSL: ['ML-DSA-65'],
  // optional: the backends that may sign natively; all by default
  backends: ['software', 'openssl', 'pkcs11', 'openssl-pkcs11', 'kms'],
  // every fallback with its reason; a console.warn by default
  onFallback: (fallback) => log.logEvent(`${fallback.operation} fell back to OpenSSL: ${fallback.reason}`),
});

signer.x509.CASignCSR({ csr, options, ca, key, password }, (err, crt) => {
  // crt.data is the certificate; crt.signedBy is 'native' or 'openssl'
});
// or: const { data, serial, signedBy } = await signer.caSignCSR({ csr, options, ca, key, password });

What falls back:

  • Not supported natively (UnsupportedError): hashes and key types outside the allowlist, libkmsp11 keys without kms.keyVersion, a missing pkcs11js or @google-cloud/kms, a CA certificate the library can't re-encode exactly.
  • Forced by forceOpenSSL.
  • Unexpected errors in the native path, so a bug there doesn't stop issuance.

A refusal of the request itself (SignerError: wrong passphrase or PIN, a token or KMS key that isn't the CA's, a CSR whose signature doesn't verify, a subject OpenSSL would refuse) doesn't fall back, because OpenSSL refuses it too. Fallback reasons never contain keys, passphrases, PINs or CSRs. Requests that fall back get node-openssl-cert2's old subject and date behaviour (ADR 0002).