Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration Reference

Complete reference for Horizon Epoch configuration options.

Configuration Sources

Configuration is loaded from (in order of precedence):

  1. Command-line arguments (highest priority)
  2. Environment variables
  3. Local repository configuration (.epoch/config)
  4. Configuration file (epoch.toml)
  5. Default values (lowest priority)

Configuration File Search Order

The CLI searches for configuration files in this order:

  1. ./epoch.toml (current directory)
  2. ./config/epoch.toml
  3. ./.epoch/config.toml
  4. ~/.config/epoch/config.toml
  5. /etc/epoch/config.toml

The first file found is used. Override with --config or EPOCH_CONFIG_FILE.

Configuration File

Default location: ~/.epoch/config.toml or ./epoch.toml

Full Example

# epoch.toml

[metadata]
url = "postgresql://localhost/horizon_epoch"
pool_size = 10
connect_timeout = 30

[defaults]
branch = "main"
author_name = "Your Name"
author_email = "you@example.com"
format = "text"

[logging]
level = "info"
format = "pretty"  # or "json"
file = "/var/log/epoch/epoch.log"

# PostgreSQL storage backends
[storage.postgres.production]
url = "postgresql://user:pass@prod-db.example.com/production"
pool_size = 20
connect_timeout = 30

[storage.postgres.staging]
host = "staging-db.example.com"
port = 5432
database = "staging"
username = "epoch_user"
password_file = "/run/secrets/db-password"
sslmode = "verify-full"
ssl_rootcert = "/etc/ssl/certs/ca.crt"

[storage.postgres.secure]
host = "secure-db.internal"
database = "secure"
vault_path = "secret/data/secure-db"

[storage.postgres.secure.ssh_tunnel]
host = "bastion.example.com"
user = "ubuntu"
key_file = "~/.ssh/id_rsa"

# S3 storage backends
[storage.s3.datalake]
bucket = "company-datalake"
region = "us-east-1"
prefix = "horizon-epoch/"

[storage.s3.partner]
bucket = "partner-shared"
region = "us-west-2"
assume_role_arn = "arn:aws:iam::123456789012:role/PartnerAccess"
external_id = "partner-123"

[storage.s3.minio]
bucket = "local-data"
endpoint = "http://localhost:9000"
access_key = "minioadmin"
secret_key = "minioadmin"
force_path_style = true

# Vault integration
[vault]
addr = "https://vault.example.com:8200"
auth_method = "approle"
role_id = "xxx-xxx-xxx"
secret_id_file = "/run/secrets/vault-secret-id"
ca_cert = "/etc/ssl/certs/vault-ca.crt"

# AWS integration
[aws]
region = "us-east-1"
profile = "production"

# Credential caching
[credentials]
cache_enabled = true
cache_ttl = 300
refresh_before_expiry = 60

Environment Variables

All configuration can be set via environment variables with EPOCH_ prefix:

Core Settings

VariableDescriptionDefault
EPOCH_METADATA_URLMetadata database URL-
DATABASE_URLFallback for metadata URL (SQLx compatible)-
EPOCH_CONFIG_FILEConfig file path~/.epoch/config.toml
EPOCH_DEFAULT_BRANCHDefault branch namemain
EPOCH_FORMATOutput formattext

Author Settings

VariableDescriptionDefault
EPOCH_AUTHOR_NAMEDefault author name for commitsgit config user.name
EPOCH_AUTHOR_EMAILDefault author email for commitsgit config user.email

Author information is resolved in this priority order:

  1. Command-line arguments (--author-name, --author-email)
  2. Environment variables (EPOCH_AUTHOR_NAME, EPOCH_AUTHOR_EMAIL)
  3. Local repository config (.epoch/config)
  4. Git configuration (git config user.name, git config user.email)

Editor Settings

VariableDescriptionDefault
EPOCH_EDITOREditor for interactive operations-
EDITORFallback editor-
VISUALSecondary fallback editor-

