This release adds a read-only Keeper Secrets Manager provider and delivers a batch of fixes to file-backed secrets, FIDO2 prompting, and shell integration.
Added
-
Keeper Secrets Manager provider (#720) -- @jdx. A new read-only
keeper-smprovider backed by Keeper's official Rust SDK. Secret values use Keeper notation such asRECORD_UID/field/password. Authentication works from a JSON config file (KSM_CONFIG/FNOX_KEEPER_CONFIG, or the default~/.keeper/ksm-config.json), with optional one-time-token bootstrap viaKSM_TOKEN/FNOX_KEEPER_TOKEN(which must persist to a file-backed config). Batch reads redeem the token once and fetch concurrently, and Keeper environment variables are scrubbed from the proxy's ambient credentials.DB_PASSWORD = { provider = "keeper-sm", value = "RECORD_UID/field/password" }
-
fnox set --from-file <path>(#730) -- @jdx. Reads a secret value verbatim from a UTF-8 file without trimming, preserving trailing newlines. This fixes SSH private keys and similaras_filesecrets losing their required final newline, which happened becausefnox settrims stdin values and shell command substitution strips trailing newlines. The existingecho "x" | fnox set KEYbehavior is unchanged;--from-filecannot be combined with a positional value.fnox set SSH_KEY --from-file ~/.ssh/id_ed25519
Fixed
-
as_filesecrets are cleaned up on shell exit (#724) -- @jdx. Decrypted temp files created foras_filesecrets previously lingered because cleanup only ran on a laterhook-envrefresh.fnox deactivatenow removes session-recorded temp files, and a new zshzshexithook cleans them up when you close the terminal. Cleanup is scoped to paths under the session's hook temp dir (survivingTMPDIRchanges), and nested zsh sessions no longer delete files owned by their parent. -
FIDO2 prompts only once per batch (#732) -- @jdx. Resolving multiple FIDO2-protected secrets no longer triggers repeated and delayed PIN/touch prompts. The provider now acquires the hardware HMAC secret once and decrypts all values with it, and device discovery runs before the PIN prompt so missing or multiple-device errors surface without an unusable prompt. Per-secret results and errors are preserved without negatively caching transient hardware failures.
-
Auth output kept off
hook-envstdout (#713) -- @halms.fnox hook-envstdout is evaluated as shell code, so an expired session that triggered reauthentication could cause login progress output to be executed as commands. Auth-command stdout is now routed to stderr while remaining live for interactive logins. -
MCP tool list works with strict clients (#727) -- @jdx.
tools/listnow includes thettlMs: 0andcacheScope: "private"cache hints required by the MCP2026-07-28schema, so strict clients such as Claude Code can fetch fnox tools again. The existing no-cache behavior is preserved.
Documentation
- Documented
${SECRET_NAME}interpolation in default values (#733) -- @arthurfiorette. Explains resolution order across providers, interpolated defaults, literal defaults, and environment variables, plus errors for undefined references and dependency cycles.
New Contributors
- @arthurfiorette made their first contribution in #733
Full Changelog: v1.33.1...v1.34.0
💚 Sponsor fnox
fnox is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Keeping fnox secure, maintained, and free is funded by sponsors.
If fnox is handling secrets or config for you or your team, please consider sponsoring at jdx.dev. Sponsorships are what let fnox stay independent and the project keep moving.