diff --git a/packaging/rustbox.toml b/packaging/rustbox.toml index 83430cd..1f374e5 100644 --- a/packaging/rustbox.toml +++ b/packaging/rustbox.toml @@ -39,7 +39,16 @@ default_interface_skin = "apple-mail" sieve_enabled = true diagnostics_enabled = true about_enabled = true -# Browser-facing CSP/frame/referrer/permissions headers. Off by default for compatibility. +# Security headers added by RustBox. Off by default for compatibility. +# +# When enabled: +# - HTML documents receive the full browser security policy +# (CSP, frame protection, referrer/permissions policy, COOP, nosniff). +# - CSS receives only headers that are meaningful for stylesheets. +# - JS/static/API responses receive only headers that are meaningful for +# non-document resources; private API responses use no-store. +# - HSTS is intentionally NOT emitted here. Configure HSTS at the HTTPS +# terminator/reverse proxy, which knows whether the request is really HTTPS. security_headers_enabled = false @@ -153,6 +162,8 @@ sieve_timeout_secs = 10 # Reverse proxy # ----------------------------------------------------------------------------- +# Also used by the administrative diagnostics endpoint to validate forwarded +# client addresses. Do not trust arbitrary Internet-facing proxy ranges. trusted_proxies = "127.0.0.1,::1" @@ -284,6 +295,27 @@ retry_timeout_secs = 60 # kms_key_id = "..." +# ----------------------------------------------------------------------------- +# IMAP synchronization / body cache +# ----------------------------------------------------------------------------- +# +# Periodic synchronization complements IMAP IDLE. The currently watched folder +# can update immediately through IDLE, while this interval is used to reconcile +# counters/flags and to make progress on folders that are not actively open. +# +# Lower values make folder counters converge faster but increase IMAP traffic. +# +[sync] + +# Periodic synchronization interval in seconds. +interval_secs = 30 + +# Maximum number of complete message bodies fetched from IMAP during one +# deep-cache/index pass. Increasing this speeds initial catch-up but increases +# IMAP traffic, disk writes and indexing CPU usage. +deep_index_batch_size = 10 + + # ----------------------------------------------------------------------------- # Search # ----------------------------------------------------------------------------- @@ -306,6 +338,21 @@ retry_timeout_secs = 60 # disabled | local_tantivy | opensearch backend = "local_tantivy" +# Global deep body cache/index policy. +# +# false (recommended production default): +# - RustBox does not force full-message caching for every account. +# - An account may still opt in through its own deep_index setting. +# +# true: +# - RustBox automatically downloads complete message bodies from IMAP and keeps +# them in the local/shared cache so the search backend can fully index content. +# - This can significantly increase IMAP bandwidth, local/S3 storage usage, +# indexing CPU and initial synchronization time for large mailboxes. +# +# This does not control IMAP IDLE itself. +deep_index = false + # Local Tantivy path. path = "/var/lib/rustbox/search" @@ -337,6 +384,86 @@ worker_max_attempts = 12 # password = "change-me" +# ----------------------------------------------------------------------------- +# Administrative system diagnostics endpoint +# ----------------------------------------------------------------------------- +# +# This endpoint is intended for local/cluster troubleshooting and monitoring. +# It is independent from the normal signed-in-user diagnostics UI. +# +# Security model: +# - disabled by default; +# - source IP must match allowed_networks; +# - authentication is additionally required (token or Basic Auth); +# - untrusted source network -> HTTP 403; +# - missing/invalid endpoint credentials -> HTTP 401; +# - backend health can make the diagnostic response report degraded/error. +# +# Behind a reverse proxy, configure trusted_proxies correctly. If forwarded +# client-IP headers are present but the proxy is not trusted, access fails +# closed instead of treating the proxy connection as localhost. +# +# The endpoint NEVER returns configured passwords, access keys, session keys, +# bearer tokens or full credential-bearing DSNs. Secret fields are exposed only +# as configured/not-configured state. +# +# Runtime statistics are intentionally limited to the RustBox process and +# application state. RustBox does not inspect host CPU/RAM/load or /proc for +# this endpoint, keeping it lightweight and portable across supported systems. +# +[diagnostics_endpoint] + +enabled = false + +# Must start with "/api/". +path = "/api/system/diagnostics" + +# Default: localhost only. +# Add explicit internal management networks when required, for example: +# allowed_networks = ["127.0.0.1/32", "::1/128", "10.20.30.0/24"] +allowed_networks = ["127.0.0.1/32", "::1/128"] + +# token | basic +auth = "token" + +# For token authentication uncomment and set a long random secret. +# Keep it outside source control in real deployments, preferably via environment +# configuration/secrets management. +# +# token = "minimum-24-random-characters" + +# For Basic authentication: +# +# auth = "basic" +# basic_username = "rustbox-monitor" +# basic_password = "minimum-16-random-characters" + +# When false, session/account diagnostics avoid exposing user identifiers. +include_user_identifiers = false + +# Timeout used by lightweight dependency probes. +probe_timeout_secs = 5 + +# Sliding security-observation window used to aggregate login failures, +# 401/403/429 responses, 5xx responses and suspicious access patterns. +security_window_secs = 900 + +# The report can include: +# - RustBox version, PID, start time and uptime; +# - effective configuration with secrets redacted; +# - SQL backend/version/pool/schema migration state; +# - Redis/Valkey state when configured; +# - filesystem/S3 blob backend state; +# - Tantivy/OpenSearch state and index health; +# - active sessions and IMAP IDLE/synchronization state; +# - cache/index backlog and worker state; +# - aggregate security signals such as failed logins, 401/403/429/5xx, +# brute-force-like patterns and rejected diagnostic endpoint access. +# +# It intentionally does NOT expose message bodies, passwords, auth headers, +# session secrets, S3 credentials or host-wide resource statistics. + + # ============================================================================= # CLUSTER EXAMPLES # ============================================================================= @@ -358,6 +485,10 @@ worker_max_attempts = 12 # # pgp_enabled = false # +# [sync] +# interval_secs = 30 +# deep_index_batch_size = 10 +# # [storage] # backend = "s3" # bucket = "rustbox" @@ -373,6 +504,7 @@ worker_max_attempts = 12 # # [search] # backend = "opensearch" +# deep_index = false # urls = ["https://opensearch.example.net:9200"] # index_prefix = "rustbox" # required = true @@ -407,6 +539,7 @@ worker_max_attempts = 12 # # [search] # backend = "opensearch" +# deep_index = false # urls = ["https://opensearch.example.net:9200"] # index_prefix = "rustbox" # required = true @@ -430,4 +563,4 @@ worker_max_attempts = 12 # ] # redis_sentinel_master = "mymaster" # redis_sentinel_password = "sentinel-secret" -# redis_password = "secret" \ No newline at end of file +# redis_password = "secret"