Editor is selected in priority order: EPOCH_EDITOR > EDITOR > VISUAL > platform default (vi on Unix, notepad.exe on Windows).

Commit Signing

VariableDescriptionDefault
EPOCH_SIGNING_KEYPath to signing key file (ASCII-armored)-
EPOCH_SIGNING_KEY_PASSWORDPassword for signing key- (prompts)

Logging

VariableDescriptionDefault
EPOCH_LOG_LEVELLog level (error/warn/info/debug/trace)info
EPOCH_LOG_FORMATLog format (pretty/json)pretty
EPOCH_LOG_FILELog file path-
RUST_LOGRust logging filter (module=level format)-

API Server

VariableDescriptionDefault
EPOCH_API_HOSTAPI server bind address0.0.0.0
EPOCH_API_PORTAPI server port8000
EPOCH_API_PREFIXAPI route prefix/api/v1
EPOCH_DEBUGEnable debug mode (exposes Swagger UI)false
EPOCH_SERVER_URLRemote server URL for CLI-

OAuth/OIDC Authentication

VariableDescription
EPOCH_OAUTH_CLIENT_IDDefault OAuth client ID
EPOCH_OAUTH_CLIENT_SECRETDefault OAuth client secret
EPOCH_OAUTH_{PROVIDER}_CLIENT_IDProvider-specific client ID
EPOCH_OAUTH_{PROVIDER}_CLIENT_SECRETProvider-specific client secret
EPOCH_OAUTH_OIDC_ISSUEROIDC issuer URL for custom provider

Supported providers: GITHUB, GOOGLE, AZURE, OKTA, OIDC (custom).

Example:

# GitHub OAuth
export EPOCH_OAUTH_GITHUB_CLIENT_ID="your-client-id"
export EPOCH_OAUTH_GITHUB_CLIENT_SECRET="your-client-secret"
epoch auth login --method oauth --provider github

# Custom OIDC provider
export EPOCH_OAUTH_CLIENT_ID="your-client-id"
export EPOCH_OAUTH_OIDC_ISSUER="https://your-idp.example.com"
epoch auth login --method oauth --provider oidc

PostgreSQL

VariableDescription
EPOCH_POSTGRES_{NAME}_URLFull connection URL
EPOCH_POSTGRES_{NAME}_HOSTDatabase host
EPOCH_POSTGRES_{NAME}_PORTDatabase port
EPOCH_POSTGRES_{NAME}_DATABASEDatabase name
EPOCH_POSTGRES_{NAME}_USERNAMEUsername
EPOCH_POSTGRES_{NAME}_PASSWORDPassword
EPOCH_POSTGRES_{NAME}_SSLMODESSL mode

S3

VariableDescription
EPOCH_S3_{NAME}_BUCKETBucket name
EPOCH_S3_{NAME}_REGIONAWS region
EPOCH_S3_{NAME}_ENDPOINTCustom endpoint
EPOCH_S3_{NAME}_ACCESS_KEYAccess key ID
EPOCH_S3_{NAME}_SECRET_KEYSecret access key
AWS_ACCESS_KEY_IDDefault AWS access key
AWS_SECRET_ACCESS_KEYDefault AWS secret key
AWS_DEFAULT_REGIONDefault AWS region

MySQL

VariableDescription
EPOCH_MYSQL_{NAME}_URLFull connection URL
EPOCH_MYSQL_{NAME}_HOSTDatabase host
EPOCH_MYSQL_{NAME}_PORTDatabase port
EPOCH_MYSQL_{NAME}_DATABASEDatabase name
EPOCH_MYSQL_{NAME}_USERNAMEUsername
EPOCH_MYSQL_{NAME}_PASSWORDPassword

SQL Server

