This page describes what mint and mint guard actually guarantee, and what they do not.
Randomness#
One entropy source#
Every random byte comes from crypto.randomBytes in node:crypto. There is no Math.random() in the source, no clock-derived fallback, no seed file and no PRNG state to leak.
The random helpers are centralized:
randomIntBelowfor integers under 2 to the 32.randomBigIntBelowfor larger ranges.randomInRangefor inclusive integer ranges.sampleCharsfor character strings.sampleOneandsampleManyfor array choices.shufflefor Fisher-Yates shuffles.
Generators are built from those helpers rather than doing their own arithmetic.
No modulo bias#
Mapping a byte onto a 58-symbol alphabet with byte % 58 makes some symbols more likely. mint does not do that.
For a charset of size k, bytes at or above floor(256 / k) * k are rejected and redrawn. Every remaining byte maps to exactly one symbol, so every symbol has probability 1/k. For alphabets that divide 256, such as 16, 32, 64 and 128, nothing is rejected.
Integers use the same idea over 32-bit values. Large integer ranges reject values outside the largest exact multiple of the range. Dice, ports, item picks and Fisher-Yates shuffles all use these primitives.
Entropy accounting#
--entropy and --json report the random bits in the value, not the encoded length:
- Encoded bytes: 8 bits per byte.
- Sampled characters: length times log base two of the alphabet size.
- UUID v4: 122 bits.
- UUID v7: 74 bits, because the timestamp is not secret.
- UUID v1: 61 bits.
- UUID nil: 0 bits.
- ULID: 80 bits.
- KSUID: 128 bits.
- TypeID: 74 bits.
- Snowflake: 22 bits.
- ObjectId: 64 bits.
- Passphrase: 11 bits per word, plus about 6.64 bits for
--number.
A value can be unique without being secret. Treat the reported bits as the security-relevant number.
Encoding is not encryption#
Base64 and base58 are encodings. They do not hide a value. The security of a generated value comes from the random bits behind it.
The CLI#
- No network requests, telemetry, update checks or remote rule feeds.
- No runtime dependencies. The package ships the compiled CLI and nothing else.
- No config file, history file or generated secret storage.
- No execution of repository code while generating or scanning.
- Values are written to stdout and optionally stderr for entropy and warnings.
- Colors only appear on a TTY.
--copyuses a platform clipboard helper when one is available.
mint guard reads project files and can run read-only git commands. It writes only when you explicitly run init, baseline, install-hook or uninstall-hook.
Redaction#
Findings in text, JSON, SARIF, Markdown and baseline output never contain the raw value.
- Length 12 or more: first four characters, three periods, last two characters.
- Length under 12:
***. - File-level env findings have no value and show
***. - Baseline entries use a salted hash, not a preview.
The scanner keeps the raw match only long enough to compare spans, compute a hash and produce the preview. It is not attached to the finding object.
Baselines#
A baseline hash is:
sha256(salt, rule id, file path, secret)
with NUL separators between fields. The salt is random and stored in the baseline file. Without the salt, the hashes cannot be compared against a list of known secrets. The file does not reveal a value, but it does prove that some value was accepted at a point in time.
What mint does not do#
- It does not encrypt, decrypt or manage keys.
- It does not generate RSA or EC key pairs. Use
ssh-keygen,opensslor a platform keystore. - It does not check password strength or breach lists.
- It does not implement BIP-39 mnemonics. The bundled list is a word source for passphrases.
- It does not hide a value from your shell, terminal scrollback, process list, shell history or clipboard manager.
- It does not store generated values. If you lose one, generate another.
mint uuid --nilis deliberately not random and reports zero bits.
What mint guard does not do#
- It does not prove a repository has no secrets.
- It does not know whether a value is live, fake or already revoked.
- It does not scan binary files, files over the size limit or lines over 8 KB.
- It does not fetch provider key formats or validate a credential online.
- It does not rotate anything. It prints rotation steps, and
--fixprints a plan. - It does not rewrite history or edit files.
- It does not replace secret management, provider-side scanning or access review.
A clean scan is a useful signal, not a security guarantee. A finding is a prompt to rotate, not just delete.
Verification#
The repository includes generator format, charset, uniqueness and uniformity tests, guard rule tests, redaction tests that assert no format leaks a raw secret, and an end-to-end verifier:
npm test
npm run verifynpm run verify drives every generator, flag and output mode through the built CLI. The site's playground is a separate implementation using Web Crypto; it is a demo, not the package's security boundary.