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

@ethan-devlab/secretgen

v0.2.0

Published

Interactive and scriptable cryptographically secure secret and key artifact generator with 80 presets

Readme

@ethan-devlab/secretgen

A Node.js 22+ CLI and library for cryptographically secure secrets, provisioning bundles, public nonce/salt material, and asymmetric key artifacts. It includes 80 presets.

Quick start

npx -y @ethan-devlab/secretgen
npx -y @ethan-devlab/secretgen django
npx -y @ethan-devlab/secretgen generic:password --length 48
npx -y @ethan-devlab/secretgen --list

The interactive terminal first lets you search for a preset. It then prompts for that preset's length, byte count, algorithm, encoding, or other options. Press Enter at an option prompt to accept its displayed default.

Install as a CLI or library:

npm install -g @ethan-devlab/secretgen
npm install @ethan-devlab/secretgen
import { generate, generateArtifact } from '@ethan-devlab/secretgen';

const password = generate('generic:password', { length: 48 });
const passphrase = generate('generic:passphrase', { words: 8, separator: 'hyphen' });
const keypair = await generateArtifact('pem:keypair', { algorithm: 'ed25519' });

generate() remains the synchronous scalar API. Multi-part presets use the asynchronous generateArtifact() API.

Presets

Run secretgen --list for all aliases and configurable flags, or secretgen --info <preset> for option ranges and defaults.

| Category | Presets | |----------|---------| | Generic and Python | generic:hex, generic:base64, generic:base64url, generic:alphanumeric, generic:password, python:token-hex, python:token-urlsafe | | Frameworks | django:secret-key, flask:secret-key, fastapi:jwt-secret, cryptography:fernet, express:session-secret, express:cookie-secret, authjs:secret, iron-session:password, rails:secret-key-base, laravel:app-key, symfony:app-secret, phoenix:secret-key-base, wordpress:salts | | Cryptography | jwt:hs256, jwt:hs384, jwt:hs512, aes:128, aes:192, aes:256, chacha20-poly1305:key, hmac:sha256, hmac:sha512, totp:secret | | Scalars and application secrets | generic:base32, generic:urlsafe-string, generic:passphrase, uuid:v4, uuid:v7, better-auth:secret, nuxt:session-password, adonis:app-key, codeigniter:encryption-key, spring:base64-key, github:webhook-secret, oauth:pkce-verifier, rails:master-key, wireguard:preshared-key, paseto:v4-local-key, hmac:sha384, hotp:secret, sodium:secretbox-key | | Provisioning and material bundles | hotp:provisioning, totp:provisioning, mfa:recovery-codes, aspnet:machine-key, salt:argon2, nonce:aes-gcm, nonce:chacha20-poly1305, nonce:xchacha20-poly1305, iv:aes-cbc | | Key artifacts | pem:keypair, jwk:keypair, jwks:keyset, openssh:keypair, wireguard:keypair, age:keypair, paseto:v4-public-keypair, sodium:box-keypair, sodium:sign-keypair, dkim:keypair | | Deployment and infrastructure | strapi:secrets, mongodb:keyfile, consul:gossip-key, nomad:gossip-key, rabbitmq:erlang-cookie, nats:nkey | | Application secrets and identifiers | directus:secret, payload:secret, keystone:session-secret, id:nanoid | | Encodings | generic:base58, generic:base32hex, generic:base32-crockford |

strapi:secrets writes .env, strapi-secrets.json, and public metadata.json. Its six environment keys are APP_KEYS (four independent values), API_TOKEN_SALT, ADMIN_JWT_SECRET, JWT_SECRET, TRANSFER_TOKEN_SALT, and ENCRYPTION_KEY. Each of the nine values is independent, padded Base64 for 32 random bytes.

Provider-issued API keys, access tokens, certificates, CSRs, password hashes, and legacy weak formats are intentionally out of scope. Those values require an issuer, an application policy, or a different lifecycle than local random generation.

CLI

secretgen                              # searchable menu, then option prompts
secretgen <preset> [preset options]   # direct generation
secretgen --list
secretgen --info <preset>

