Secrets Management¶
Floh uses a pluggable SecretProvider interface to load sensitive configuration
values. The provider is selected at startup via the SECRETS_BACKEND environment
variable.
Backends¶
env (default)¶
Reads secrets from environment variables / .env files. This is the default
for local development — no additional setup required.
authifi¶
Fetches secrets from the Authifi tenant secrets vault at startup.
Authentication uses private_key_jwt (RFC 7523) so the only file-based
credential is an RSA private key.
Development Setup¶
No changes from the standard workflow. Leave SECRETS_BACKEND unset (or set
to env) and secrets are read from your .env file as before.
Production Setup (Authifi)¶
1. Generate an RSA key pair¶
Register the public key with the Authifi OAuth2 client that Floh will use for vault access.
2. Create secrets in Authifi¶
Using the Authifi admin API or UI, create tenant secrets with a FLOH_
prefix. Each secret name maps to the corresponding environment variable:
| Authifi secret name | Maps to |
|---|---|
FLOH_DB_PASSWORD |
DB_PASSWORD |
FLOH_JWT_SECRET |
JWT_SECRET |
FLOH_SESSION_SECRET |
SESSION_SECRET |
FLOH_OIDC_CLIENT_SECRET |
OIDC_CLIENT_SECRET |
FLOH_CONNECTOR_ENCRYPTION_KEY |
CONNECTOR_ENCRYPTION_KEY |
FLOH_SESSION_ENCRYPTION_KEY |
SESSION_ENCRYPTION_KEY |
FLOH_AUDIT_CHECKPOINT_KEY |
AUDIT_CHECKPOINT_KEY |
FLOH_REDIS_PASSWORD |
REDIS_PASSWORD |
FLOH_SMTP_USER |
SMTP_USER |
FLOH_SMTP_PASS |
SMTP_PASS |
3. Configure the Floh server¶
Set the following environment variables (these are non-secret bootstrap values):
SECRETS_BACKEND=authifi
AUTHIFI_VAULT_URL=https://auth.example.com/_api
AUTHIFI_VAULT_TENANT=my-tenant
AUTHIFI_VAULT_TENANT_ID=123
AUTHIFI_VAULT_CLIENT_ID=floh-vault-client
AUTHIFI_VAULT_KEY_FILE=/etc/floh/vault-key.pem
Mount the private key file into the container at the path specified by
AUTHIFI_VAULT_KEY_FILE.
4. Required Authifi client scopes¶
The OAuth2 client needs these scopes:
SECRETS_MANAGER.LIST— enumerate tenant secretsSECRETS_MANAGER.PLAIN_SECRET— retrieve decrypted values
No write scopes are needed; secrets are provisioned separately by tenant admins.
How It Works¶
- On startup,
createSecretProvider()readsSECRETS_BACKEND. - For
authifi, it loads the vault config from env vars and the RSA private key from disk. - A JWT assertion is signed and exchanged for an access token via the
Authifi token endpoint (
POST /{tenant}/oidc/token). - The provider lists all tenant secrets, filters by the
FLOH_prefix, and fetches the plaintext value for each. loadConfig()callsprovider.getSecret(key)for each sensitive field, falling back toprocess.envif the provider returns nothing.
Architecture¶
┌─────────────┐
│ loadConfig │
│ (async) │
└──────┬───────┘
│
▼
┌──────────────────┐
│ SecretProvider │◄── interface
└──────┬───────────┘
│
┌────┴────────────────┐
│ │
▼ ▼
┌──────────────┐ ┌─────────────────────┐
│ EnvSecret │ │ AuthifiSecret │
│ Provider │ │ Provider │
│ (process.env)│ │ (vault + JWT auth) │
└──────────────┘ └─────────────────────┘
Optional Configuration¶
| Variable | Default | Description |
|---|---|---|
AUTHIFI_VAULT_SECRET_PREFIX |
FLOH_ |
Prefix for filtering tenant secrets |
AUTHIFI_VAULT_SCOPE |
SECRETS_MANAGER.LIST SECRETS_MANAGER.PLAIN_SECRET |
OAuth2 scopes |
See Also¶
- Encryption Keys — AES-256-GCM keys for connector secrets, session data, and audit checkpoints
- Authifi Secret Manager API — look for the Tenant Secret Manager tag