Connect a vault and cache locally
Keep secrets in 1Password, commit their references in fnox.toml, and use fnox sync to create an encrypted personal cache. Daily reads then use your local age key without contacting 1Password. This is the golden path for teams with an existing vault.
The same recipe works with any remote provider — swap 1Password for AWS Secrets Manager, Bitwarden, Doppler, or any other remote provider.
Prerequisites
- fnox installed
- The 1Password CLI installed and signed in (
op signin) ageinstalled (brew install age/apt install age)
Step 1: one-time machine setup
Create a personal age key and a machine-wide sync-age provider. You do this once per machine, then reuse it in every project:
# Generate your personal age key
mkdir -p ~/.config/fnox
age-keygen -o ~/.config/fnox/age.txt
# Add the machine-wide provider, then replace its age1... placeholder
# with the "public key:" line from ~/.config/fnox/age.txt
fnox provider add sync-age age --global
"${EDITOR:-vi}" "${FNOX_CONFIG_DIR:-$HOME/.config/fnox}/config.toml"Point the provider at your key file so decryption works without any environment setup:
# ~/.config/fnox/config.toml
[providers.sync-age]
type = "age"
recipients = ["age1..."] # your public key
key_file = "~/.config/fnox/age.txt"Harden it with hardware
Instead of a key file on disk, the age key can live in Apple's Secure Enclave (Touch ID), a YubiKey, or a TPM or FIDO2 token. Only this step changes — everything below stays the same.
Step 2: put secrets in 1Password
The vault is the single source of truth. Use existing items, or create them:
op item create --category=login --vault=Engineering --title=Database \
'url=postgresql://db.example.com/myapp'
op item create --category=login --vault=Engineering --title=Stripe \
'secret-key=sk_live_...'Step 3: commit references in fnox.TOML
In the project, reference the 1Password items — no secret material goes into git:
cd my-api
fnox init --skip-wizard# fnox.toml (committed)
[providers.op]
type = "1password"
vault = "Engineering"
[secrets]
DATABASE_URL = { provider = "op", value = "Database/url" }
STRIPE_KEY = { provider = "op", value = "Stripe/secret-key" }Make sure the local cache never gets committed:
echo "fnox.local.toml" >> .gitignore
git add fnox.toml .gitignore
git commit -m "chore: add fnox config"Step 4: sync
Pull every secret from 1Password once and cache it locally, re-encrypted to your personal age key:
fnox sync --provider sync-age --local-fileThis writes the encrypted values into the gitignored fnox.local.toml. From now on fnox decrypts locally instead of calling 1Password — see Syncing Secrets Locally for exactly what this looks like on disk.
Step 5: enable shell integration
# Add to your shell profile
eval "$(fnox activate zsh)"For other shells and startup file locations, see shell integration. Entering the project now loads secrets from the local cache:
~/projects $ cd my-api
fnox: +2 DATABASE_URL, STRIPE_KEY
~/projects/my-api $Keep the cache current
The cache does not refresh automatically. After a secret changes in 1Password, re-sync:
fnox sync --provider sync-age --local-file --forceOnboard a teammate: grant vault access, then have them complete Step 1 on their machine, clone the repo, and run Step 4. Their cache is encrypted to their own key — nothing is shared except the vault.
Add a secret: Add the item to 1Password, add its reference to fnox.toml, commit, and everyone re-syncs.
What about CI?
In CI, authenticate to the vault directly. Install fnox and the 1Password CLI before this workflow step:
# GitHub Actions
- name: Run tests
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
run: fnox exec -- npm testThe committed fnox.toml references resolve straight from 1Password using the service account token. Alternatively, keep a separate set of age-encrypted secrets in git for CI.
Next steps
- Syncing Secrets Locally - Everything
fnox synccan do, including hardware-backed keys - Real-World Setup - An alternative workflow with encrypted secrets in git
- Profiles - Different secrets for dev, staging, and production
- Credential Leases - Short-lived credentials from long-lived masters