Skip to content

Configuration reference

For a short, ordered walkthrough, start with Run your first server. This page is the detailed reference for environment variables, probes, exit codes, and bootstrap behavior. Its existing quick_start.md path is retained for incoming links.

Environment Variables

Hubuum accepts command-line options and HUBUUM_ environment variables; CLI options override the corresponding environment values. Supported credentials can also come from mounted files. Both binaries accept --secret-source file and --secret-file-root DIRECTORY, equivalent to HUBUUM_SECRET_SOURCE=file and HUBUUM_SECRET_FILE_ROOT. The default source remains environment.

File mode changes where supported secret values are read, while ordinary configuration keeps its existing inputs. Explicit database URL arguments override the selected source; missing required files do not fall back to environment credentials. See Secret Sources for the full precedence rules, environment/file mapping, and complete server, migration, and restore-executor deployment examples. Use hubuum-server --help or hubuum-admin --help to list each binary's CLI options.

Health Probes

Hubuum exposes unauthenticated probe endpoints for container schedulers and load balancers:

Endpoint Purpose
/healthz Liveness probe. Returns 200 OK when the process can serve HTTP. Does not touch the database.
/readyz Readiness probe. Returns 200 OK only after the database is reachable and the migration required by this binary is applied. Returns 503 Service Unavailable when the service should not receive traffic.

Probe paths bypass the client IP allowlist so platform health checks are not rejected before reaching the handler.

Local Docker Compose

The development Compose stack requires a local, untracked .env file instead of using a password committed to the repository:

printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 32)" > .env
docker compose --profile administration run --rm hubuum-migrate --migrate
docker compose up --build -d hubuum-restore-executor hubuum

This default uses one PostgreSQL login for the server, one-shot migrations, and the isolated restore executor. To opt into separate least-privilege roles, set HUBUUM_DATABASE_ROLE_MODE=split, provide unique migrator and runtime passwords and URLs as shown in .env.example, and initialize a fresh Compose database volume.

The API is published on 127.0.0.1:9999 and PostgreSQL on 127.0.0.1:9998; neither service listens on all host interfaces by default. The Hubuum container runs as the unprivileged hubuum user with a read-only root filesystem, all Linux capabilities dropped, and only a small temporary filesystem at /tmp.

The production image includes a /healthz health check, but long-lived server containers never run migrations. PostgreSQL client administration tools and the standalone Diesel CLI are not installed; use the image's hubuum-admin binary in a one-shot migration workload.

Server Configuration

Variable Default Description
HUBUUM_BIND_IP 127.0.0.1 IP address the server binds to
HUBUUM_BIND_PORT 8080 Port the server listens on
HUBUUM_LOG_LEVEL info JSON log verbosity (trace, debug, info, warn, error)
HUBUUM_ACTIX_WORKERS Detected CPU count Number of Actix worker threads
HUBUUM_RUNTIME_ROLE all Process role: all, api, or worker
HUBUUM_METRICS_ENABLED true Enables the Prometheus metrics scrape endpoint
HUBUUM_METRICS_PATH /metrics Literal absolute path for the Prometheus metrics scrape endpoint; worker-only processes expose just this route on their configured listener

Logs are newline-delimited JSON only and are configured through HUBUUM_LOG_LEVEL. Release builds include their Git SHA in the structured startup event; local builders may set HUBUUM_BUILD_GIT_SHA at compile time. See Structured Logging for fields and examples.

Access Control Configuration

Variable Default Description
HUBUUM_CLIENT_ALLOWLIST 127.0.0.1,::1 Comma-separated list of allowed client IPs or CIDRs (e.g., 10.0.0.0/24,2001:db8::/32)
HUBUUM_TRUST_IP_HEADERS false Master switch for trusting the X-Forwarded-For header when resolving the client IP
HUBUUM_TRUSTED_PROXIES (empty) Comma-separated trusted reverse-proxy IPs/CIDRs. Skipped from the connection peer inward; the first untrusted hop is the client
HUBUUM_TRUSTED_PROXY_HOPS 0 Number of proxy hops to skip from the right of the chain; used only when HUBUUM_TRUSTED_PROXIES is empty

