Skip to content
v0.8.4stable

Configuration reference

Halro uses a strict YAML configuration. Unknown fields, invalid enums, and illegal combinations are rejected. The authoritative field inventory is the configs/config.example.yaml file at the pinned source revision above.

Runtime file versus example
FilePurposeEdit directly?
config.yamlThe file passed to the current instance with --configYes; back it up and validate every change
configs/config.example.yamlVersion-matched reference templateCopy for a new managed deployment; never overwrite a live configuration during upgrade

Relative paths resolve from the process working directory. Managed deployments should use explicit absolute paths. Choose the usage IANA timezone before initialization; changing accounting boundaries later requires operational review.

One deliberate difference is easy to miss: the repository template uses Asia/Shanghai for usage.timezone, while the config.yaml created by the first halro start uses UTC. Both are valid; choose the real accounting timezone before initialization.

Terminal window
cp ./config.yaml ./config.yaml.bak
$EDITOR ./config.yaml
./halro config check --config ./config.yaml
# restart through the deployment manager
curl -fsS http://127.0.0.1:8080/health/ready

Configuration is not a general live-reload contract. Validate first, then restart exactly one writer.

Except for the items below, every configuration change requires a Halro restart.

Activation and reload behavior
Reloadable with SIGHUP on Linux/macOSBehavior
logging.levelHalro rereads the configuration; the entire file must still validate
Files referenced by tls.certificatesFile contents are reread at the same paths; path or list changes require restart
Files referenced by metrics.tlsCertificate, key, and client CA reload as one set; path changes require restart
Log file handlesSupports the external “rename, then signal” rotation pattern

Use systemctl reload halro or kill -HUP <PID>. For other changes, use the deployment manager—for example sudo systemctl restart halro. Windows does not deliver SIGHUP, so restart for every change. Listener addresses, timeouts, proxy trust, admin.external_origin, storage, and Master Key settings always require restart.

Top-level version
ParameterExampleMeaning
version1Configuration schema version; it must currently be 1 and is not the Halro release version
Server: listeners and HTTP limits
ParameterExamplePurpose and constraints
server.gateway_listen127.0.0.1:8080Model request entry point; prefer TLS termination at a reverse proxy in production
server.admin_listen127.0.0.1:8081Admin API and console; do not expose directly to the public Internet
server.metrics_listen127.0.0.1:9090Prometheus Metrics and audit-anchor pull listener
server.read_header_timeout5sMaximum time to read all request headers; must be positive
server.read_body_timeout15sMaximum time to read the request body; must be positive
server.shutdown_timeout120sGraceful shutdown budget; must be positive and no shorter than gateway.route_total_timeout
server.max_header_bytes32768Maximum request-header bytes; minimum 1024
server.max_request_bytes10485760Maximum non-streaming request size; must be positive; example is 10 MiB

All enabled listener addresses must differ. Non-loopback listeners trigger additional TLS and authentication validation.

When other machines can reach Gateway or Admin, production traffic must use HTTPS. The recommended deployment terminates TLS at Caddy, nginx, or Traefik and keeps Halro on a protected loopback or container network with tls.enabled: false. Enable Halro TLS only when clients connect to it directly.

TLS: Gateway and Admin inbound encryption
ParameterExamplePurpose and constraints
tls.enabledfalseEnables inbound TLS for Gateway and Admin
tls.certificates[]Certificate list; one to sixteen entries when enabled
tls.certificates[].cert_filePEM certificate-chain path; no duplicates
tls.certificates[].key_fileMatching PEM private-key path
tls:
enabled: true
certificates:
- cert_file: /etc/halro/tls/fullchain.pem
key_file: /etc/halro/tls/privkey.pem

The first certificate serves clients without SNI; the others are selected by hostname. The certificate list must be empty while TLS is disabled.

Storage: data and Master Key
ParameterExamplePurpose and constraints
storage.data_dir./dataRoot for database, Ledger, Audit, and Usage data; relative to the process working directory
storage.metadata_filehalro.dbMetadata filename only; directories are not allowed
storage.master_key.modefileMaster Key source; normal single-node deployments use a local file, advanced deployments use external key slots
storage.master_key.file./master.keyMaster Key path in file mode; relative to the process working directory

Mount the data directory and Master Key on separate persistent volumes. Design key_slots mode around the real KMS provider, region, account, key ID, algorithm, and startup timeout; do not trial-and-error a live migration from file mode.

