Thorax Configuration
Thorax Configuration
Section titled “Thorax Configuration”Configure the Thorax gRPC orchestration server.
Configuration File
Section titled “Configuration File”Thorax searches for a config file in the following order:
- Path specified by
THORAX_CONFIGenvironment variable thorax.tomlin the current directory/etc/mantis/thorax.toml~/.config/mantis/thorax.toml(platform-dependent config directory)
If no file is found, defaults are used. Environment variables always override file settings.
Configuration Sections
Section titled “Configuration Sections”Top-Level Fields
Section titled “Top-Level Fields”name = "thorax-prod-01"log_level = "info"| Field | Type | Default | Required | Description |
|---|---|---|---|---|
name | string | hostname-derived (e.g., "thorax-<hostname>") | No | Server name for logging. Env: THORAX__NAME |
log_level | string | "info" | No | Log 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"| Field | Type | Default | Required | Description |
|---|---|---|---|---|
auth_mode | string | "thumbprint" | No | Authentication mode: thumbprint (self-signed OK) or ca_signed (CA-signed required). Env: MANTIS_TLS_AUTH_MODE |
cert_path | string | - | Yes | Server certificate PEM file. Env: MANTIS_TLS_CERT_PATH |
key_path | string | - | Yes | Server private key PEM file. Env: MANTIS_TLS_KEY_PATH |
ca_cert_path | string | - | Yes (ca_signed mode) | CA certificate for client verification. Env: MANTIS_TLS_CA_CERT_PATH |
ca_key_path | string | - | No | CA private key for signing client CSRs. Env: MANTIS_TLS_CA_KEY_PATH |
[grpc]
Section titled “[grpc]”gRPC server settings.
[grpc]address = "0.0.0.0"port = 50051max_message_size = 16777216request_timeout_secs = 300| Field | Type | Default | Required | Description |
|---|---|---|---|---|
address | string | "0.0.0.0" | No | Bind address. Env: THORAX__GRPC__ADDRESS |
port | integer | 50051 | No | Listen port. Env: THORAX__GRPC__PORT |
max_message_size | integer | 16777216 (16 MB) | No | Maximum gRPC message size in bytes |
request_timeout_secs | integer | 300 | No | Request timeout (5 minutes) |
[session]
Section titled “[session]”Client session management configuration.
[session]heartbeat_timeout_secs = 90stale_timeout_secs = 300cleanup_interval_secs = 60| Field | Type | Default | Required | Description |
|---|---|---|---|---|
heartbeat_timeout_secs | integer | 90 | No | Mark client offline if no heartbeat (3x heartbeat interval) |
stale_timeout_secs | integer | 300 | No | Time stale before marking offline (5 minutes) |
cleanup_interval_secs | integer | 60 | No | Session 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):
# Set both overrides for an instancecurl -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 unchangedcurl -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_rate_limit]
Section titled “[tls_rate_limit]”TLS handshake failure rate limiting to detect misconfigured clients or attacks.
[tls_rate_limit]enabled = truefailure_threshold = 5window_secs = 60cleanup_interval_secs = 30entry_ttl_secs = 300alert_cooldown_secs = 60| Field | Type | Default | Required | Description |
|---|---|---|---|---|
enabled | boolean | true | No | Enable TLS handshake failure rate limiting |
failure_threshold | integer | 5 | No | Max failures within window before alerting |
window_secs | integer | 60 | No | Sliding window for rate calculation |
cleanup_interval_secs | integer | 30 | No | Cleanup interval for stale IP entries |
entry_ttl_secs | integer | 300 | No | TTL for IP entries after last failure (5 minutes) |
alert_cooldown_secs | integer | 60 | No | Cooldown before re-alerting for same IP |
[console]
Section titled “[console]”Tokio-console settings for async runtime debugging. Only active when the tokio-console feature is enabled.
[console]enabled = trueaddress = "127.0.0.1"port = 6669retention_secs = 60publish_interval_ms = 1000| Field | Type | Default | Required | Description |
|---|---|---|---|---|
enabled | boolean | false | No | Enable the tokio-console server. Env: THORAX__CONSOLE__ENABLED |
address | string | "127.0.0.1" | No | Bind address. Env: THORAX__CONSOLE__ADDRESS |
port | integer | 0 (sentinel) | No | Console 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_secs | integer | 60 | No | How long to retain completed task data. Env: THORAX__CONSOLE__RETENTION_SECS |
publish_interval_ms | integer | 1000 | No | Update interval for connected clients (ms). Env: THORAX__CONSOLE__PUBLISH_INTERVAL_MS |
recording_path | string | - | No | Path to record console data for offline analysis. Env: THORAX__CONSOLE__RECORDING_PATH |
[encryption]
Section titled “[encryption]”Encryption settings for credential protection at rest (AES-256-GCM).
[encryption]key = "base64-encoded-32-byte-key"| Field | Type | Default | Required | Description |
|---|---|---|---|---|
key | string | - | Yes | Base64-encoded 32-byte encryption key. Env: MANTIS_ENCRYPTION_KEY or MANDIBLE__ENCRYPTION__KEY. Generate with: openssl rand -base64 32 |
[mandible]
Section titled “[mandible]”Mandible gRPC client configuration for Thorax-to-Mandible communication. Uses mTLS.
[mandible]endpoint = "https://mandible:50052"connect_timeout_secs = 10request_timeout_secs = 30heartbeat_interval_secs = 30tls_cert_path = "/etc/mantis/certs/client.crt"tls_key_path = "/etc/mantis/certs/client.key"tls_ca_cert_path = "/etc/mantis/certs/ca.crt"| Field | Type | Default | Required | Description |
|---|---|---|---|---|
endpoint | string | "https://localhost:50052" | Yes | Mandible internal gRPC endpoint (must use HTTPS). Env: THORAX__MANDIBLE__ENDPOINT |
connect_timeout_secs | integer | 10 | No | Connection timeout. Env: THORAX__MANDIBLE__CONNECT_TIMEOUT_SECS |
request_timeout_secs | integer | 30 | No | Request timeout. Env: THORAX__MANDIBLE__REQUEST_TIMEOUT_SECS |
heartbeat_interval_secs | integer | 30 | No | Heartbeat interval. Env: THORAX__MANDIBLE__HEARTBEAT_INTERVAL_SECS |
instance_name | string | hostname-derived | No | Instance name for registration |
tls_cert_path | string | - | Yes | Client certificate for mTLS. Env: THORAX__MANDIBLE__TLS_CERT_PATH |
tls_key_path | string | - | Yes | Client private key for mTLS. Env: THORAX__MANDIBLE__TLS_KEY_PATH |
tls_ca_cert_path | string | - | Yes | CA certificate for server verification. Env: THORAX__MANDIBLE__TLS_CA_CERT_PATH |
[queue]
Section titled “[queue]”RabbitMQ queue settings for command consumption. TLS is mandatory.
[queue]enabled = truehost = "rabbitmq.internal"port = 5671username = "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 = 10fallback_on_failure = truereconnect_delay_secs = 5| Field | Type | Default | Required | Description |
|---|---|---|---|---|
enabled | boolean | false | No | Enable 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. |
host | string | "localhost" | No | RabbitMQ host. Env: THORAX__QUEUE__HOST |
port | integer | 5671 | No | AMQPS port (TLS only). Env: THORAX__QUEUE__PORT |
username | string | "" (empty — must be set when enabled) | No | RabbitMQ username. Validation rejects an empty value when enabled = true. Env: THORAX__QUEUE__USERNAME |
password | string | "" (empty — must be set when enabled) | No | RabbitMQ password. Env: THORAX__QUEUE__PASSWORD |
vhost | string | "/" | No | Virtual host. Env: THORAX__QUEUE__VHOST |
ca_cert_path | string | - | Yes (if enabled) | CA certificate for TLS. Env: THORAX__QUEUE__CA_CERT_PATH |
client_cert_path | string | - | No | Client certificate for mTLS. Env: THORAX__QUEUE__CLIENT_CERT_PATH |
client_key_path | string | - | No | Client private key for mTLS. Env: THORAX__QUEUE__CLIENT_KEY_PATH |
prefetch_count | integer | 10 | No | Consumer prefetch count |
fallback_on_failure | boolean | true | No | Fall back to polling when RabbitMQ is unavailable. Env: THORAX__QUEUE__FALLBACK_ON_FAILURE |
reconnect_delay_secs | integer | 5 | No | Reconnection delay after failure. Env: THORAX__QUEUE__RECONNECT_DELAY_SECS |
[cluster]
Section titled “[cluster]”Cluster coordination for multi-Thorax deployments via Redis.
[cluster]enabled = trueinstance_id = "thorax-prod-01"redis_url = "redis://redis:6379"heartbeat_interval_secs = 10liveness_timeout_secs = 30namespace = "thorax"| Field | Type | Default | Required | Description |
|---|---|---|---|---|
enabled | boolean | false | No | Enable cluster coordination. Automatically enabled when RABBITMQ_ENABLED=true. Env: THORAX__CLUSTER__ENABLED, RABBITMQ_ENABLED |
instance_id | string | hostname-derived | No | Instance ID for this Thorax |
redis_url | string | "redis://localhost:6379" | No | Redis connection URL. Env: THORAX__CLUSTER__REDIS_URL |
heartbeat_interval_secs | integer | 10 | No | Heartbeat interval to Redis. Env: THORAX__CLUSTER__HEARTBEAT_INTERVAL_SECS |
liveness_timeout_secs | integer | 30 | No | Timeout before considering instance dead. Env: THORAX__CLUSTER__LIVENESS_TIMEOUT_SECS |
namespace | string | "thorax" | No | Redis key namespace prefix. Env: THORAX__CLUSTER__NAMESPACE |
Environment Variables
Section titled “Environment Variables”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 Variable | Description |
|---|---|
THORAX_CONFIG | Path to config file |
THORAX__NAME | Server name |
MANTIS_LOG_LEVEL | Log level |
THORAX__MANDIBLE__ENDPOINT | Mandible gRPC endpoint (full HTTPS URL, e.g. https://mandible:50052) |
THORAX__GRPC__ADDRESS | gRPC bind address |
THORAX__GRPC__PORT | gRPC port |
MANTIS_TLS_CERT_PATH | Server TLS certificate |
MANTIS_TLS_KEY_PATH | Server TLS private key |
MANTIS_TLS_CA_CERT_PATH | CA certificate |
MANTIS_TLS_CA_KEY_PATH | CA private key |
MANTIS_TLS_AUTH_MODE | TLS auth mode (thumbprint or ca_signed) |
MANTIS_ENCRYPTION_KEY | Encryption key (base64, 32 bytes) |
RABBITMQ_ENABLED | Enable RabbitMQ + cluster mode |
See Environment Variables for complete reference.
Complete Example
Section titled “Complete Example”Production Configuration
Section titled “Production Configuration”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 = truehost = "rabbitmq.internal"port = 5671username = "mantis"password = "secret"ca_cert_path = "/etc/mantis/certs/rabbitmq-ca.crt"
[cluster]enabled = trueredis_url = "redis://redis.internal:6379"namespace = "mantis-prod"Next Steps
Section titled “Next Steps”- Mandible Configuration - REST API server
- Tarsus Configuration - Client agent
- Environment Variables - Variable reference