Container note: The default HUBUUM_CLIENT_ALLOWLIST=127.0.0.1,::1 is loopback-only. In containerized setups, clients commonly arrive from bridge/network IPs, not loopback. For local/dev containers, set HUBUUM_CLIENT_ALLOWLIST=*. For production, prefer explicit CIDRs/IP ranges.

Proxy note: The client IP is resolved from the right of the [X-Forwarded-For..., peer] hop chain, so spoofed X-Forwarded-For values cannot take effect. When HUBUUM_TRUST_IP_HEADERS=true, configure HUBUUM_TRUSTED_PROXIES (preferred) or HUBUUM_TRUSTED_PROXY_HOPS. If neither is set, forwarded headers are ignored and the peer address is used.

Database Configuration

Variable Default Description
HUBUUM_STORAGE_BACKEND postgresql Storage adapter selected from those registered in this application build; empty selects the default, while other unknown values are rejected at startup
HUBUUM_DATABASE_URL postgres://localhost (server only) Runtime/shared PostgreSQL connection URL in environment mode; file mode uses database/url. --database-url overrides either source
HUBUUM_DATABASE_ROLE_MODE single Credential topology: one shared login (single) or separate owner, migrator, and runtime roles (split)
HUBUUM_MIGRATION_DATABASE_URL (none) Privileged admin URL; file mode uses database/migration-url. Optional in single, required for migrations/restores in split; --migration-database-url overrides either source. Keep it out of API/worker processes
HUBUUM_DATABASE_OWNER_ROLE hubuum_owner Non-login schema-owner role used in split mode
HUBUUM_DATABASE_MIGRATOR_ROLE hubuum_migrator Migration and isolated restore-executor role used in split mode
HUBUUM_DATABASE_RUNTIME_ROLE hubuum_runtime Non-owning API and worker role used in split mode
HUBUUM_DATABASE_PRIVILEGE_MODE warn Split-role runtime privilege audit behavior: warn or startup-failing strict; ignored in single mode
HUBUUM_DB_POOL_SIZE 10 Maximum number of database connections in the pool
HUBUUM_DB_POOL_ACQUIRE_TIMEOUT_MS 2000 Maximum wait for a free pooled connection before failing the request
HUBUUM_DB_STATEMENT_TIMEOUT_MS 30000 Pool-global Postgres statement_timeout in ms (0 disables). Cancels any query exceeding it server-side; applies to all DB work, not just exports

See Database Pool Tuning and Load Testing for connection budgeting, pool observability, and a repeatable k6 scenario. See PostgreSQL Database Roles for provisioning, grant diagnostics, and one-shot workload examples.

Administrators can inspect the selected storage backend and these effective pool settings at GET /api/v1/admin/config. The endpoint reports only whether the database URL is configured; it never returns the URL or credentials. See Application and Storage Boundary for the all-or-nothing backend contract.

Task System Configuration

Variable Default Description
HUBUUM_TASK_WORKERS About half the detected CPU count, minimum 1 Number of background task workers
HUBUUM_TASK_POLL_INTERVAL_MS 5000 Safety-net idle polling interval for background task workers; committed task inserts normally wake workers through the selected storage backend
HUBUUM_TASK_LEASE_SECONDS 60 Durable task lease duration
HUBUUM_TASK_HEARTBEAT_SECONDS 20 Lease renewal interval; must be shorter than the lease
HUBUUM_TASK_IMPORT_EXECUTION_TIMEOUT_SECONDS 3600 Maximum import execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_EXPORT_EXECUTION_TIMEOUT_SECONDS 900 Maximum export execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_BACKUP_EXECUTION_TIMEOUT_SECONDS 3600 Maximum backup execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_REINDEX_EXECUTION_TIMEOUT_SECONDS 7200 Maximum reindex execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_REMOTE_CALL_EXECUTION_TIMEOUT_SECONDS 300 Maximum remote-call execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_SCHEMA_VALIDATION_EXECUTION_TIMEOUT_SECONDS 7200 Maximum schema validation execution seconds from first claim; 1 to 2592000
HUBUUM_TASK_RECOVERY_INTERVAL_SECONDS 30 Minimum interval between abandoned-task recovery scans
HUBUUM_COMPUTED_REINDEX_BATCH_SIZE 100 Objects processed per computed-field rebuild transaction; valid range is 1 through 1000
HUBUUM_IMPORT_MAX_ACTIVE_TASKS_PER_USER 100 Maximum queued, validating, or running import tasks one user may have at once

