github jdx/fnox v1.17.0
v1.17.0: MCP Server, Cloudflare and GitHub App Leases, XDG Compliance

15 hours ago

v1.17.0 introduces an MCP server for AI agent secret access, two new lease backends (Cloudflare and GitHub App), and the ability to resolve leased credentials from fnox get. It also brings XDG-compliant directory locations, improved signal handling in fnox exec, and several UX fixes across the TUI, FIDO2, and fnox set.

Highlights

  • MCP server for AI agents -- fnox mcp starts a session-scoped secret broker over stdio, letting AI agents like Claude Code access secrets without having them directly in the environment.
  • Cloudflare and GitHub App lease backends -- Create short-lived, scoped Cloudflare API tokens and GitHub App installation tokens with automatic expiry and revocation support.
  • fnox get resolves leases -- Requesting a key that a lease backend produces (e.g. fnox get AWS_ACCESS_KEY_ID) now resolves the lease automatically, with caching.
  • XDG-compliant directories -- Lease ledger storage now follows the XDG spec, moving from ~/.config/fnox/leases/ to ~/.local/state/fnox/leases/ with automatic migration.

Added

MCP server for secret-gated AI agent access (#343) -- @jdx

The new fnox mcp command starts a Model Context Protocol server over stdio with two tools: get_secret (retrieve a secret by name) and exec (run a command with secrets injected as env vars). Secrets are batch-resolved on first access and cached in memory for the session. Tools can be selectively enabled via config:

[mcp]
tools = ["get_secret", "exec"]  # default: both enabled

Configure in .claude/settings.json:

{
  "mcpServers": {
    "fnox": {
      "command": "fnox",
      "args": ["mcp"]
    }
  }
}

Cloudflare API token lease backend (#335) -- @jdx

A new cloudflare lease backend creates short-lived, scoped Cloudflare API tokens. A parent token with API Tokens: Edit permission creates child tokens that automatically expire. Supports user-owned and account-owned tokens, explicit policies or parent-inherited policies, and configurable duration up to 24 hours.

[leases.cf]
type = "cloudflare"
account_id = "abc123def456"
duration = "1h"

[[leases.cf.policies]]
effect = "allow"
resources = { "com.cloudflare.api.account.{account_id}" = "*" }

[[leases.cf.policies.permission_groups]]
id = "c8fed203ed3043cba015a93ad1616f1f"
name = "Zone Read"

GitHub App installation token lease backend (#342) -- @jdx

A new github-app lease backend creates short-lived GitHub installation access tokens (1 hour max, GitHub's hard limit). Supports scoping to specific permissions and repositories, GitHub Enterprise via api_base, and token revocation via the GitHub API.

[leases.github]
type = "github-app"
app_id = "12345"
installation_id = "67890"
private_key_file = "~/.config/fnox/github-app.pem"

[leases.github.permissions]
contents = "read"
pull_requests = "write"

fnox get resolves leased credentials (#338) -- @jdx

fnox get now checks if the requested key is produced by a configured lease backend before falling back to provider secret resolution. For example, fnox get AWS_ACCESS_KEY_ID will resolve through the AWS STS lease backend (with caching) if one is configured.

fnox lease defaults to creating all leases (#337) -- @jdx

fnox lease create no longer requires a backend name -- omitting it (or passing --all) creates leases for all configured backends sequentially. Secrets are resolved once upfront and shared across backends. fnox lease with no subcommand also defaults to lease create --all.

FIDO2 PIN masking (#334) -- @jdx

FIDO2 PIN prompts now mask input with asterisks during typing, preventing shoulder-surfing.

fnox init -f (#329) -- @jdx

Added -f as a short alias for --force on the init command, consistent with import and sync.

Fixed

XDG-compliant directory locations (#336) -- @jdx

Lease ledger files are now stored under ~/.local/state/fnox/leases/ (or $XDG_STATE_HOME/fnox/leases/), following the XDG Base Directory spec. Config resolution now honors $XDG_CONFIG_HOME. Existing ledger files are automatically migrated on first access. A new FNOX_STATE_DIR env var overrides the state directory.

fnox exec signal handling and silent exit (#339) -- @jdx

fnox exec now forwards SIGINT and SIGTERM to the child process so Ctrl-C and kill reach it properly. On subprocess failure, fnox exits silently with the child's exit code (128+signal for signal deaths) instead of printing a noisy error message. Temp files from as_file secrets are now properly cleaned up via Rust destructors.

fnox set writes to the correct config file (#331) -- @jdx

fnox set now writes to the lowest-priority existing config file in the current directory instead of always targeting fnox.toml. If only fnox.local.toml exists, secrets are written there. If a non-default profile is active and a profile-specific file exists (e.g. fnox.staging.toml), secrets are written there.

TUI skips interactive-auth providers (#333) -- @jdx

fnox tui now skips FIDO2 and YubiKey providers that require physical interaction, preventing display corruption from provider stderr output and input prompts. An error message directs users to fnox exec instead.

Removed duplicate FIDO2 touch prompt (#332) -- @jdx

Removed the redundant "Touch your FIDO2 key..." message -- the underlying library already prints its own touch prompt.

Breaking Changes

Lease ledger location moved -- Lease ledger files have moved from ~/.config/fnox/leases/ to ~/.local/state/fnox/leases/. Existing files are migrated automatically, but if you have scripts that reference the old path directly, update them to use ~/.local/state/fnox/leases/ or the FNOX_STATE_DIR env var.

fnox exec exit behavior changed -- fnox exec no longer prints an error message or returns a CommandExitFailed error when the subprocess fails. It exits silently with the child's exit code. If you were parsing fnox's error output to detect subprocess failures, check the exit code instead.

fnox lease create backend name is now optional -- Running fnox lease create without arguments now creates all configured leases instead of printing a usage error. Scripts that relied on the missing-argument error should be updated.

Full Changelog: v1.16.1...v1.17.0

Don't miss a new fnox release

NewReleases is sending notifications on new releases.