Skip to main content

Configuration

DaoFlow is configured through environment variables and a CLI config file.

Environment Variables​

Local Development​

VariableDescription
DATABASE_URLPostgreSQL connection string
BETTER_AUTH_URLPublic-facing URL of the DaoFlow instance
BETTER_AUTH_SECRETOptional locally, required in production
ENCRYPTION_KEYOptional locally, at least 32 characters in production
DAOFLOW_BACKUP_DESTINATION_ENCRYPTION_KEYOptional destination-only key; defaults to ENCRYPTION_KEY
DAOFLOW_PREVIOUS_BACKUP_DESTINATION_ENCRYPTION_KEYTemporary old destination key used during rotation
DAOFLOW_RECOVERY_ENCRYPTION_KEYSeparate external key used to encrypt control-plane recovery bundles
DAOFLOW_PREVIOUS_RECOVERY_ENCRYPTION_KEYTemporary old recovery key used during rotation
DAOFLOW_RCLONE_COMMAND_TIMEOUT_MSRecovery-object transfer timeout in milliseconds
APPROVAL_ACTION_DISPATCH_POLL_INTERVAL_MSDurable approved-operation monitor interval in milliseconds
DAOFLOW_APPROVAL_DISPATCH_MAX_ATTEMPTSMaximum automatic submission attempts
DAOFLOW_APPROVAL_DISPATCH_RETRY_BASE_MSInitial approved-operation retry window in milliseconds
DAOFLOW_APPROVAL_DISPATCH_RETRY_MAX_MSMaximum approved-operation retry window in milliseconds
PROVIDER_FEEDBACK_POLL_INTERVAL_MSProvider-feedback monitor interval in milliseconds
DAOFLOW_PROVIDER_FEEDBACK_MAX_ATTEMPTSMaximum feedback-delivery attempts before dead-lettering
DAOFLOW_PROVIDER_FEEDBACK_RETRY_BASE_MSInitial provider-feedback retry delay in milliseconds
DAOFLOW_PROVIDER_FEEDBACK_RETRY_MAX_MSMaximum provider-feedback retry delay in milliseconds
DAOFLOW_CONTROL_PLANE_RECOVERY_VERIFIER_STORAGE_MBIsolated recovery verifier limit in megabytes

Production .env​

The generated production .env file is intentionally smaller than the runtime environment inside the container. The compose stack derives DATABASE_URL, REDIS_URL, and most container-local defaults internally.

Most operators edit only these values:

VariableDefaultDescription
DAOFLOW_VERSION0.11.0 in reference ComposeConcrete image tag to run; the installer-generated .env pins the installed CLI release
BETTER_AUTH_URL—Public origin used for sign-in and callbacks
DAOFLOW_DATABASE_NAMEdaoflowDatabase selected by the production Compose DATABASE_URL; keep the default for a standard install
DAOFLOW_PORT3000Host port bound to the DaoFlow container
BETTER_AUTH_SECRET—Production session signing secret
ENCRYPTION_KEY—Global DaoFlow secret-encryption key; keep it unchanged during destination-key rotation
DAOFLOW_BACKUP_DESTINATION_ENCRYPTION_KEYunsetCurrent backup-destination key; falls back to ENCRYPTION_KEY
DAOFLOW_PREVIOUS_BACKUP_DESTINATION_ENCRYPTION_KEYunsetTemporary old backup-destination key used only during rotation
DAOFLOW_RECOVERY_ENCRYPTION_KEYunsetDedicated recovery-bundle encryption key; store it outside the control-plane database
DAOFLOW_PREVIOUS_RECOVERY_ENCRYPTION_KEYunsetTemporary previous recovery key during a controlled key rotation
DAOFLOW_RCLONE_COMMAND_TIMEOUT_MS1800000Maximum time for one recovery-object transfer
APPROVAL_ACTION_DISPATCH_POLL_INTERVAL_MS5000Poll interval for durable approved-operation submission and completion checks
DAOFLOW_APPROVAL_DISPATCH_MAX_ATTEMPTS12Automatic submission attempts before a dispatch reaches terminal failure
DAOFLOW_APPROVAL_DISPATCH_RETRY_BASE_MS1000Initial full-jitter retry window for a temporary submission failure
DAOFLOW_APPROVAL_DISPATCH_RETRY_MAX_MS300000Maximum full-jitter retry window for a temporary submission failure
SERVER_METRICS_MONITOR_POLL_INTERVAL_MS15000Poll interval for selecting servers whose metric policy is due
SERVER_METRICS_MONITOR_CONCURRENCY4Maximum concurrent read-only server metric collections, from 1 to 16
PROVIDER_FEEDBACK_POLL_INTERVAL_MS5000Poll interval for provider-feedback delivery; stays idle until an adapter is installed
DAOFLOW_PROVIDER_FEEDBACK_MAX_ATTEMPTS12Automatic feedback-delivery attempts before an item is dead-lettered
DAOFLOW_PROVIDER_FEEDBACK_RETRY_BASE_MS1000Initial bounded exponential retry delay for a temporary provider failure
DAOFLOW_PROVIDER_FEEDBACK_RETRY_MAX_MS300000Maximum provider-feedback retry delay
DAOFLOW_CONTROL_PLANE_RECOVERY_VERIFIER_STORAGE_MB4096Storage and memory ceiling for each isolated recovery verifier
POSTGRES_PASSWORD—Password for the DaoFlow application database
TEMPORAL_POSTGRES_PASSWORD—Password for Temporal's Postgres database
DEPLOY_TIMEOUT_MS86400000Max queue-wait and execution time; expiry aborts active work
DAOFLOW_ENABLE_TEMPORALfalseEnables durable Temporal-backed orchestration
TEMPORAL_NAMESPACEdaoflowTemporal namespace when Temporal mode is enabled
TEMPORAL_TASK_QUEUEdaoflow-deploymentsTemporal task queue name

