The age provider can now pick one identity per machine from a shared config, read passphrase-protected identity files, and use a named table of recipients. fnox push adds an Azure Container Apps target that writes all of a target's variables in one request. This release also fixes op signin detection for 1Password and fnox sync caching for secrets that use a profile's default_provider.
Added
- Named age identities (#1099, #1100) by @jdx. One shared
fnox.tomlcan list an identity for each machine, for example one per YubiKey. Choose one withdefault_identity, or setFNOX_AGE_IDENTITYto override it on a given machine. An entry can be a key file path or a{ provider, value }reference, such as an age identity unlocked through thefido2provider:[providers.age] type = "age" recipients = ["age1...", "age1...", "age1..."] default_identity = "yk1" [providers.age.identities] yk1 = { provider = "fido2-yk1", value = "..." } yk2 = { provider = "fido2-yk2", value = "..." } recovery = "~/.config/fnox/recovery.txt"
- The selected identity replaces
key_file, oridentityfor provider-backed entries.FNOX_AGE_KEYstill takes precedence over everything. - fnox only calls the provider of the selected entry, so a machine never asks for another machine's key.
- An unknown name is an error that lists the available names. A table that mixes
secretwithprovider/valueis rejected. - Configs that don't set
identities,default_identityorFNOX_AGE_IDENTITYwork as before.
- The selected identity replaces
- Passphrase-encrypted age identity files (#1097) by @jdx.
key_filecan now point at an identity created withage-keygen | age -p -o identity.age, in binary or armored form. When fnox decrypts a secret, it prompts for the passphrase once per file in each run.fnox setonly uses the public recipients, so it never prompts. Without a terminal, fnox fails with an auth error that suggests decrypting the identity and settingFNOX_AGE_KEY. The daemon does not cache the passphrase, and no environment variable can supply it. - Named age recipients (#1104) by @jdx.
recipientscan now be a table, so you can see whose key each entry is:Secrets are encrypted to every key, in the order written. The names are only labels, so renaming one doesn't require[providers.age.recipients] desktop = "age1..." laptop = "age1..." recovery = "age1..."
fnox reencrypt. The array form still works. azure-container-appspush target (#1098) by @jdx.fnox pushcan now set environment variables on an Azure Container App through the ARM REST API. It uses the same credentials asazure-smandazure-ac: service principal environment variables, anaz/azdlogin, or a managed identity. Values never appear on a command line.[targets.api] type = "azure-container-apps" subscription = "00000000-0000-0000-0000-000000000000" resource_group = "rg-dev" app = "ca-api-dev" # container = "api" # required if the app has several containers
- Every env change creates a new revision, so fnox writes all of a target's variables in one request. If every value already matches, it writes nothing.
- Variables that fnox doesn't push, and the app's
secrets, are left alone. A pushed variable is stored as a plainvalueand replaces any existing variable with the same name, including one that used asecretRef. - When Azure provides an
ETag, the write is conditional, so a concurrent change to the app causes the push to fail instead of being overwritten. fnox polls long-running updates for up to five minutes but doesn't wait for the new revision to become ready. Only the public cloud is supported. fnox pushnow groups writes by target, so output lines are ordered by target. If a batch fails, every variable in it is reported as failed.
Fixed
- 1Password: When
opreports "You are not currently signed in", fnox now treats it as an authentication failure. In a terminal, it offers to runop signinand then retries. Otherwise, it shows theop signinhint. Item, vault or field names containing words like "authorization" no longer cause unrelated failures to be reported as sign-in errors. (#1102) by @djgoku - Sync:
fnox syncnow caches secrets that have avaluebut noproviderand are read through the profile'sdefault_provider. Before,--local-fileskipped them, so they kept calling the remote provider and failed offline. The same rule now applies to--source, the "from" labels, and the cleanup of stale cache entries. (#1106) by @jdx
New Contributors
Full Changelog: v1.46.0...v1.47.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.