VariableDescription
EPOCH_MSSQL_{NAME}_URLFull connection URL
EPOCH_MSSQL_{NAME}_HOSTDatabase host
EPOCH_MSSQL_{NAME}_PORTDatabase port
EPOCH_MSSQL_{NAME}_DATABASEDatabase name
EPOCH_MSSQL_{NAME}_USERNAMEUsername
EPOCH_MSSQL_{NAME}_PASSWORDPassword

SQLite

VariableDescription
EPOCH_SQLITE_{NAME}_PATHDatabase file path

Azure Blob Storage

VariableDescription
EPOCH_AZURE_{NAME}_ACCOUNTStorage account name
EPOCH_AZURE_{NAME}_CONTAINERContainer name
EPOCH_AZURE_{NAME}_CONNECTION_STRINGConnection string
EPOCH_AZURE_{NAME}_ACCESS_KEYStorage access key
AZURE_TENANT_IDAzure AD tenant ID
AZURE_CLIENT_IDAzure AD client ID
AZURE_CLIENT_SECRETAzure AD client secret

Google Cloud Storage

VariableDescription
EPOCH_GCS_{NAME}_BUCKETBucket name
EPOCH_GCS_{NAME}_PROJECTGCP project ID
GOOGLE_APPLICATION_CREDENTIALSService account key file path

Local Filesystem

VariableDescription
EPOCH_LOCAL_{NAME}_PATHBase directory path

Vault

VariableDescription
VAULT_ADDRVault server address
VAULT_TOKENVault token
VAULT_ROLE_IDAppRole role ID
VAULT_SECRET_IDAppRole secret ID

SSH

VariableDescription
EPOCH_SSH_HOSTSSH tunnel host
EPOCH_SSH_USERSSH username
EPOCH_SSH_KEY_FILESSH private key path
SSH_AUTH_SOCKSSH agent socket

Configuration Sections

[metadata]

Metadata database configuration.

OptionTypeDefaultDescription
urlstring-PostgreSQL connection URL
pool_sizeint10Connection pool size
connect_timeoutint30Connection timeout (seconds)
idle_timeoutint600Idle connection timeout
max_lifetimeint3600Max connection lifetime

[defaults]

Default values for operations.

OptionTypeDefaultDescription
branchstring“main”Default branch
author_namestring-Default author name
author_emailstring-Default author email
formatstring“text”Output format

[logging]

Logging configuration.

OptionTypeDefaultDescription
levelstring“info”Log level
formatstring“pretty”Log format
filestring-Log file path
jsonboolfalseJSON log format

[storage.postgres.{name}]

PostgreSQL backend configuration.

OptionTypeDefaultDescription
urlstring-Full connection URL
hoststring-Database host
portint5432Database port
databasestring-Database name
usernamestring-Username
passwordstring-Password
password_filestring-Password file path
sslmodestring“prefer”SSL mode
ssl_certstring-Client certificate
ssl_keystring-Client key
ssl_rootcertstring-CA certificate
pool_sizeint10Pool size
connect_timeoutint30Timeout
vault_pathstring-Vault secret path
vault_rolestring-Vault dynamic role
aws_secret_idstring-AWS Secrets Manager ID
use_iam_authboolfalseUse RDS IAM auth

[storage.postgres.{name}.ssh_tunnel]

SSH tunnel configuration for PostgreSQL.

OptionTypeDefaultDescription
hoststring-Bastion host
portint22SSH port
userstring-SSH username
key_filestring-Private key path
key_passphrasestring-Key passphrase
use_agentboolfalseUse SSH agent
known_hosts_filestring-Known hosts file
strict_host_key_checkingbool/stringtrueHost key checking
keepalive_intervalint60Keepalive interval
connect_timeoutint30Connection timeout
auto_reconnectbooltrueAuto-reconnect

[storage.s3.{name}]

S3 backend configuration.