Background workers and storage notification listeners participate in bounded graceful shutdown. See Background Worker Lifecycle for startup ownership, cancellation, task interruption, and pool-drop ordering.

Event And Audit Configuration

Variable Default Description
HUBUUM_EVENT_FANOUT_WORKERS 1 Number of background workers that fan matching audit events out to delivery rows
HUBUUM_EVENT_FANOUT_BATCH_SIZE 100 Number of events a fan-out worker claims per batch
HUBUUM_EVENT_FANOUT_POLL_INTERVAL_MS 5000 Safety-net idle polling interval for fan-out workers
HUBUUM_EVENT_FANOUT_LOCK_TIMEOUT_MS 30000 Fan-out claim lock timeout before another worker may retry
HUBUUM_EVENT_DELIVERY_WORKERS 0 Number of background workers that deliver rows to external sinks; 0 disables transport delivery
HUBUUM_EVENT_DELIVERY_BATCH_SIZE 100 Upper bound on delivery rows per claim; each worker claims at most its eight execution slots
HUBUUM_EVENT_DELIVERY_POLL_INTERVAL_MS 5000 Safety-net idle polling interval for delivery workers
HUBUUM_EVENT_DELIVERY_LOCK_TIMEOUT_MS 30000 Delivery claim lock timeout before another worker may retry
HUBUUM_EVENT_DELIVERY_TRANSPORT_TIMEOUT_MS 25000 Maximum transport time, reduced by claim/dispatch delays; must be less than the lock timeout, with the difference reserved for acknowledgment
HUBUUM_EVENT_DELIVERY_RETRY_BACKOFF_BASE_MS 1000 Initial delivery retry backoff
HUBUUM_EVENT_DELIVERY_RETRY_BACKOFF_MAX_MS 300000 Maximum delivery retry backoff
HUBUUM_EVENT_DELIVERY_MAX_ATTEMPTS 10 Attempts before a delivery row moves to dead-letter status
HUBUUM_EVENT_RETENTION_PURGE_ENABLED false Enables destructive audit event retention purge
HUBUUM_EVENT_RETENTION_DAYS 365 Age threshold for purging eligible audit events
HUBUUM_EVENT_DELIVERY_RETENTION_DAYS 30 Age threshold for purging terminal delivery rows
HUBUUM_EVENT_RETENTION_PURGE_INTERVAL_SECONDS 3600 Retention worker interval
HUBUUM_EVENT_RETENTION_PURGE_BATCH_SIZE 1000 Maximum event rows selected per purge batch
HUBUUM_EVENT_RETENTION_FILE_ARCHIVE_ENABLED false Enables local JSON Lines archive writes before deleting eligible events
HUBUUM_EVENT_RETENTION_ARCHIVE_PATH (empty) Durable directory for atomic per-claim JSON Lines files; required when file archive writes are enabled

Event note: The canonical audit stream is always stored in the events table. External delivery workers default to disabled, and retention purge defaults to disabled because it deletes audit rows. See Event And Audit for audit querying, sink/subscription setup, delivery semantics, operational health, and retention behavior.

Export and Template Execution Configuration

