Skip to main content
A common need is to authenticate a Flox environment to external services—for example, a GitHub account or a database password inside a project environment. Secrets should never be hardcoded in a manifest.toml file. Hard-coded secrets could end up committed to git, visible in shell history, and cannot be rotated without editing the manifest. Dotenv files have similar issues. A secure pattern is to keep secrets in a secret store and retrieve them just-in-time during flox activate, exporting them as environment variables that live only while the environment is active.

The JIT secrets pattern

The pattern has three phases:

1. Primary auth (once per session)

A human authenticates once to a secret store using a primary credential (biometric, SSO session, password, etc.). This grants a session or token that the retrieval step will use. This is the human-in-the-loop gate—it makes secret access auditable and revocable.

2. Secret retrieval (plugin or hook)

Two mechanisms retrieve secrets at shell activation time:
  • Secrets plugins (flox 1.14.0 or later) — install a plugin package for your secret store and declare which secrets you need in a [plugins.<name>] table in manifest.toml. The plugin bundles the store’s CLI together with the retrieval script, so one package delivers both.
  • on-activate hook — for stores without a plugin, call the store’s CLI yourself from the on-activate hook in .flox/env/manifest.toml.
Either way the store validates the active session before returning values, and the manifest carries only references to where secrets live—never the values themselves. See Activating environments for more about hooks.

3. Scoped env var injection

Retrieved secrets are exported as environment variables. They exist only in the active Flox shell and are gone when the shell exits. They are never written to the project directory, the manifest, or git.

Key security properties

  • Not in manifest — secret values are never written to manifest.toml
  • Not committed to git — the manifest is safe to commit; it contains only retrieval instructions, not values
  • Not in dotenv files — no .env file to accidentally expose
  • Not in shell history — retrieval runs non-interactively during activation
  • Auditable — the secret store logs each access
  • Rotatable — update the value in the store; the manifest never changes
  • Scoped — credentials are per-environment, not global

Secrets plugins

A secrets plugin is an ordinary package that ships the store’s CLI plus a script Flox runs during activation (dev and build modes; in build mode the sandboxed script skips network lookups). The script reads this plugin’s [plugins.<name>] table from the manifest and exports one environment variable per entry. Plugins exist for 1Password, HashiCorp Vault, OpenBao, and Infisical. The packages are currently built from the flox-plugins repository—run flox build in the plugin’s directory and flox install the resulting store path (each plugin’s README walks through it):
The [plugins] manifest section requires flox 1.14.0 or later. A reference that fails to resolve (missing secret, expired session) prints a warning and leaves that variable unset—activation still succeeds, and the store CLI’s own error output passes through so you can act on it.

Implementation examples

Install the _1password plugin package, then declare the secrets the environment needs:
References are 1Password secret references (vault/item/field, with or without the op:// prefix).Requires an active op session: op signin, the desktop-app integration with biometric approval, or OP_SERVICE_ACCOUNT_TOKEN in non-interactive contexts (CI, servers).See the Flox + 1Password blog post for a hook-based walkthrough of the same store.

Rotating a secret

Because the value lives in the store, not the manifest, rotation requires no manifest changes:
  1. Generate a new secret at the issuer.
  2. Update the secret store.
The next flox activate automatically uses the new value. No PR, no teammate notification, no dotenv sync required.
If a Flox shell is already active when rotation happens, the old value remains set in that running shell. The new value takes effect on the next fresh flox activate (re-attaching to a still-cached activation replays the previously fetched values). If rotation is in response to a credential compromise, kill active shells explicitly.
Finally, revoke the old token at the issuer once no more environments are active with the old secret value.

Secret store reference

Further reading