Skip to content

Thorax Configuration

Configure the Thorax gRPC orchestration server.

Thorax searches for a config file in the following order:

  1. Path specified by THORAX_CONFIG environment variable
  2. thorax.toml in the current directory
  3. /etc/mantis/thorax.toml
  4. ~/.config/mantis/thorax.toml (platform-dependent config directory)

If no file is found, defaults are used. Environment variables always override file settings.

name = "thorax-prod-01"
log_level = "info"
FieldTypeDefaultRequiredDescription
namestringhostname-derived (e.g., "thorax-<hostname>")NoServer name for logging. Env: THORAX__NAME
log_levelstring"info"NoLog level: trace, debug, info, warn, error. Env: MANTIS_LOG_LEVEL

TLS configuration. TLS is always enabled and client certificates are always required (mTLS is mandatory).

[tls]
auth_mode = "thumbprint"
cert_path = "/etc/mantis/certs/server.crt"
key_path = "/etc/mantis/certs/server.key"
ca_cert_path = "/etc/mantis/certs/ca.crt"
ca_key_path = "/etc/mantis/certs/ca.key"
FieldTypeDefaultRequiredDescription
auth_modestring"thumbprint"NoAuthentication mode: thumbprint (self-signed OK) or ca_signed (CA-signed required). Env: MANTIS_TLS_AUTH_MODE
cert_pathstring-YesServer certificate PEM file. Env: MANTIS_TLS_CERT_PATH
key_pathstring-YesServer private key PEM file. Env: MANTIS_TLS_KEY_PATH
ca_cert_pathstring-Yes (ca_signed mode)CA certificate for client verification. Env: MANTIS_TLS_CA_CERT_PATH
ca_key_pathstring-NoCA private key for signing client CSRs. Env: MANTIS_TLS_CA_KEY_PATH

gRPC server settings.

[grpc]
address = "0.0.0.0"
port = 50051
max_message_size = 16777216
request_timeout_secs = 300
FieldTypeDefaultRequiredDescription
addressstring"0.0.0.0"NoBind address. Env: THORAX__GRPC__ADDRESS
portinteger50051NoListen port. Env: THORAX__GRPC__PORT
max_message_sizeinteger16777216 (16 MB)NoMaximum gRPC message size in bytes
request_timeout_secsinteger300NoRequest timeout (5 minutes)

Client session management configuration.

[session]
heartbeat_timeout_secs = 90
stale_timeout_secs = 300
cleanup_interval_secs = 60
FieldTypeDefaultRequiredDescription
heartbeat_timeout_secsinteger90NoMark client offline if no heartbeat (3x heartbeat interval)
stale_timeout_secsinteger300NoTime stale before marking offline (5 minutes)
cleanup_interval_secsinteger60NoSession cleanup check interval

Client poll interval, max concurrent commands, and default command timeout are sent to agents by Mandible at registration time — see MANDIBLE__CLIENT_SESSION__* in the Mandible Configuration reference.

Per-instance runtime overrides (live, no restart)

Section titled “Per-instance runtime overrides (live, no restart)”

The heartbeat interval and session timeout above are seeded from this file at startup, but can be overridden per Thorax instance at runtime without restarting the process. Mandible stores the override and pushes it to the instance on its next heartbeat; the instance applies it live (the heartbeat loop rebuilds its timer; the session-cleanup loop picks up the new timeout).

Set or clear overrides with the admin API (thorax_instances:update permission):

Terminal window
# Set both overrides for an instance
curl -X PATCH .../api/v1/thorax-instances/<id>/config \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"heartbeat_interval_secs": 15, "session_timeout_secs": 600}'
# Clear the heartbeat override (revert to the instance default); omit a field to
# leave it unchanged
curl -X PATCH .../api/v1/thorax-instances/<id>/config \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"heartbeat_interval_secs": null}'

Each field is tri-state: omit to leave unchanged, send null to clear (revert to the configured default), or send a positive integer to set. A session_timeout_secs override maps to the stale→offline threshold (stale_timeout_secs).

TLS handshake failure rate limiting to detect misconfigured clients or attacks.

[tls_rate_limit]
enabled = true
failure_threshold = 5
window_secs = 60
cleanup_interval_secs = 30
entry_ttl_secs = 300
alert_cooldown_secs = 60
FieldTypeDefaultRequiredDescription
enabledbooleantrueNoEnable TLS handshake failure rate limiting
failure_thresholdinteger5NoMax failures within window before alerting
window_secsinteger60NoSliding window for rate calculation
cleanup_interval_secsinteger30NoCleanup interval for stale IP entries
entry_ttl_secsinteger300NoTTL for IP entries after last failure (5 minutes)
alert_cooldown_secsinteger60NoCooldown before re-alerting for same IP