OptionTypeDefaultDescription
bucketstring-Bucket name
regionstring-AWS region
endpointstring-Custom endpoint
prefixstring“”Key prefix
access_keystring-Access key ID
secret_keystring-Secret access key
session_tokenstring-Session token
force_path_styleboolfalsePath-style URLs
use_instance_credentialsboolfalseUse instance profile
assume_role_arnstring-Role to assume
external_idstring-External ID
vault_pathstring-Vault secret path
aws_secret_idstring-Secrets Manager ID

[storage.mysql.{name}]

MySQL backend configuration.

OptionTypeDefaultDescription
urlstring-Full connection URL
hoststring-Database host
portint3306Database port
databasestring-Database name
usernamestring-Username
passwordstring-Password
password_filestring-Password file path
ssl_modestring“preferred”SSL mode
ssl_castring-CA certificate
pool_sizeint10Pool size
connect_timeoutint30Timeout
vault_pathstring-Vault secret path

[storage.mysql.{name}.ssh_tunnel]

SSH tunnel configuration for MySQL (same options as PostgreSQL).

[storage.mssql.{name}]

SQL Server backend configuration.

OptionTypeDefaultDescription
urlstring-Full connection URL
hoststring-Database host
portint1433Database port
databasestring-Database name
usernamestring-Username
passwordstring-Password
password_filestring-Password file path
trust_certboolfalseTrust server certificate
encryptbooltrueEncrypt connection
pool_sizeint10Pool size
connect_timeoutint30Timeout
vault_pathstring-Vault secret path
use_windows_authboolfalseUse Windows auth

[storage.sqlite.{name}]

SQLite backend configuration.

OptionTypeDefaultDescription
pathstring-Database file path
modestring“rwc”Open mode (r/rw/rwc)
in_memoryboolfalseUse in-memory database
busy_timeoutint5000Busy timeout (ms)
journal_modestring“wal”Journal mode

[storage.azure.{name}]

Azure Blob Storage backend configuration.

OptionTypeDefaultDescription
accountstring-Storage account name
containerstring-Container name
prefixstring“”Blob prefix
auth_methodstring“connection_string”Auth method
connection_stringstring-Connection string
access_keystring-Storage access key
sas_tokenstring-SAS token
tenant_idstring-Azure AD tenant ID
client_idstring-Azure AD client ID
client_secretstring-Azure AD client secret
use_managed_identityboolfalseUse managed identity
vault_pathstring-Vault secret path

[storage.gcs.{name}]

Google Cloud Storage backend configuration.

OptionTypeDefaultDescription
bucketstring-Bucket name
project_idstring-GCP project ID
prefixstring“”Object prefix
auth_methodstring“service_account”Auth method
credentials_filestring-Service account key file
use_adcboolfalseUse Application Default Credentials
vault_pathstring-Vault secret path

[storage.local.{name}]

Local filesystem backend configuration.

OptionTypeDefaultDescription
pathstring-Base directory path
create_dirsbooltrueCreate directories if missing

[vault]

HashiCorp Vault configuration.

OptionTypeDefaultDescription
addrstring-Vault address
tokenstring-Vault token
auth_methodstring“token”Auth method
role_idstring-AppRole role ID
secret_idstring-AppRole secret ID
secret_id_filestring-Secret ID file
rolestring-K8s/AWS role
ca_certstring-CA certificate
skip_verifyboolfalseSkip TLS verify
namespacestring-Vault namespace

[aws]

AWS configuration.

OptionTypeDefaultDescription
regionstring-Default region
profilestring-AWS profile
access_key_idstring-Access key
secret_access_keystring-Secret key

[credentials]

Credential caching configuration.

OptionTypeDefaultDescription
cache_enabledbooltrueEnable caching
cache_ttlint300Cache TTL (seconds)
cache_max_sizeint100Max cache entries
refresh_before_expiryint60Refresh threshold

Variable Substitution

Environment variables can be referenced in config:

[storage.postgres.production]
password = "${DB_PASSWORD}"

File contents can be referenced:

[storage.postgres.production]
password = "@file:/run/secrets/db-password"

Profiles

Multiple profiles can be defined:

[profiles.development]
metadata.url = "postgresql://localhost/horizon_epoch_dev"

[profiles.production]
metadata.url = "postgresql://prod-db/horizon_epoch"

Switch profiles:

epoch --profile production status

Local Repository Configuration

When you initialize a repository with epoch init, a .epoch/ directory is created with local configuration.

Directory Structure

.epoch/
├── config          # Repository configuration (TOML)
├── HEAD            # Current branch reference
└── refs/
    ├── heads/      # Branch references
    └── tags/       # Tag references

Local Config File (.epoch/config)

# Repository identity
repository_name = "my-data-repo"
repository_id = "550e8400-e29b-41d4-a716-446655440000"

# Metadata database connection
metadata_url = "postgresql://localhost/horizon_epoch"

# Current branch (also tracked in HEAD file)
current_branch = "main"

# Author information (optional, overrides global config)
[author]
name = "Your Name"
email = "you@example.com"

# Branching configuration (optional)
[branching]
strategy = "environment"  # or "gitflow", "trunk"

[branching.promotion]
paths = [
    { source = "development", target = "staging" },
    { source = "staging", target = "production" }
]
require_approval = true

HEAD File

The HEAD file tracks the current branch:

ref: refs/heads/main

Or in detached HEAD state (direct commit reference):

abc123def456...

DDL Configuration

DDL (Data Definition Language) execution settings for schema changes.

[ddl]

OptionTypeDefaultDescription
lock_timeout_secsint30Lock acquisition timeout
statement_timeout_secsint300Statement execution timeout
check_table_statsbooltrueCheck table size before DDL
use_concurrentboolfalseUse concurrent index operations
warn_large_table_rowsint1000000Warn if table exceeds rows
warn_large_table_bytesint1073741824Warn if table exceeds bytes (1GB)

[ddl.retry]

OptionTypeDefaultDescription
max_retriesint3Maximum retry attempts
initial_delay_msint500Initial retry delay
max_delay_msint30000Maximum retry delay
backoff_multiplierfloat2.0Exponential backoff factor

Example:

[ddl]
lock_timeout_secs = 30
statement_timeout_secs = 300
check_table_stats = true

[ddl.retry]
max_retries = 3
initial_delay_ms = 500
max_delay_ms = 30000

Branching Configuration

[branching]

OptionTypeDefaultDescription
strategystring“environment”Branching strategy
default_branchstring“main”Default branch name
protected_branchesarray[“main”, “production”]Protected branch patterns

Branching Strategies

environment (default):

  • Branches represent environments (development, staging, production)
  • Promotion flows upward through environments
  • Good for data pipelines and ETL workflows

gitflow:

  • Feature branches, develop, release, hotfix, main
  • Traditional Git Flow pattern adapted for data
  • Good for teams familiar with Git Flow

trunk:

  • Single main branch with short-lived feature branches
  • Continuous integration style
  • Good for fast-moving projects

[branching.promotion]

OptionTypeDefaultDescription
pathsarray[]Allowed promotion paths
require_approvalboolfalseRequire approval for promotions
auto_mergebooltrueAuto-merge if no conflicts
conflict_strategystring“fail”Conflict handling (fail/ours/theirs)

Example:

[branching]
strategy = "environment"
default_branch = "development"
protected_branches = ["staging", "production"]

[branching.promotion]
paths = [
    { source = "development", target = "staging" },
    { source = "staging", target = "production" }
]
require_approval = true
conflict_strategy = "fail"

Conflict Handling

[conflict]

OptionTypeDefaultDescription
default_strategystring“manual”Default conflict resolution
auto_resolve_schemaboolfalseAuto-resolve schema conflicts

[conflict.table_rules]

Per-table conflict rules:

[conflict.table_rules.users]
strategy = "last_write_wins"
timestamp_field = "updated_at"