Variable Default Description
HUBUUM_EXPORT_OUTPUT_RETENTION_HOURS 168 How long successful async export outputs remain refetchable before cleanup
HUBUUM_EXPORT_OUTPUT_CLEANUP_INTERVAL_SECONDS 300 How often workers attempt cleanup of expired stored export and backup outputs (legacy variable name)
HUBUUM_EXPORT_MAX_ACTIVE_TASKS_PER_USER 100 Maximum queued, validating, or running export tasks one user may have at once
HUBUUM_EXPORT_TEMPLATE_RECURSION_LIMIT 64 MiniJinja recursion and template composition depth limit
HUBUUM_EXPORT_TEMPLATE_FUEL 50000 MiniJinja fuel budget for one render
HUBUUM_EXPORT_TEMPLATE_MAX_OBJECTS 2000 Maximum hydrated relation-aware template objects per export
HUBUUM_EXPORT_MAX_OUTPUT_BYTES 262144 Server maximum for rendered export output size; request-level limits.max_output_bytes cannot exceed this
HUBUUM_EXPORT_STAGE_TIMEOUT_MS 10000 Post-completion rejection budget per export stage (ms). Rejects an export after a stage finishes if it exceeded this; it does not interrupt in-flight work. Use HUBUUM_DB_STATEMENT_TIMEOUT_MS to actually cancel slow queries
HUBUUM_EXPORT_DB_STATEMENT_TIMEOUT_MS 0 Export-scoped Postgres statement_timeout in ms (0 disables). Cancels slow queries in-flight only while executing exports (applied as a transaction-local SET LOCAL), without affecting imports or other DB work. Typically set <= HUBUUM_EXPORT_STAGE_TIMEOUT_MS

Export/template note: These settings control async export task behavior, including stored output retention, template execution limits, and relation hydration guardrails. See Export API and Export Template Guide for the user-facing behavior these limits affect.

Backup and Restore Configuration

Variable Default Description
HUBUUM_BACKUP_OUTPUT_RETENTION_HOURS 24 How long a successful full-system backup remains downloadable
HUBUUM_BACKUP_MAX_ACTIVE_TASKS_PER_USER 1 Maximum active backup tasks one unscoped administrator may own
HUBUUM_BACKUP_MAX_OUTPUT_BYTES 268435456 Maximum backup artifact and individual source-row bytes, also enforced during capture
HUBUUM_BACKUP_MAX_CAPTURE_ROWS 1000000 Maximum rows enumerated during backup capture, including excluded history rows
HUBUUM_RESTORE_STAGE_RETENTION_MINUTES 60 How long a validated restore stage remains confirmable
HUBUUM_RESTORE_MAX_UPLOAD_BYTES 268435456 Maximum full-system restore document size accepted by the API

Backups and restore staging are unscoped administrator-only disaster-recovery operations. Destructive confirmation is disabled through the API and must run through hubuum-admin with the migrator credential. See Backup and Restore for the destructive confirmation flow, locking behavior, and export/import alternative for selective transfers.

Pagination Configuration

Variable Default Description
HUBUUM_DEFAULT_PAGE_LIMIT 100 Default number of items per page
HUBUUM_MAX_PAGE_LIMIT 250 Maximum number of items per page
HUBUUM_MAX_TRANSITIVE_DEPTH 100 Maximum recursion depth for transitive relation graph walks

Clients can discover the effective pagination values, including deployment overrides, without authentication:

GET /api/v1/config

The response exposes only settings deliberately classified as client-safe:

{
  "pagination": {
    "default_page_limit": 100,
    "max_page_limit": 250
  }
}

Positive request limits above max_page_limit are clamped rather than rejected. Paginated responses include X-Page-Limit with the effective page size.

Authentication & Authorization