-b, --bytes <n>                       # byte-configurable presets
    --length <n>                      # character-configurable presets
-n, --count <n>                       # scalar or artifact batch
    --format raw|env|json             # scalar output; artifacts default to JSON
    --env-name <NAME>                 # scalar env output
    --output-dir <path>               # artifact or scalar bundle directory
    --part <role|filename>            # one raw artifact part on stdout
    --force                           # replace an existing bundle
    --passphrase-env <NAME>           # private-key passphrase source
    --passphrase-file <path>          # private-key passphrase source
-i, --interactive                     # prompt for a named preset's options

Direct examples:

secretgen generic:password --length 64
secretgen generic:passphrase --words 8 --separator underscore
secretgen totp:provisioning --account [email protected] --issuer Example
secretgen totp:provisioning --part provisioning-uri
secretgen jwk:keypair --algorithm ec --curve P-384 --output-dir ./signing-key
secretgen dkim:keypair --selector mail --domain example.com --output-dir ./dkim

Scalar raw mode prints only generated values to stdout. Artifact mode prints a JSON envelope by default. Binary parts in that envelope use Base64. --part selects one role or filename and writes its raw content. --info also reports scalar sensitivity: only UUID v4, UUID v7, and NanoID are public identifiers; all other scalar values are secret.

Artifact batches use numbered subdirectories. RSA and DKIM RSA generation is limited to 10 artifacts per command; other artifact presets are limited to 100; scalar presets are limited to 1,000.

Scalar bundle output

Every scalar preset accepts --output-dir. It writes the already-generated value once, with no change to the library API or ordinary stdout format:

  • Most presets write value.txt with role value.
  • rabbitmq:erlang-cookie writes .erlang.cookie with role cookie.
  • Secret scalar files use mode 0600; UUID and NanoID identifier files use 0644.
  • Batches retain the numbered-directory layout and the manifest never contains generated values.

--output-dir cannot be combined with --format, --env-name, --part, or passphrase flags. --force is only valid with --output-dir. In interactive scalar mode, secretgen asks for an output directory after options; press Enter to keep stdout output.

Private-key encryption

pem:keypair and openssh:keypair can encrypt private keys. Interactive mode asks for the passphrase twice without echo. Scripts must use an environment variable or file; secretgen deliberately has no literal --passphrase argument.

export SECRETGEN_KEY_PASSPHRASE='use a secret source in real automation'
secretgen pem:keypair --encrypt-private-key \
  --passphrase-env SECRETGEN_KEY_PASSPHRASE \
  --output-dir ./keys

For a batch, one passphrase encrypts all private keys generated by that command. Passphrase files may end in one newline; the newline is not part of the passphrase.

Artifact file safety

Artifact output is written to a sibling staging directory before it is moved into place. Existing targets are rejected unless --force is present. Symbolic-link and junction targets are rejected.

  • POSIX: bundle directories use mode 0700; secret parts and the manifest use 0600; public parts use 0644.
  • Windows: inherited ACLs are removed from the bundle and every file. Access is granted only to the current user and Local System. If ACL hardening fails, generation fails before the bundle is installed.
  • secretgen-manifest.json describes roles, filenames, media types, encodings, and metadata. It never duplicates part contents.

Treat stdout JSON as sensitive for keypair and provisioning presets because it can contain private keys or OTP seeds.

Security design

  • Secret randomness comes from Node.js node:crypto or the selected cryptographic library's CSPRNG.
  • No Math.random(), seed option, telemetry, or network calls.
  • Fixed-format presets reject incompatible size overrides.
  • EFF long-list passphrases use unbiased CSPRNG word selection.
  • UUID v4 uses Node.js CSPRNG and UUID v7 uses the maintained uuid implementation.
  • Salts, nonces, and IV presets label their material as public and unique-per-operation. They are not reusable encryption keys.
  • Aliases resolve through one registry, and typed option validation is shared by the CLI and library APIs.

An ecosystem preset generates a locally created value in the documented format. It does not contact or impersonate the named provider or framework.

Local development

npm install
npm link
npm test
npm run check
npm audit --omit=dev
node ./bin/secretgen.js generic:password --length 48