Tokio-console settings for async runtime debugging. Only active when the tokio-console feature is enabled.

[console]
enabled = true
address = "127.0.0.1"
port = 6669
retention_secs = 60
publish_interval_ms = 1000
FieldTypeDefaultRequiredDescription
enabledbooleanfalseNoEnable the tokio-console server. Env: THORAX__CONSOLE__ENABLED
addressstring"127.0.0.1"NoBind address. Env: THORAX__CONSOLE__ADDRESS
portinteger0 (sentinel)NoConsole port. Thorax uses 6669 by convention — set this explicitly in the config file. The serde default is the sentinel 0, which lets the OS assign an ephemeral port, so an explicit value is required for any reliable console connection. Env: THORAX__CONSOLE__PORT
retention_secsinteger60NoHow long to retain completed task data. Env: THORAX__CONSOLE__RETENTION_SECS
publish_interval_msinteger1000NoUpdate interval for connected clients (ms). Env: THORAX__CONSOLE__PUBLISH_INTERVAL_MS
recording_pathstring-NoPath to record console data for offline analysis. Env: THORAX__CONSOLE__RECORDING_PATH

Encryption settings for credential protection at rest (AES-256-GCM).

[encryption]
key = "base64-encoded-32-byte-key"
FieldTypeDefaultRequiredDescription
keystring-YesBase64-encoded 32-byte encryption key. Env: MANTIS_ENCRYPTION_KEY or MANDIBLE__ENCRYPTION__KEY. Generate with: openssl rand -base64 32

Mandible gRPC client configuration for Thorax-to-Mandible communication. Uses mTLS.

[mandible]
endpoint = "https://mandible:50052"
connect_timeout_secs = 10
request_timeout_secs = 30
heartbeat_interval_secs = 30
tls_cert_path = "/etc/mantis/certs/client.crt"
tls_key_path = "/etc/mantis/certs/client.key"
tls_ca_cert_path = "/etc/mantis/certs/ca.crt"
FieldTypeDefaultRequiredDescription
endpointstring"https://localhost:50052"YesMandible internal gRPC endpoint (must use HTTPS). Env: THORAX__MANDIBLE__ENDPOINT
connect_timeout_secsinteger10NoConnection timeout. Env: THORAX__MANDIBLE__CONNECT_TIMEOUT_SECS
request_timeout_secsinteger30NoRequest timeout. Env: THORAX__MANDIBLE__REQUEST_TIMEOUT_SECS
heartbeat_interval_secsinteger30NoHeartbeat interval. Env: THORAX__MANDIBLE__HEARTBEAT_INTERVAL_SECS
instance_namestringhostname-derivedNoInstance name for registration
tls_cert_pathstring-YesClient certificate for mTLS. Env: THORAX__MANDIBLE__TLS_CERT_PATH
tls_key_pathstring-YesClient private key for mTLS. Env: THORAX__MANDIBLE__TLS_KEY_PATH
tls_ca_cert_pathstring-YesCA certificate for server verification. Env: THORAX__MANDIBLE__TLS_CA_CERT_PATH

RabbitMQ queue settings for command consumption. TLS is mandatory.

[queue]
enabled = true
host = "rabbitmq.internal"
port = 5671
username = "mantis"
password = "secret"
vhost = "/"
ca_cert_path = "/etc/mantis/certs/rabbitmq-ca.crt"
client_cert_path = "/etc/mantis/certs/rabbitmq-client.crt"
client_key_path = "/etc/mantis/certs/rabbitmq-client.key"
prefetch_count = 10
fallback_on_failure = true
reconnect_delay_secs = 5
FieldTypeDefaultRequiredDescription
enabledbooleanfalseNoEnable RabbitMQ consumption. Env: THORAX__QUEUE__ENABLED. Note: RABBITMQ_ENABLED=true automatically enables cluster coordination (the [cluster] section’s enabled flag) — it does not set this queue flag.
hoststring"localhost"NoRabbitMQ host. Env: THORAX__QUEUE__HOST
portinteger5671NoAMQPS port (TLS only). Env: THORAX__QUEUE__PORT
usernamestring"" (empty — must be set when enabled)NoRabbitMQ username. Validation rejects an empty value when enabled = true. Env: THORAX__QUEUE__USERNAME
passwordstring"" (empty — must be set when enabled)NoRabbitMQ password. Env: THORAX__QUEUE__PASSWORD
vhoststring"/"NoVirtual host. Env: THORAX__QUEUE__VHOST
ca_cert_pathstring-Yes (if enabled)CA certificate for TLS. Env: THORAX__QUEUE__CA_CERT_PATH
client_cert_pathstring-NoClient certificate for mTLS. Env: THORAX__QUEUE__CLIENT_CERT_PATH
client_key_pathstring-NoClient private key for mTLS. Env: THORAX__QUEUE__CLIENT_KEY_PATH
prefetch_countinteger10NoConsumer prefetch count
fallback_on_failurebooleantrueNoFall back to polling when RabbitMQ is unavailable. Env: THORAX__QUEUE__FALLBACK_ON_FAILURE
reconnect_delay_secsinteger5NoReconnection delay after failure. Env: THORAX__QUEUE__RECONNECT_DELAY_SECS