Variable Default Description
HUBUUM_ADMIN_GROUPNAME admin Name of the admin group
HUBUUM_ADMIN_IDENTITY_SCOPE local Identity scope containing the admin group
HUBUUM_AUTH_CONFIG_PATH (empty) Optional TOML file for external auth providers such as LDAP
HUBUUM_TOKEN_LIFETIME_HOURS 24 Token lifetime in hours
HUBUUM_MAX_TOKEN_LIFETIME_HOURS 8760 Maximum lifetime in hours for an explicitly requested token expiry
HUBUUM_TOKEN_RETENTION_PURGE_ENABLED true Delete terminal token rows after the retention period
HUBUUM_TOKEN_RETENTION_DAYS 30 Days to retain a token after the earlier of revocation and effective expiry
HUBUUM_TOKEN_RETENTION_PURGE_INTERVAL_SECONDS 3600 Delay between token-retention purge runs
HUBUUM_TOKEN_RETENTION_PURGE_BATCH_SIZE 1000 Maximum token rows deleted in one purge batch; minimum 10
HUBUUM_LOGIN_RATE_LIMIT_ENABLED true Master switch for login throttling
HUBUUM_LOGIN_RATE_LIMIT_MAX_ATTEMPTS 5 Max failed attempts per (name, IP) per window
HUBUUM_LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_IP 20 Max failed attempts per client IP per window (0 disables)
HUBUUM_LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_SUBNET 100 Max failed attempts per client subnet per window (0 disables)
HUBUUM_LOGIN_RATE_LIMIT_WINDOW_SECONDS 300 Login rate-limit sliding window in seconds
HUBUUM_LOGIN_RATE_LIMIT_BACKOFF_BASE_SECONDS 300 First lockout duration; doubles on repeated lockouts
HUBUUM_LOGIN_RATE_LIMIT_BACKOFF_MAX_SECONDS 86400 Maximum lockout duration for exponential backoff
HUBUUM_LOGIN_RATE_LIMIT_SUBNET_PREFIX_V4 24 IPv4 prefix length for per-subnet aggregation
HUBUUM_LOGIN_RATE_LIMIT_SUBNET_PREFIX_V6 64 IPv6 prefix length for per-subnet aggregation
HUBUUM_LOGIN_RATE_LIMIT_BACKEND memory Limiter state backend: local memory or shared valkey
HUBUUM_LOGIN_RATE_LIMIT_VALKEY_URL (empty) Valkey/Redis URL required by the shared backend
HUBUUM_LOGIN_RATE_LIMIT_VALKEY_PREFIX hubuum:login-rate-limit Shared limiter key namespace
HUBUUM_LOGIN_RATE_LIMIT_VALKEY_IO_TIMEOUT_MS 1000 Shared backend I/O timeout
HUBUUM_TOKEN_HASH_KEY (generated per startup if unset) Key used for deterministic token hashing at rest
HUBUUM_TOKEN_HASH_ACTIVE_KEY_ID (legacy single-key mode) Active key ID for newly issued tokens
HUBUUM_TOKEN_HASH_PREVIOUS_KEY_IDS (empty) Comma-separated previous verification key IDs (maximum seven)
HUBUUM_REQUIRE_STABLE_TOKEN_HASH_KEY false Fail startup when stable token key material is unavailable
HUBUUM_SECRET_SOURCE environment Secret source: environment or file; overridden by --secret-source on either binary
HUBUUM_SECRET_FILE_ROOT (empty) Mounted secret directory required by file mode; overridden by --secret-file-root on either binary

See Secret Sources for the mounted-file layout and rotation contracts, and External Authentication for LDAP scopes.

Token lifetime note: Newly issued tokens always receive an explicit expires_at. If a mint request omits it, the server applies HUBUUM_TOKEN_LIFETIME_HOURS. Clients can read the effective default without authentication from GET /api/v1/config at authentication.default_token_lifetime_hours; issuance responses return the authoritative expires_at. Explicit expirations must be in the future and no later than issuance plus HUBUUM_MAX_TOKEN_LIFETIME_HOURS; the public config also exposes this limit as authentication.max_token_lifetime_hours.

Login rate-limit note: These settings throttle failed logins across layered scopes with exponential backoff. For the full model, client-IP resolution behind proxies, and the admin endpoints for inspecting and releasing throttled scopes, see login_rate_limiting.md.