Admin: sessions and management features
ParameterExamplePurpose and constraints
admin.session_ttl8hMaximum Admin session lifetime; must be positive
admin.idle_timeout30mIdle-session expiry; positive and no longer than session_ttl
admin.login_rpm5Login attempts per minute; minimum 1
admin.mfa_policyoptionalInstance policy: optional or required
admin.developer_workbenchenabledReal Gateway debugging on the Admin listener: enabled or disabled
admin.reauth_elevation_window10mHow long reauthentication authorizes sensitive actions; 0s means every action
admin.external_origin""Canonical browser origin, for example https://admin.example.com; no path, query, or fragment
admin.setup_token_file""Absolute path to a production-mounted one-time setup token; ignored after an administrator exists. Available since v0.8.3
admin.setup_token_ttl30mGenerated-token lifetime or maximum remaining lifetime accepted from a file; positive, at most 24h, and never renewed by restart. Available since v0.8.3

Disable the developer workbench when Admin is not loopback-only. external_origin must exactly match the user-facing scheme, host, and port. A non-empty value requires a one-time setup token for the first administrator.

Starting in v0.8.3, production serve does not generate a Token that operators cannot retrieve safely. A remote zero-administrator instance must configure an absolute setup_token_file or create the administrator offline with admin bootstrap. A missing, malformed, expired, or over-long-remaining-TTL file blocks startup with no log fallback. The file is read once at process start; after rotating the Secret, stop the old Pod and start one that loads the new version. Halro stops reading after an administrator exists, but the orchestrator must still remove mandatory mount dependencies before rescheduling without the Secret.

See Production Admin bootstrap and secret lifecycle for generation, mounting, automated Jobs, Audit verification, and compromise recovery. Releases up to and including v0.8.2 does not contain these fields; do not give the updated configuration to that older binary.

MFA policy
PolicyNo authenticatorAuthenticator existsIntended use
optionalConsole access is allowed; the user may enrollExisting MFA remains required and is not removed or bypassedLoopback-only development or personal instances
requiredOnly MFA setup is available after password loginEvery login requires password and TOTP; the final authenticator cannot be removedAny remotely reachable Admin, especially production

Remote Admin should use required together with HTTPS, network access control, and accurate time synchronization. Policy changes require restart. To recover after losing every authenticator and recovery code, stop Halro and run:

Terminal window
./halro admin reset-mfa --config ./config.yaml --username admin

The command deletes that account’s authenticators and recovery codes, invalidates sessions and pending challenges, and writes an Audit record. With required, the next password login is limited to MFA reenrollment.

Capability detection runs only after explicit administrator confirmation and can issue billable Provider calls.

Model capability detection
ParameterExamplePurpose and constraints
admin.model_capability_detection.fresh_ttl24hTime a result remains fresh; must be positive
admin.model_capability_detection.retention720hRecord retention; no shorter than fresh_ttl
admin.model_capability_detection.refresh_cooldown5mMinimum interval between manual refreshes of one model
admin.model_capability_detection.total_timeout90sTask timeout; positive and no more than 2m
admin.model_capability_detection.global_concurrency4Instance-wide detection concurrency; minimum 1
admin.model_capability_detection.provider_concurrency1Per-Provider concurrency; minimum 1 and no greater than global concurrency
admin.model_capability_detection.max_provider_calls10Maximum billable calls in one detection
admin.model_capability_detection.create_rpm6New tasks per administrator per minute; 160
Usage: persistence and export
ParameterExamplePurpose and constraints
usage.durabilitybalancedbalanced favors throughput and latency; strict strengthens durability at higher write cost
usage.timezoneAsia/ShanghaiAccounting timezone used only at first initialization; change an initialized instance in Admin settings
usage.wal_queue_capacity4096Usage records waiting for the WAL; minimum 1
usage.wal_max_batch128Records per WAL batch; minimum 1, no greater than queue capacity
usage.wal_flush_interval2msMaximum time an incomplete batch waits; must be positive
usage.analytics_queue_capacity4096Records waiting for analytics processing; minimum 1
usage.checkpoint_interval1mPersistent-checkpoint cadence; must be positive
usage.parquet_interval1hAnalytics-partition write cadence; must be positive
usage.retention_days90Local analytics retention; minimum 1 day
usage.console_window_days30Initial in-memory console window for Attempts and failures; runtime value lives in instance settings and cannot exceed retention
usage.export_formatparquetNew partition format: parquet or ndjson; existing partitions are not rewritten

Changing usage.timezone after initialization does not change the active accounting timezone; halro doctor reports the mismatch.

Ledger: sealing
ParameterExamplePurpose and constraints
ledger.seal.enabledfalseSeals a complete active Accounting WAL generation at the threshold
ledger.seal.max_active_bytes8589934592Active WAL threshold; minimum 16 MiB
ledger.seal.compresstrueReplaces a sealed generation with a verified gzip copy after export and checkpoint boundaries are safe

Sealing does not delete accounting history. Replay continues from sealed segments into the active WAL. Treat it as a recovery design choice, not ordinary log rotation.

