Files
envsitter/README.md
2026-01-12 10:46:12 +01:00

4.3 KiB
Raw Blame History

envsitter

Safely inspect and match .env secrets without ever printing values.

envsitter is designed for LLM/agent workflows where you want to:

  • List keys present in an env source (.env file or external provider)
  • Check whether a keys value matches a candidate value you provide at runtime ("outside-in")
  • Do bulk matching (one candidate against many keys, or candidates-by-key)
  • Produce deterministic fingerprints for comparisons/auditing

Security model (what this tool does and does not do)

  • Values are read in-process for comparisons, but never returned by the library API and never printed by the CLI.
  • Deterministic matching uses HMAC-SHA-256 with a local pepper.
    • This avoids publishing raw SHA-256 hashes that are easy to dictionary-guess.
  • Candidate secrets should be passed via stdin (--candidate-stdin) to avoid shell history.

Non-goals:

  • This tool is not a secret manager.
  • This tool does not encrypt or relocate .env values; it operates on sources in-place.

Install

npm install envsitter

Or run the CLI without installing globally:

npx envsitter keys --file .env

Pepper (required for deterministic fingerprints)

envsitter uses a local "pepper" as the HMAC key.

Resolution order:

  1. process.env.ENVSITTER_PEPPER (or ENV_SITTER_PEPPER)
  2. Pepper file at .envsitter/pepper (auto-created if missing)

The pepper file is created with mode 0600 when possible, and .envsitter/ is gitignored.

CLI usage

List keys

envsitter keys --file .env

Filter by key name (regex):

envsitter keys --file .env --filter-regex "/(KEY|TOKEN|SECRET)/i"

Fingerprint a single key

envsitter fingerprint --file .env --key OPENAI_API_KEY

Outputs JSON containing the keys fingerprint and metadata (never the value).

node -e "process.stdout.write('candidate-secret')" \
  | envsitter match --file .env --key OPENAI_API_KEY --candidate-stdin --json

Exit codes:

  • 0 match found
  • 1 no match
  • 2 error/usage

Match one candidate against multiple keys

node -e "process.stdout.write('candidate-secret')" \
  | envsitter match --file .env --keys OPENAI_API_KEY,ANTHROPIC_API_KEY --candidate-stdin --json

Match one candidate against all keys

node -e "process.stdout.write('candidate-secret')" \
  | envsitter match --file .env --all-keys --candidate-stdin --json

Match candidates-by-key (bulk assignment)

Provide a JSON object mapping key -> candidate value.

envsitter match-by-key --file .env \
  --candidates-json '{"OPENAI_API_KEY":"sk-...","ANTHROPIC_API_KEY":"sk-..."}'

For safer input, pass the JSON via stdin:

cat candidates.json | envsitter match-by-key --file .env --candidates-stdin

Scan for value shapes (no values returned)

envsitter scan --file .env --detect jwt,url,base64

Optionally restrict which keys to scan:

envsitter scan --file .env --keys-regex "/(JWT|URL)/" --detect jwt,url

Library API

Basic usage

import { EnvSitter } from 'envsitter';

const es = EnvSitter.fromDotenvFile('.env');

const keys = await es.listKeys();
const fp = await es.fingerprintKey('OPENAI_API_KEY');
const match = await es.matchCandidate('OPENAI_API_KEY', 'candidate-secret');

Bulk matching

import { EnvSitter } from 'envsitter';

const es = EnvSitter.fromDotenvFile('.env');

// One candidate tested against a set of keys
const matches = await es.matchCandidateBulk(['OPENAI_API_KEY', 'ANTHROPIC_API_KEY'], 'candidate-secret');

// Candidates-by-key
const byKey = await es.matchCandidatesByKey({
  OPENAI_API_KEY: 'sk-...',
  ANTHROPIC_API_KEY: 'sk-...'
});

External sources (hooks)

You can load dotenv-formatted output from another tool/secret provider:

import { EnvSitter } from 'envsitter';

const es = EnvSitter.fromExternalCommand('my-secret-provider', ['export', '--format=dotenv']);
const keys = await es.listKeys();

Development

npm install
npm run typecheck
npm test

Run a single test file:

npm run build
node --test dist/test/envsitter.test.js

Run a single test by name:

npm run build
node --test --test-name-pattern "outside-in" dist/test/envsitter.test.js

License

MIT. See LICENSE.