Cluster coordination for multi-Thorax deployments via Redis.

[cluster]
enabled = true
instance_id = "thorax-prod-01"
redis_url = "redis://redis:6379"
heartbeat_interval_secs = 10
liveness_timeout_secs = 30
namespace = "thorax"
FieldTypeDefaultRequiredDescription
enabledbooleanfalseNoEnable cluster coordination. Automatically enabled when RABBITMQ_ENABLED=true. Env: THORAX__CLUSTER__ENABLED, RABBITMQ_ENABLED
instance_idstringhostname-derivedNoInstance ID for this Thorax
redis_urlstring"redis://localhost:6379"NoRedis connection URL. Env: THORAX__CLUSTER__REDIS_URL
heartbeat_interval_secsinteger10NoHeartbeat interval to Redis. Env: THORAX__CLUSTER__HEARTBEAT_INTERVAL_SECS
liveness_timeout_secsinteger30NoTimeout before considering instance dead. Env: THORAX__CLUSTER__LIVENESS_TIMEOUT_SECS
namespacestring"thorax"NoRedis key namespace prefix. Env: THORAX__CLUSTER__NAMESPACE

Thorax uses double-underscore env var names in its apply_env_overrides() method. See each section above for the specific env var names.

Common env vars:

Environment VariableDescription
THORAX_CONFIGPath to config file
THORAX__NAMEServer name
MANTIS_LOG_LEVELLog level
THORAX__MANDIBLE__ENDPOINTMandible gRPC endpoint (full HTTPS URL, e.g. https://mandible:50052)
THORAX__GRPC__ADDRESSgRPC bind address
THORAX__GRPC__PORTgRPC port
MANTIS_TLS_CERT_PATHServer TLS certificate
MANTIS_TLS_KEY_PATHServer TLS private key
MANTIS_TLS_CA_CERT_PATHCA certificate
MANTIS_TLS_CA_KEY_PATHCA private key
MANTIS_TLS_AUTH_MODETLS auth mode (thumbprint or ca_signed)
MANTIS_ENCRYPTION_KEYEncryption key (base64, 32 bytes)
RABBITMQ_ENABLEDEnable RabbitMQ + cluster mode

See Environment Variables for complete reference.

thorax.toml
name = "thorax-prod-01"
log_level = "info"
[tls]
auth_mode = "ca_signed"
cert_path = "/etc/mantis/certs/server.crt"
key_path = "/etc/mantis/certs/server.key"
ca_cert_path = "/etc/mantis/certs/ca.crt"
ca_key_path = "/etc/mantis/certs/ca.key"
[grpc]
address = "0.0.0.0"
port = 50051
[session]
heartbeat_timeout_secs = 90
# max_concurrent_commands and default_command_timeout_secs are sent by Mandible
# at registration time — configure them via MANDIBLE__CLIENT_SESSION__* instead.
[mandible]
endpoint = "https://mandible.internal:50052"
tls_cert_path = "/etc/mantis/certs/client.crt"
tls_key_path = "/etc/mantis/certs/client.key"
tls_ca_cert_path = "/etc/mantis/certs/ca.crt"
[queue]
enabled = true
host = "rabbitmq.internal"
port = 5671
username = "mantis"
password = "secret"
ca_cert_path = "/etc/mantis/certs/rabbitmq-ca.crt"
[cluster]
enabled = true
redis_url = "redis://redis.internal:6379"
namespace = "mantis-prod"