Hub configuration
The Hub reads a YAML config file at startup from
BRITTLE_CONFIG_PATH (default: /etc/brittle/hub.config.yaml). Most
deployments only need the four secrets: DATABASE_URL, JWT_SECRET,
BRITTLE_AI_SECRET_KEY, and whatever your artifact store needs.
This page lists the full schema. The Installation page ships a working config inline; reach for individual fields here only when you need to deviate.
File format
Section titled “File format”server: host: 0.0.0.0 port: ${HUB_PORT:3100} logLevel: ${LOG_LEVEL:info}
database: url: ${DATABASE_URL}
auth: jwtSecret: ${JWT_SECRET}
artifacts: store: local:/var/lib/brittle/artifacts
# Required-by-schema blocks even when their fields all default.session: {}nodes: heartbeat: {}internal: {}tunnel: {}
ai: enabled: false${VAR} and ${VAR:default} placeholders interpolate from process env
at startup.
server
Section titled “server”| Field | Type | Default | Notes |
|---|---|---|---|
host | string | 0.0.0.0 | Bind address. Leave as-is unless you’re binding to a specific NIC. |
port | int | 3000 | HTTP port the Hub listens on inside the container. |
logLevel | enum | info | One of `fatal |
database
Section titled “database”| Field | Type | Required | Notes |
|---|---|---|---|
url | string | yes | Postgres URL: postgresql://user:pass@host:port/db?schema=public. |
| Field | Type | Required | Notes |
|---|---|---|---|
jwtSecret | string | yes | Min 32 chars. Used to sign session cookies. Rotate by replacing the value and restarting. |
artifacts
Section titled “artifacts”Where session artifact bytes (videos, traces, screenshots) live. The
store field is a URI:
| Prefix | Behaviour |
|---|---|
local: | Filesystem under the absolute path. The Hub streams bytes through itself for upload + download. |
s3:// | S3-compatible bucket. Reporters and the dashboard hit the bucket directly; the Hub doesn’t proxy bytes. |
artifacts: store: s3://my-brittle-artifacts/prod s3: region: us-east-1 accessKeyId: ${AWS_ACCESS_KEY_ID} secretAccessKey: ${AWS_SECRET_ACCESS_KEY} # Optional. Set for non-AWS providers (MinIO, R2, GCS S3-compat). endpoint: https://example.r2.cloudflarestorage.com forcePathStyle: true # Optional. When minting download URLs, use this hostname instead # of `endpoint`. Lets internal traffic stay on the private endpoint # while browsers/CI runners hit a public CDN URL. publicEndpoint: https://cdn.example.com presignTtlSeconds: 900The s3: sub-block applies only when store: s3://.... Inner fields
are individually optional. Set the ones your provider needs.
Optional. AI failure pattern detection across runs.
ai: enabled: true provider: gemini| Field | Type | Notes |
|---|---|---|
enabled | bool | Master switch. When false (default), no AI jobs run regardless of per-org configuration. |
provider | enum | One of `openai |
apiKey | string | Default API key. Per-org keys configured in the dashboard override this. Optional. |
model | string | Default model. Per-org override available. Optional. |
Per-organisation provider config (via dashboard Manage → Organization → AI) overrides this hub-level block at job-execution time. Hub-level config is the default for orgs without their own setup.
internal
Section titled “internal”Reserved for monitoring endpoints (queue depth, AI job status). Set
internal.token to a bearer string to enable them; leave unset and
the endpoints return 503. See
Production notes.
The schema also includes a few placeholder blocks (session,
nodes, tunnel) that don’t do anything today. Leave them empty
or omit them entirely.
Env vars the Hub reads
Section titled “Env vars the Hub reads”In addition to placeholders interpolated by the YAML config, the Hub reads these directly from process env:
| Variable | Required | Notes |
|---|---|---|
BRITTLE_CONFIG_PATH | no | Path to the YAML config. Default /etc/brittle/hub.config.yaml. |
BRITTLE_AI_SECRET_KEY | yes | Min 16 chars. Encrypts per-org AI keys in the database. Generate with openssl rand -hex 32. Required even when AI is off. |
BRITTLE_RUN_MIGRATIONS | no | Default true. Set to false to skip the DB migration step at startup (use when you migrate out of band). |
NODE_ENV | no | Default production. Affects logger output format. |
All of the YAML config’s ${VAR} placeholders also read from env.
Reloading
Section titled “Reloading”There’s no SIGHUP reload. After editing the config, restart the Hub:
docker compose restart brittleNext steps
Section titled “Next steps”- Production notes for TLS, secret rotation, and backups.
- Self-host overview covers the shape of a deployment.