Gateway: request budgets, attempts, and limits

Section titled “Gateway: request budgets, attempts, and limits”
Gateway: request budgets, attempts, and limits
ParameterExamplePurpose and constraints
gateway.route_total_timeout120sTotal request budget across every Attempt
gateway.pricing_clock_rollback_tolerance2sPermitted clock rollback when selecting prices; not below the safety floor
gateway.pricing_clock_forward_tolerance30sPermitted price timestamp lead; nonnegative
gateway.pricing_unknown_policyrejectreject or allow_without_cost_governance
gateway.attempt_connect_timeout5sPer-Attempt upstream connection timeout
gateway.attempt_response_header_timeout60sPer-Attempt wait for upstream headers
gateway.downstream_write_timeout15sTimeout for one downstream response write
gateway.stream_max_duration10mMaximum streaming request duration
gateway.max_total_attempts3Request-wide Attempt limit across all targets; minimum 1
gateway.deferred_response_workers4Instance-wide deferred-response workers
gateway.health_probe_interval30sBackground Deployment health-probe interval
gateway.source_rate_limit.requests_per_minute600Pre-authentication per-source budget; 0 disables it
gateway.source_rate_limit.max_tracked_sources16384Distinct tracked sources before overflow shares one budget

Increasing an Attempt timeout does not increase the total budget. Review gateway.route_total_timeout and server.shutdown_timeout together.

Failed-request diagnostic capture
ParameterExamplePurpose and constraints
gateway.failure_capture.enabledfalseStores bounded, redacted final-failure diagnostics
gateway.failure_capture.max_bytes65536Maximum stored bytes per record
gateway.failure_capture.max_records_per_day1000Maximum records per accounting day
gateway.failure_capture.retain24hDiagnostic retention

It never stores Provider credentials and is not a request-body archive. Enable it only after reviewing disk and privacy boundaries.

Retry and Circuit Breaker
ParameterExamplePurpose and constraints
retry.max_attempts_per_target2Attempts on one upstream target; minimum 1
retry.base_delay100msInitial retry backoff; positive
retry.max_delay2sBackoff cap; no shorter than base_delay
retry.jittertrueRandomizes backoff to prevent synchronized retries
circuit_breaker.consecutive_failures5Consecutive failures before opening; minimum 1
circuit_breaker.open_duration30sTime open before half-open; positive
circuit_breaker.half_open_max_requests1Concurrent half-open probes; minimum 1

The effective boundary combines the per-target limit, the request-wide gateway.max_total_attempts, and available route targets.

Alerts
ParameterExamplePurpose and constraints
alerts.queue_capacity1024Pending alert-delivery queue; minimum 1
alerts.workers2Parallel delivery workers; minimum 1
alerts.timeout5sPer-delivery timeout; positive
alerts.max_attempts3Delivery attempts per alert; minimum 1
alerts.base_delay250msInitial alert retry backoff; positive
alerts.max_delay5sAlert retry cap; no shorter than base delay
alerts.dedup_cooldown1mCooldown before the same alert may be delivered again
Security: private access and proxy trust
ParameterExamplePurpose and constraints
security.allow_private_provider_endpointsfalseAllows Provider endpoints to resolve or connect to private addresses; expands SSRF reachability
security.allow_private_webhooksfalseAllows Webhook targets on private addresses
security.trust_proxy_headersfalseTrusts forwarded client-address headers
security.trusted_proxy_cidrs[]Proxy CIDRs allowed to supply trusted headers

Enable proxy trust only behind a controlled reverse proxy and restrict CIDRs to real proxy networks.

security:
trust_proxy_headers: true
trusted_proxy_cidrs:
- "10.42.0.0/16"
Metrics: Prometheus and independent mTLS
ParameterExamplePurpose and constraints
metrics.enabledtrueEnables the Metrics service
metrics.require_authtrueRequires an independent bearer credential
metrics.credential_file""Metrics credential file; requires require_auth: true
metrics.max_concurrent_scrapes2Concurrent scrapes, 132
metrics.write_timeout5sResponse-write timeout; positive and at most 30s
metrics.tls.enabledfalseEnables independent TLS and client-certificate authentication
metrics.tls.cert_file""Metrics server certificate chain
metrics.tls.key_file""Metrics server private key
metrics.tls.client_ca_file""CA used to authenticate scrape clients

For loopback-only Metrics, an empty credential file derives a default token from the Master Key; read it with halro metrics token --config ./config.yaml. Production should use a separately rotatable credential file. A non-loopback Metrics listener requires that independent credential and complete mTLS configuration.