Token hash key note: If neither the compatible HUBUUM_TOKEN_HASH_KEY nor a key ring is configured, Hubuum generates an ephemeral key on startup and logs a warning. Tokens issued before restart will be invalid after restart. All API replicas must use the same ring. See Secret Sources for the staged multi-replica procedure.

For runtime roles, one-shot migrations, task recovery, database connection budgeting, and shared limiter behavior, see Distributed Deployment.

TLS Configuration

Variable Default Description
HUBUUM_TLS_CERT_PATH None Path to TLS certificate chain file (PEM format)
HUBUUM_TLS_KEY_PATH None Path to TLS private key file (PEM format)
HUBUUM_TLS_KEY_PASSPHRASE None Passphrase for encrypted private key (OpenSSL only)
HUBUUM_TLS_BACKEND Auto / unset Preferred TLS backend when TLS is enabled (rustls or openssl)

Note: TLS requires both certificate and key paths to be set. The rustls feature does not support encrypted keys with passphrases. Certificate chains must be regular PEM files no larger than 4 MiB; private keys must be regular PEM files no larger than 1 MiB.

Exit Codes

The application uses specific exit codes to indicate different failure modes, which helps with monitoring and automation:

Exit Code Constant Description
0 - Successful execution
1 EXIT_CODE_GENERIC_ERROR Generic/unclassified errors
2 EXIT_CODE_CONFIG_ERROR Configuration validation
3 EXIT_CODE_DATABASE_ERROR Database connection or pool initialization failures
4 EXIT_CODE_INIT_ERROR Critical initialization errors (e.g., admin user/group creation)
5 EXIT_CODE_TLS_ERROR TLS setup errors

Exit Code Usage Examples

# Check if server started successfully
./hubuum-server || echo "Server failed with exit code $?"

First-Time Bootstrap

On first startup with an empty database, Hubuum automatically creates:

  • A default admin user (name: admin) with a randomly generated password
  • A default admin group (named as per HUBUUM_ADMIN_GROUPNAME, default: admin)
  • The admin user is added to the admin group

Important: The generated password is not printed or logged. Reset the password immediately after startup:

hubuum-admin --reset-password admin

Example Configurations

Development (HTTP)

export HUBUUM_BIND_IP="127.0.0.1"
export HUBUUM_BIND_PORT="8080"
export HUBUUM_LOG_LEVEL="debug"
export HUBUUM_DATABASE_URL="postgres://user:pass@localhost/hubuum_dev"
./hubuum-server

Production (HTTPS)

export HUBUUM_BIND_IP="0.0.0.0"
export HUBUUM_BIND_PORT="8443"
export HUBUUM_LOG_LEVEL="warn"
export HUBUUM_DATABASE_URL="postgres://hubuum:secure_password@db.example.com/hubuum_prod"
export HUBUUM_TLS_CERT_PATH="/etc/hubuum/certs/fullchain.pem"
export HUBUUM_TLS_KEY_PATH="/etc/hubuum/certs/privkey.pem"
export HUBUUM_ACTIX_WORKERS="8"
export HUBUUM_DB_POOL_SIZE="20"
./hubuum-server

Mounted Secrets

For a mounted directory containing database/url and token/key:

export HUBUUM_SECRET_SOURCE=file
export HUBUUM_SECRET_FILE_ROOT=/run/secrets/hubuum
export HUBUUM_REQUIRE_STABLE_TOKEN_HASH_KEY=true
hubuum-admin --migrate

Then run hubuum-admin --restore-executor and hubuum-server as separate supervised processes with the same environment. The default single database mode shares database/url; opt-in split uses a separate admin mount containing database/migration-url. See the complete mounted-secret Compose example and split-role mounts.

Docker Compose

Use single-host deployment for a complete installation with PostgreSQL, explicit migration sequencing, a restore executor, and optional frontend. For source development, use the repository's Compose configuration and the migration commands described above. A server-only Compose service does not provision its database or apply migrations.

See Also