Skip to content

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

openssl genrsa -out vault-key.pem 2048
openssl rsa -in vault-key.pem -pubout -out vault-key.pub

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 secrets
  • SECRETS_MANAGER.PLAIN_SECRET — retrieve decrypted values

No write scopes are needed; secrets are provisioned separately by tenant admins.


How It Works

  1. On startup, createSecretProvider() reads SECRETS_BACKEND.
  2. For authifi, it loads the vault config from env vars and the RSA private key from disk.
  3. A JWT assertion is signed and exchanged for an access token via the Authifi token endpoint (POST /{tenant}/oidc/token).
  4. The provider lists all tenant secrets, filters by the FLOH_ prefix, and fetches the plaintext value for each.
  5. loadConfig() calls provider.getSecret(key) for each sensitive field, falling back to process.env if 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