// docs / configuration
Configuration
Openflow reads its configuration from a single .env file at
/opt/openflow/.env. The manager reads all of it; instance containers receive
only the subset they need, injected as environment variables at create time.
The .env file
The format is the conventional one: KEY=value per line, no shell quoting
around values, comments with #. Values containing spaces are passed through
as-is. .env.example in the repository is the canonical reference; copy it and
fill in the blanks.
Manager keys
Read once at startup. Changing any of these requires a manager restart.
| key | default | purpose |
|---|---|---|
DATABASE_URL | required | Postgres connection string |
ROOT_DOMAIN | required | apex domain, e.g. example.com |
MANAGER_URL | required | full URL the manager is served at; instance URLs derive from this |
SESSION_SECRET | required | 64-byte random; signs session cookies |
JWT_SECRET | required | 64-byte random; signs instance capability tokens |
PORT | 4071 | HTTP listener port |
NODE_ENV | production | set to development for the dev-login route |
DATA_PATH | ./data | where instance /data bind mounts live on the host |
BACKUP_PATH | ./data/backups | where scheduled backup tarballs land |
PORT_RANGE_START | 10000 | first host port handed out to instance containers |
PORT_RANGE_END | 11000 | last host port |
Optional integrations
ANTHROPIC_API_KEY | unset | enables the in-editor AI assistant |
AUDIT_SUMMARY_ENABLED | false | enables LLM-summarized audit log prose |
AUDIT_SUMMARY_MODEL | claude-haiku-4-5 | model used by the audit summarizer |
AUDIT_SUMMARY_DAILY_TOKEN_BUDGET | 2000000 | safety budget for the summarizer |
GOOGLE_OAUTH_CLIENT_ID | unset | enables Google sign-in |
GOOGLE_OAUTH_CLIENT_SECRET | unset | paired with the above |
Per-instance keys
Some values aren't read from .env at all but live on the instances
row in Postgres, set through the dashboard's instance settings. They're injected into the
container at create time, prefixed with OPENFLOW_.
| injected as | source |
|---|---|
OPENFLOW_INSTANCE_ID | the instance row id |
OPENFLOW_SUBDOMAIN | the instance's subdomain slug |
OPENFLOW_AUTH_URL | derived from MANAGER_URL |
OPENFLOW_MAGIC_TOKEN | per-instance master token, generated at create |
OPENFLOW_MQTT_HOST / _PORT | the shared EMQX broker |
OPENFLOW_MQTT_USERNAME / _PASSWORD | per-instance credentials, auto-provisioned |
OPENFLOW_MQTT_TOPIC_PREFIX | project mountpoint, e.g. openflow/<projectId>/ |
OPENFLOW_CREDENTIAL_SECRET | only set on migrated instances, decrypts their flows_cred.json |
OPENFLOW_PALETTE | space-separated npm specs the entrypoint installs before start |
User-defined env vars
Per-instance, set through the dashboard. The container receives them verbatim. Reserved
prefixes (OPENFLOW_, PATH, HOME, TZ,
NODE_PATH) are silently filtered to prevent shadowing platform configuration.
Secrets
SESSION_SECRETandJWT_SECRETshould be 64 raw bytes each, generated once at install. Rotating either of them invalidates all sessions and all in-flight instance capability tokens. Plan for it.ANTHROPIC_API_KEYcan be set in the manager.envor via the admin Settings tab. The Settings tab overrides the env var when both are set.- Database credentials are part of
DATABASE_URL. The manager doesn't accept them as separate keys.
Applying changes
- Manager-level keys take effect on the next process start:
systemctl restart openflow - Per-instance keys (palette, user env vars, resource limits) take effect on the next container start. The dashboard surfaces a "Restart needed" indicator after edits that require it.
- Some keys (e.g.
ROOT_DOMAINchange) also require a client rebuild AND a wildcard cert that covers both the apex and*.<new-root>. See install for the cert dance.