Rotating Backup-Destination Credentials​

The destination key is separate from the global ENCRYPTION_KEY. Leave ENCRYPTION_KEY unchanged so other DaoFlow secrets continue to use the same key.

  1. Set DAOFLOW_BACKUP_DESTINATION_ENCRYPTION_KEY to the new destination key. If it is unset, the destination key defaults to ENCRYPTION_KEY.

  2. Temporarily set DAOFLOW_PREVIOUS_BACKUP_DESTINATION_ENCRYPTION_KEY to the old destination key.

  3. Restart DaoFlow or run migration-only mode:

    docker compose run --rm -e DAOFLOW_RUN_MIGRATIONS_ONLY=true daoflow

    Startup verifies every backup-destination envelope, re-encrypts it transactionally with the current destination key, and clears legacy plaintext secrets. Mixed or undecryptable state fails closed; a failed rotation commits no partial changes.

  4. Confirm /ready is healthy and run a connection test for every backup destination before removing the previous key.

  5. Remove DAOFLOW_PREVIOUS_BACKUP_DESTINATION_ENCRYPTION_KEY and restart.

If migration fails before commit, restore the old value as DAOFLOW_BACKUP_DESTINATION_ENCRYPTION_KEY (or unset it if it previously inherited ENCRYPTION_KEY), remove the temporary previous-key variable, and restart. Do not change the global ENCRYPTION_KEY for this rollback.

Control-plane Recovery Key​

DAOFLOW_RECOVERY_ENCRYPTION_KEY is independent of both ENCRYPTION_KEY and the backup-destination key. Generate it with openssl rand -hex 32 and keep it in an external secret manager. DaoFlow stores only its fingerprint and rotation timestamp. If the key is rotated, supply the old value as DAOFLOW_PREVIOUS_RECOVERY_ENCRYPTION_KEY for the migration window, verify a new recovery plan, then remove the previous key. Losing this external key makes encrypted recovery bundles unreadable.

Initial Owner Bootstrap​

These variables are optional, but when both are set DaoFlow bootstraps the first owner account on first start:

VariableDescription
DAOFLOW_INITIAL_ADMIN_EMAILEmail for the first owner account
DAOFLOW_INITIAL_ADMIN_PASSWORDPassword for the first owner account

The CLI install flow also reads these same variables when --email and --password are omitted, then writes them into the generated server .env file.

The environment-created owner is also assigned an owner organization membership and a default organization before localhost server registration. On restart, DaoFlow repairs an older environment-created owner that is missing organization membership, while preserving any valid default organization that is already configured.

Offline clean-install restore​

The offline restore contract uses daoflow backup recovery restore with a local bundle, signed manifest, external secrets file, and a new --database-name. Start with --dry-run --json, then run the exact returned plan with --confirm <exact-plan-hash> --yes --json. The full command options are --dir, --bundle, --manifest, --external-secrets, --database-name, --dry-run, --confirm, --yes, and --json.

Set the external secrets file to mode 600. It needs BETTER_AUTH_SECRET, ENCRYPTION_KEY, DAOFLOW_RECOVERY_ENCRYPTION_KEY, any manifest-required optional key, DAOFLOW_RECOVERY_VERIFY_EMAIL, and DAOFLOW_RECOVERY_VERIFY_PASSWORD. The restore targets a new database, retains the original database and configuration, and rolls the configuration back automatically if post-start verification fails. Clean up only a failed target database before a retry. See Control-plane Recovery Bundles for the operator sequence.

For the full production variable reference, including SMTP and advanced worker settings, see Self-Hosting Environment Variables.

CLI Configuration​

The CLI stores its configuration in ~/.daoflow/config.json:

{
"currentContext": "default",
"contexts": {
"default": {
"apiUrl": "http://localhost:3000",
"token": "your-api-token",
"authMethod": "api-token"
}
}
}

The CLI also supports DAOFLOW_URL and DAOFLOW_TOKEN as environment-based auth for CI and agent workflows. Set both together; if either one is missing, the CLI now fails closed instead of silently falling back to the saved config context.

Setting CLI Defaults​

# Set the API URL
daoflow login --url https://your-instance.com --token YOUR_TOKEN

# For non-interactive automation
export DAOFLOW_URL=https://your-instance.com
export DAOFLOW_TOKEN=YOUR_TOKEN

# For fresh installs, preseed the first owner
export DAOFLOW_INITIAL_ADMIN_EMAIL=owner@your-instance.com
export DAOFLOW_INITIAL_ADMIN_PASSWORD=replace-this-secret

Server Configuration​

Each registered deployment server has configurable settings in the dashboard or admin API:

SettingDefaultDescription
SSH Host—IP address or hostname
SSH Port22SSH port
SSH Private Key—Stored SSH private key material
Target Server Name—Stable name used by deploy plans
Docker Socket/var/run/docker.sockDocker socket on the managed host

Security Configuration​

See the Security & RBAC guide for configuring:

  • User roles and permissions
  • API token scopes
  • Agent principal accounts
  • Audit log retention