[conflict.table_rules.audit_log]
strategy = "append_only"

[conflict.field_rules]

Per-field conflict rules:

[conflict.field_rules."users.email"]
strategy = "source_wins"

[conflict.field_rules."users.login_count"]
strategy = "sum"

Strategies: manual, source_wins, target_wins, last_write_wins, sum, max, min, append_only.

Testing and Development

Development Environment Variables

VariableDescription
DATABASE_URLDatabase URL for tests/development
TEST_DATABASE_URLAlternative test database URL
SQLX_OFFLINEEnable SQLx offline mode (true)

S3/MinIO Testing

VariableDescription
S3_ENDPOINTS3/MinIO endpoint URL
S3_BUCKETTest bucket name
S3_ACCESS_KEYAccess key for testing
S3_SECRET_KEYSecret key for testing

E2E Testing

VariableDescriptionDefault
EPOCH_BINPath to CLI binary for tests./target/debug/epoch
E2E_KEEP_TEMPKeep temporary test directoriesfalse
E2E_VERBOSEVerbose test outputfalse

Example Development Setup

# .env file for development
DATABASE_URL=postgresql://horizon:horizon_dev_password@localhost:5432/horizon_epoch
EPOCH_METADATA_URL=postgresql://horizon:horizon_dev_password@localhost:5432/horizon_epoch

# MinIO for local S3 testing
EPOCH_S3_ENDPOINT=http://localhost:9000
EPOCH_S3_ACCESS_KEY=minioadmin
EPOCH_S3_SECRET_KEY=minioadmin
EPOCH_S3_BUCKET=horizon-epoch-data

# Development settings
EPOCH_DEBUG=true
EPOCH_LOG_LEVEL=debug
RUST_LOG=horizon_epoch=debug,sqlx=warn

# Author info
EPOCH_AUTHOR_NAME="Development User"
EPOCH_AUTHOR_EMAIL="dev@example.com"

Complete Configuration Example

# epoch.toml - Complete configuration example

# =============================================================================
# Metadata Database
# =============================================================================
[metadata_db]
url = "postgresql://localhost:5432/horizon_epoch"
max_connections = 10
min_connections = 2

# =============================================================================
# Logging
# =============================================================================
[logging]
level = "info"
format = "json"  # "pretty" or "json"

# =============================================================================
# DDL Execution
# =============================================================================
[ddl]
lock_timeout_secs = 30
statement_timeout_secs = 300
check_table_stats = true
use_concurrent = false

[ddl.retry]
max_retries = 3
initial_delay_ms = 500
max_delay_ms = 30000

# =============================================================================
# Branching Strategy
# =============================================================================
[branching]
strategy = "environment"
default_branch = "development"
protected_branches = ["staging", "production"]

[branching.promotion]
paths = [
    { source = "development", target = "staging" },
    { source = "staging", target = "production" }
]
require_approval = true

# =============================================================================
# Storage Backends
# =============================================================================

# PostgreSQL backends
[[storage.postgresql]]
name = "primary"
url = "postgresql://localhost:5432/data"

[[storage.postgresql]]
name = "analytics"
host = "analytics-db.internal"
port = 5432
database = "analytics"

[storage.postgresql.credentials]
type = "vault"
addr = "https://vault.example.com:8200"
secret_path = "database/creds/analytics"

[storage.postgresql.tls]
mode = "verify_full"
ca_cert = "/etc/ssl/certs/ca.pem"

# S3 backends
[[storage.s3]]
name = "datalake"
endpoint = "https://s3.amazonaws.com"
bucket = "company-datalake"
region = "us-east-1"
prefix = "epoch/"

[[storage.s3]]
name = "archive"
endpoint = "http://minio.internal:9000"
bucket = "archive"
access_key_id = "${MINIO_ACCESS_KEY}"
secret_access_key = "${MINIO_SECRET_KEY}"
force_path_style = true