Audit Anchor: external audit anchors
ParameterExamplePurpose and constraints
audit.anchor.enabledfalsePublishes audit-chain summaries without event bodies
audit.anchor.sinkdead_man_pullOnly implemented sink; other names are reserved
audit.anchor.interval5mMaximum interval between anchors; positive and at most 1h
audit.anchor.record_delta500New records required to trigger an anchor; minimum 1
audit.anchor.credential_file""Independent dead-man pull credential

External anchoring requires Metrics mTLS and an anchor credential different from metrics.credential_file.

Model Catalog: signed model catalog
ParameterExamplePurpose and constraints
model_catalog.enabledfalseRefreshes a signed model catalog in the background; Gateway requests never download it
model_catalog.refresh_interval6hRefresh interval, 5m168h
model_catalog.pinned_revision""Optional sha256: revision followed by 64 hex digits
model_catalog.max_download_bytes1048576Compressed response cap, 4 KiB–16 MiB
model_catalog.max_decoded_bytes4194304Decoded cap; at least download cap and no more than 64 MiB
model_catalog.max_compression_ratio20Maximum expansion ratio, 1100
model_catalog.max_entries10000Verified manifest entry cap, 1100000

Providers: v0.8.1 configuration compatibility

Section titled “Providers: v0.8.1 configuration compatibility”

v0.8.2 no longer uses global providers.bedrock.region. A Bedrock Mantle Credential saved in Admin determines its Region and binds to that Region’s endpoint. For in-place upgrades, Halro still accepts and validates this legacy block:

providers:
bedrock:
region: us-east-1

The value must still be a valid AWS Region name, but it no longer changes saved Credentials or Providers. Remove it after confirming the Admin Credential is bound to the intended regional endpoint.

Logging: output and rotation
ParameterExamplePurpose and constraints
logging.levelinfodebug, info, warn, or error; the only semantic field reloadable by SIGHUP
logging.formatjsonjson for collectors or text for terminals; both are redacted
logging.outputstderrstderr, file, or both
logging.file""Empty uses <data_dir>/logs/halro.log; used only for file output
logging.max_size_mb64File size cap, 14096 MiB
logging.max_files5Files retained including active file, 1100

logging.error_file is an independent ERROR-level diagnostic file:

Logging: output and rotation
ParameterExamplePurpose and constraints
logging.error_file.enabledfalseEnables the independent ERROR log
logging.error_file.file""Empty uses the default path under the data directory
logging.error_file.max_size_mb32Per-file cap
logging.error_file.max_files10Retained error-log files

systemd, Docker, and Kubernetes normally send stderr to platform collection. Without a collector, use file or both and size the data volume accordingly.

Common adjustment scenarios
GoalReview together
Expose Admin through a reverse proxyserver.admin_listen, admin.external_origin, proxy trust, and proxy TLS/access control
Extend long or streaming responsesgateway.stream_max_duration, gateway.route_total_timeout, server.shutdown_timeout, and outer-proxy timeouts
Increase request sizeserver.max_request_bytes and proxy/Ingress body-size limits
Expose Metrics to another hostserver.metrics_listen, metrics.credential_file, and complete Metrics mTLS
Increase retriesBoth retry limits, total timeout, non-idempotent behavior, and Provider cost
Rate-limit by real client IPTrust only controlled proxy CIDRs before enabling forwarded headers
Change accounting timezoneSet usage.timezone before new-instance initialization; use Admin instance settings afterward
Change console history windowChange the runtime instance setting and review retention
Increase deferred-response throughputWorkers, Project queue, Project/Deployment concurrency, and total timeout
Enable failure diagnosticsCapture settings, data volume, retention, and privacy policy

Run Governance parameters outside config.yaml

Section titled “Run Governance parameters outside config.yaml”

Run Governance is Project policy configured in the Admin Console, not instance YAML.

Run Governance parameters outside config.yaml
Project parameterPurpose and constraints
run_governance.enabledEnables Work Unit/Run APIs and request attribution; cannot be disabled while a Run is active
default_run_budget_micros_usdDefault budget when Run creation omits one
max_run_budget_micros_usdMaximum lifetime budget a Run may declare
default_run_ttl_secondsDefault TTL when Run creation omits one
max_run_ttl_secondsMaximum Run TTL, no more than 30 days
max_active_runsActive Runs per Project, maximum 1000
max_open_work_unitsOpen Work Units per Project, maximum 1000

The console displays budgets in USD and TTLs in hours; the Run API uses micros USD and seconds. See Integrate Run Governance.

For certificate, permission, disk, and runtime-data checks, stop Halro and run:

Terminal window
./halro doctor --config ./config.yaml

config check validates structure, ranges, and combinations. doctor also inspects deployment conditions and requires exclusive access to the data directory. Start only after both checks pass, then verify /health/ready and logs.