The macOS keychain provider can now require Touch ID for each read, and fnox proxy run streams rule-domain responses so SSE and LLM clients get events as they arrive. Secrets can record the URL where a new value is issued. This release also fixes several 1Password problems: secrets lost their trailing newline, and environment:// references failed on CLI 2.42.0.
Added
- Touch ID protection for macOS Keychain secrets (#1140, #1146) by @jdalton and @jdx. Set
touch_id = trueon akeychainprovider:[providers.keychain] type = "keychain" service = "fnox" touch_id = true
- Protected items are stored under a separate
<service>.touch-idKeychain service. Before each read, fnox shows the invoking command, project path and secret name, then asks macOS for Touch ID. Canceling or failing the check blocks access, and there is no password fallback. - fnox asks for Touch ID on every protected read. With
touch_id = true,fnox provider testcreates a temporary protected item and reads it, so it checks real protected access. - The protected Keychain operation runs through a signed
Fnox.apphelper. Official releases publish it as a separatefnox-touch-id-<target>.zipasset. Install it in/Applicationsor next to thefnoxbinary. Without the helper, Touch ID operations fail with an Apple missing-entitlement error. - Source builds on macOS need Node.js 22.18.0 or later to build the approval UI. They also need a Developer ID provisioning profile, and the CLI and helper must be signed with the same team and identifier. Builds made with an SDK older than macOS 26 use an opaque approval panel instead of the glass style. See the keychain docs for helper packaging.
- Protected items are stored under a separate
- Secret URLs and
fnox set --open(#1145) by @jdx. A secret can now include aurlfield for the page where you create a new value, such as a service's token settings page. The URL must usehttporhttps.fnox set KEY --openprints that URL, opens it in your browser, and then shows the usual hidden prompt for the value:fnox set GITHUB_TOKEN --url <URL> # record the URL only fnox set GITHUB_TOKEN --open # open the page, then enter the new value
--openneeds an interactive terminal and can't be combined withVALUE,--from-fileor--generate.fnox listshows aURLcolumn only when at least one secret has a URL, andfnox tuishows the URL in the secret details. - Find 1Password items by tag (#1138) by @jdalton.
fnox provider discoverlists item metadata (ID, title, tags and vault) without reading any secret fields, so you can look up references before adding them to your config. It uses the provider's configured account and vault. If no vault is configured, it searches every vault the account can access. Tags can be comma-separated or passed more than once, and archived items are skipped.fnox provider discover op --tags project/example --json
- Opt-in sudo Touch ID setup script (#1139) by @jdalton.
scripts/enable-sudo-touch-id.shcan check, preview or enable Touch ID forsudoon macOS, using the--check,--dry-runand--applymodes.--jsongives structured output. The script never elevates itself and only creates/etc/pam.d/sudo_localwhen that file doesn't exist. It refuses to change existing policies it doesn't recognize.
Changed
- Streaming proxy responses (#1113) by @jdx.
fnox proxy runno longer waits for a rule domain's full upstream response before forwarding it. It sends the headers right away and then sends the body in chunks as it arrives. Secret values are still redacted, including values split across two chunks. Before this change, streaming APIs such as SSE-based LLM endpoints delivered no events until the upstream finished, and agent clients could time out.- Responses no longer have a 10 MiB limit. Request bodies are still limited to 10 MiB.
- If the upstream fails partway through a response, the client receives an incomplete chunked body instead of a 502.
Fixed
fnox proxy runno longer exits when a client disconnects mid-response (#1112) by @jdx. Previously, the proxy was killed by SIGPIPE (exit 141). The child command then pointed at a closed port and the proxy's CA file was left in the temp directory.proxy runanddaemon servenow drop only the affected connection and keep running. Pipelines such asfnox get FOO | headbehave as before.- 1Password values keep their trailing newline (#1131) by @jdx. Values read from 1Password now match the stored value exactly. This fixes SSH private keys in
[files]that OpenSSH rejected withinvalid format. Batched reads also no longer change multi-line values or drop empty ones. As a result, a stored value that really ends in whitespace now keeps it in environment variables too. Sync cache entries written by earlier versions keep the trimmed value until you refresh them. - 1Password
environment://references work with CLI 2.42.0+ (#1144) by @jdx. fnox now runsop environment secret list. It falls back toop environment readonly when the CLI doesn't know the new command, which is the case for older betas. fnox getandfnox syncresolve provider tokens stored as secrets (#1125) by @jdx. A provider token kept as its own fnox secret, such asBWS_ACCESS_TOKEN, is now resolved forgetandsyncas it already was forexecandexport.syncstill writes only the secrets you selected.- Shell hook reports the actual config error (#1130) by @jdx. When
fnox.tomlhas a schema error,hook-envnow warns with the parse error. Previously it reported a missing.config/fnox.local.toml, or showed no warning at all when that file existed. - Vault leases send
ttlonly whendurationis set (#1129) by @jdx. This fixesunknown field: ttlerrors from strict engines such as the GitHub secrets plugin on OpenBao. If you don't setduration, engines that honorttlnow use their role's default TTL instead of the 15 minutes fnox used to request. Setdurationto keep the old behavior. - Daemon shell hooks pick up
FNOX_AGE_KEYchanges (#1137) by @Aschenbath. Adding, replacing or removing the inline age key in the calling shell now takes effect on the next hook request, without restarting the daemon. fnox sync --local-filewarns before removing stale local cache (#1135) by @jdx. When entries are marked for removal,--dry-runand the confirmation prompt now show a hint. Personal secrets synced by v1.36.0 or older lacklocal_source = trueand look the same as cache copies, so you need to add that flag to keep them. The sync guide now documentslocal_sourceand how to recover those entries.
New Contributors
- @jdalton made their first contribution in #1132
- @Aschenbath made their first contribution in #1137
Full Changelog: v1.47.0...v1.48.0
💚 Sponsor fnox
fnox is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If fnox handles secrets or config for you or your team, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep fnox secure, free, and independent.