Running commands
Most of the time you use fnox through one command, fnox exec. This page covers it and the other ways to get secrets out of fnox: get, export, file secrets, and env --json for tools.
fnox exec
fnox exec -- npm start
fnox exec --profile production -- ./deploy.shfnox resolves the secrets for the current directory and profile, starts the command with them added to its environment, and exits with the command's exit code. Your shell's environment is not changed.
Put fnox options before --. Everything after it is passed to the command untouched.
Your shell expands $VARIABLES before fnox runs, so this prints an empty line:
fnox exec -- echo $DATABASE_URL # wrong: expanded by your shell firstTo use a secret in a shell expression, run a child shell and single-quote the script:
fnox exec -- sh -c 'psql "$DATABASE_URL" -c "select 1"'Useful options:
| Option | What it does |
|---|---|
-P, --profile <name> | Use a profile. Repeat or comma-separate to stack profiles. |
--if-missing error | Fail if any secret can't be resolved. See missing secrets. |
--refresh <KEY> | Re-read one secret from its provider instead of the daemon cache. |
--replace | Replace the fnox process with the command (Unix only). Rejected when the command would receive an as_file secret or the profile configures leases, since fnox must clean those up afterward. |
--non-interactive | Never prompt or open a browser to authenticate. Use in CI. |
fnox x is a short alias for fnox exec.
Choose which secrets reach a command
Each secret has an env setting:
env | fnox exec | Interactive shell (shell integration) |
|---|---|---|
true (default) | Injected | Injected |
"exec" | Injected | Not injected |
false | Not injected | Not injected |
env = "exec" # project-wide default: keep secrets out of the interactive shell
[secrets]
DATABASE_URL = { provider = "age", value = "YWdl..." }
SIGNING_KEY = { provider = "age", value = "YWdl...", env = false }An env = false secret is still available to fnox get, to other secrets and providers that reference it, and to lease backends that use it as a bootstrap credential. fnox exec resolves it only when something it injects depends on it.
Secrets as files
Some tools want a path to a file, such as a service-account key or a TLS certificate. Set as_file = true, and the variable holds the path to a private temporary file instead of the value:
[secrets]
GOOGLE_APPLICATION_CREDENTIALS = { provider = "op", value = "GCP/key.json", as_file = true }fnox exec deletes the file when the command exits. To store a file's exact contents, including trailing newlines, use fnox set KEY --from-file path.
fnox get
Print one value to stdout:
fnox get DATABASE_URL
fnox get DATABASE_URL --profile stagingUse it in scripts that need a single value. For an as_file secret, get prints a file path. --base64-decode decodes a base64-encoded value before printing.
To check that secrets resolve without printing them, use fnox check --all.
fnox export
Write the resolved environment in another format, for tools that can't be wrapped in fnox exec:
fnox export # KEY=value (.env format)
fnox export --format shell # export KEY=value
fnox export --format json -o secrets.jsonFormats are env, shell, json, yaml, and toml. Output contains plaintext secrets, so prefer fnox exec when you can, and keep exported files out of git. Like the interactive shell, export skips env = "exec" and env = false secrets unless you pass --all.
See import and export for migrations between formats and providers.
fnox env --json
Tools that start processes themselves (mise, editors, test runners) can ask fnox for the environment as JSON rather than wrapping each command:
fnox env --json
fnox env --json --describe # keys and where they would be injected, no valuesThe output format is documented in the fnox env JSON reference.
See also
- Shell integration: load secrets when you
cdinto a project. - mise integration: wrap tasks with
fnox exec. fnox execreference: every flag.