Last Updated: 2025-11-30
Harmony supports environment variable substitution in all TOML configuration values. This allows you to externalize sensitive data, deployment-specific settings, and other configuration that varies across environments.
Use $VARIABLE_NAME to reference environment variables in any TOML value:
[proxy]
id = "$PROXY_ID"
[network.default.http]
bind_address = "$BIND_ADDRESS"
bind_port = $BIND_PORT
[backends.remote]
service = "http"
[backends.remote.options]
url = "https://$REMOTE_HOST:$REMOTE_PORT/api"Valid variable names must:
- Start with a letter or underscore
- Contain only alphanumeric characters and underscores
- Examples:
$VAR,$VAR_NAME,$_VAR123 - Invalid:
$123VAR(starts with number),$MY-VAR(contains hyphen)
If variable is set: Replaced with its value
export HOST=example.com
# $HOST in config becomes: example.comIf variable is not set: Replaced with empty string and warning logged
url = "https://$UNDEFINED_VAR/api" # becomes: https:///api (warning logged)Escaped dollar signs: Use $$ to represent a literal $ character
description = "Cost is $$100" # becomes: Cost is $100[backends.production]
service = "http"
[backends.production.options]
url = "https://api.example.com"
api_key = "$API_KEY"Set at runtime:
export API_KEY="secret_key_xyz"
cargo run -- --config config/config.toml[network.default.http]
bind_address = "$BIND_ADDRESS"
bind_port = $BIND_PORT
[proxy]
id = "harmony-$ENVIRONMENT"Run different environments:
# Development
export BIND_ADDRESS=127.0.0.1 BIND_PORT=8080 ENVIRONMENT=dev
cargo run -- --config config/config.toml
# Production
export BIND_ADDRESS=0.0.0.0 BIND_PORT=443 ENVIRONMENT=prod
./harmony --config /etc/harmony/config.tomlurl = "$PROTOCOL://$HOST:$PORT/path"
# becomes: https://example.com:443/path (if PROTOCOL=https, HOST=example.com, PORT=443)- Use meaningful variable names:
$API_KEYinstead of$K,$BIND_ADDRESSinstead of$BA - Document required variables: Include a
.env.exampleor README section listing all expected environment variables - Use default values in scripts: Wrap your startup in a shell script that sets defaults
#!/bin/bash export BIND_ADDRESS=${BIND_ADDRESS:-127.0.0.1} export BIND_PORT=${BIND_PORT:-8080} exec /path/to/harmony --config config.toml
- Never commit secrets: Use
.gitignoreto exclude.envfiles - Log warnings: Check logs during startup to catch missing variables early
- Mark critical variables as required: Use
required_env_varsin[proxy]section to enforce presence of critical variables[proxy] id = "harmony" required_env_vars = ["API_KEY", "DATABASE_PASSWORD"]
- Use systemd EnvironmentFile or similar: Instead of exporting secrets in shell, use secure credential management systems
- Rotate secrets regularly: Check your secret management and rotation policies
- Validate logs: Ensure sensitive values don't leak into logs (only variable names are logged)
Metadata Disclosure
- Environment variable references are visible in your config files
- Restrict config file permissions:
chmod 600 config.tomlorchmod 400 config.toml(read-only after deployment) - Configuration files should not be committed to version control if they contain
$VAR_NAMEreferences for sensitive values
Missing Variables
- By default, missing environment variables are replaced with empty strings
- Check startup logs for warnings about missing variables:
Environment variable 'X' not found - Use
required_env_varsin your config to enforce critical variables and fail fast if they're missing
Value Validation
- Environment variable values are substituted as-is into TOML
- Ensure your values don't contain TOML metacharacters (newlines, unescaped quotes) or they may break configuration
- Startup validation (see below) can help catch malformed values
Process Environment Visibility
- On some systems, environment variables are visible to other users via
ps auxor/proc - For highly sensitive secrets, consider using:
- systemd
EnvironmentFilewith restricted permissions - HashiCorp Vault or cloud provider secret managers (AWS Secrets Manager, Azure Key Vault)
- Docker secrets or Kubernetes secrets for containerized deployments
- systemd
Audit Trail
- Substituted variable names are logged at INFO level during startup
- Missing variables are logged at WARN level during startup
- Example logs:
[INFO] Substituted 3 environment variables: API_KEY, DATABASE_PASSWORD, JWT_SECRET [WARN] 1 environment variable not found: MISSING_CONFIG_VAR - Review startup logs to verify which variables were actually substituted
Validation Command
Test your configuration without starting the server:
./harmony --config config.toml --validate-config
# Output:
# ✓ Configuration is valid
# ✓ All required environment variables present
# ✓ Substituted 3 environment variables
# Exit code: 0This validates that:
- All required variables are present
- Configuration can be parsed after substitution
- No risky values detected in environment variables
Harmony uses a two-layer configuration model:
- Top-level config: Networks, providers, logging, service registrations
- Pipeline files: Endpoints, middleware, backends, routing rules, and ingress/egress definitions
- Mesh files: Mesh definitions that group ingress/egress for inter-proxy communication
Protocol adapters (HTTP, DIMSE, etc.) are automatically spawned based on pipeline configurations. See adapters.md for details.
All configuration is validated against formal schemas defined in harmony-dsl. For detailed technical reference, see:
- Configuration Schemas - Overview of all harmony configuration schemas
- Mesh Configuration - Data mesh networking and ingress/egress definitions
- Providers - Provider configuration for resource resolution and cloud polling
- Resource References - Reference syntax for cross-provider resources
Top-level config (typically config.toml):
[proxy]: Service identity, paths (pipelines, transforms, mesh), limits, and cloud polling[provider.*]: Provider configurations for resource resolution and polling[management]: Management API settings[network.<name>]: Network interface configurations[network.<name>.http]: HTTP/1.x and HTTP/2 listener settings[network.<name>.http3]: HTTP/3 (QUIC) listener settings
[logging]: File logging and log level configuration[runbeam]: [DEPRECATED] Legacy Runbeam Cloud settings (use[provider.runbeam]instead)
Pipeline files (typically in pipelines/ directory):
[pipelines.<name>]: Pipeline definition grouping endpoints, middleware, backendsnetworks: List of network names to bind this pipeline toendpoints: Endpoints this pipeline handlesmiddleware: Ordered middleware chainbackends: Backend targets
[pipelines.<name>.mesh.ingress.*]: Ingress definitions (URLs → endpoints)[pipelines.<name>.mesh.egress.*]: Egress definitions (backends → mesh targets)[middleware.<name>]: Middleware configuration[endpoints.<name>]: Endpoint configuration[backends.<name>]: Backend configuration[targets.<name>]: Concrete destinations for backends
Mesh files (typically in mesh/ directory):
[mesh.<name>]: Mesh definition grouping ingress/egress with authentication
Ingress and egress are nested within pipeline files, while mesh definitions group them in separate mesh files. See Mesh Configuration for complete documentation.
Adapters are started automatically based on configuration:
- HttpAdapter: For HTTP/FHIR/JMIX/DICOMweb endpoints (TCP: HTTP/1.x, HTTP/2, optional TLS)
- Http3Adapter: For networks with HTTP/3 configuration (QUIC-based, requires TLS)
- DimseAdapter: For DICOM DIMSE endpoints
- See
src/lib.rs::run()for orchestration logic
- Networks must define valid HTTP bind_address and non-zero bind_port
- HTTP/3 networks must specify valid cert_path and key_path for TLS
- HTTPS networks must specify both cert_path and key_path
- Each pipeline should reference at least one network, endpoint, and backend
- Mesh definitions must reference valid ingress/egress definitions
- If ingress/egress specify endpoint/backend overrides, those must exist in the pipeline
- All referenced providers must be configured
- Unknown middleware names cause validation failure
- Minimal passthrough: examples/default/pipelines/default.toml
- FHIR passthrough: examples/default/pipelines/fhir.toml
- FHIR to DICOM flow: examples/default/pipelines/fhir-dicom.toml
- Data mesh: examples/default/pipelines/data-mesh/ (includes mesh/, pipelines/, config.toml)
[network.default]
interface = "wg0"
enable_wireguard = false
[network.default.http]
bind_address = "0.0.0.0"
bind_port = 8080To enable HTTPS on the HTTP adapter, add both cert_path and key_path to the TCP configuration:
[network.secure]
interface = "wg0"
enable_wireguard = false
[network.secure.http]
bind_address = "0.0.0.0"
bind_port = 443
cert_path = "/etc/harmony/certs/fullchain.pem"
key_path = "/etc/harmony/certs/privkey.pem"Requirements:
- Both
cert_pathandkey_pathmust be provided to enable HTTPS - Certificate and private key must be in PEM format
- Supported key formats: PKCS#8 (preferred) and RSA PKCS#1 (legacy)
- The adapter automatically uses TLS 1.3 with HTTP/1.1 and HTTP/2 ALPN
To force all HTTP requests to redirect to HTTPS, use the force_https option:
[network.redirect]
interface = "wg0"
enable_wireguard = false
[network.redirect.http]
bind_address = "0.0.0.0"
bind_port = 80
force_https = trueBehavior:
- Returns HTTP 301 (Moved Permanently) redirect to
https://URL - Only applies when TLS is NOT configured (no
cert_path/key_path) - Preserves the original path and query parameters
- Uses the
Hostheader to construct the HTTPS URL
Common Use Case: Run two networks - one on port 80 with force_https = true to redirect, and one on port 443 with TLS certificates to handle HTTPS requests.
Certificate Generation (for testing):
# Generate self-signed certificate for testing
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout key.pem -out cert.pem -days 365 \
-subj "/CN=localhost"Production Certificates:
- Use Let's Encrypt (certbot) for free production certificates
- Or obtain certificates from your organization's certificate authority
- Ensure certificates are renewed before expiration
Supported Key Formats:
- PKCS#8 unencrypted (RSA and ECDSA) - preferred format
- RSA PKCS#1 unencrypted (legacy format)
Supported Key Algorithms:
- RSA (2048, 3072, 4096 bit)
- ECDSA (P-256, P-384, P-521 curves)
Encrypted Keys Not Supported:
Harmony does not support encrypted private keys (PKCS#8 with PBES2 or encrypted RSA PKCS#1). If you have encrypted keys, decrypt them first:
# Decrypt PKCS#8 encrypted key
openssl pkcs8 -in encrypted_key.pem -out key.pem
# Decrypt RSA encrypted key (legacy format)
openssl rsa -in encrypted_rsa_key.pem -out key.pem
# Secure the unencrypted key
chmod 600 key.pem
chown harmony:harmony key.pem # If running as harmony userWhy No Encrypted Key Support?
Encrypted keys with passwords stored in configuration files provide no real security benefit:
- Password stored alongside encrypted key = no protection
- Industry best practice is unencrypted keys with filesystem permissions
- Modern deployments use secret management systems instead
Security Best Practices:
-
File System Permissions (primary security mechanism):
chmod 600 /etc/harmony/certs/privkey.pem chown harmony:harmony /etc/harmony/certs/privkey.pem
-
Secret Management Systems (recommended for production):
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
- Google Cloud Secret Manager
-
Container Deployments:
- Docker secrets:
docker secret create harmony_key key.pem - Kubernetes secrets: mount as read-only volume
- Environment variable injection (base64 encoded)
- Docker secrets:
-
Automated Certificate Management:
- Use certbot with Let's Encrypt for automatic renewal
- Set up hooks to reload Harmony after certificate renewal
- Monitor certificate expiration dates
-
Hardware Security Modules (HSM):
- For highly sensitive environments, use HSM-backed certificates
- Consider cloud provider HSM services (AWS CloudHSM, Azure Dedicated HSM)
-
Key Rotation:
- Rotate private keys periodically (e.g., annually)
- Use hot reload to apply new certificates without downtime
- Keep backup of old keys during rotation period
Example Production Setup:
# 1. Store key in secret manager
aws secretsmanager create-secret \
--name harmony-tls-key \
--secret-string file://privkey.pem
# 2. Retrieve at container startup
aws secretsmanager get-secret-value \
--secret-id harmony-tls-key \
--query SecretString \
--output text > /run/secrets/privkey.pem
# 3. Set permissions
chmod 600 /run/secrets/privkey.pem
# 4. Start Harmony
./harmony --config /etc/harmony/config.toml[network.http3_network]
interface = "wg0"
enable_wireguard = false
[network.http3_network.http3]
bind_address = "0.0.0.0"
bind_port = 443
cert_path = "/etc/harmony/certs/fullchain.pem"
key_path = "/etc/harmony/certs/privkey.pem"HTTP/3 always uses TLS and requires certificates. It runs over UDP instead of TCP.
You can run both plain HTTP and HTTPS by configuring multiple networks:
# Plain HTTP for internal traffic
[network.internal]
interface = "wg0"
enable_wireguard = false
[network.internal.http]
bind_address = "127.0.0.1"
bind_port = 8080
# HTTPS for external traffic
[network.external]
interface = "wg0"
enable_wireguard = false
[network.external.http]
bind_address = "0.0.0.0"
bind_port = 443
cert_path = "/etc/harmony/certs/fullchain.pem"
key_path = "/etc/harmony/certs/privkey.pem"Then configure your pipelines to use the appropriate network:
[pipelines.internal_api]
networks = ["internal"]
endpoints = ["api"]
backends = ["backend"]
middleware = { incoming = [], outgoing = [] }
[pipelines.external_api]
networks = ["external"]
endpoints = ["api"]
backends = ["backend"]
middleware = { incoming = ["jwt_auth"], outgoing = [] }Status: Available since v0.4.0
Harmony supports hot-reloading configuration changes without requiring a full application restart. Changes are automatically detected and applied based on their impact.
The config file watcher monitors your configuration file for changes with a 200ms debounce. When changes are detected:
- Validation: New config is validated before applying
- Diff Computation: Changes are classified into categories
- Apply Strategy:
- Zero-downtime changes: Atomic config swap (instant)
- Adapter restarts: Selective restart of affected networks only
- Logging: Reload results logged with details
These changes are picked up on the next request with no service interruption:
- Middleware configuration: Transform specs, auth rules, custom middleware options
- Route definitions: Groups, endpoints, backends, path patterns
- Backend configuration: Target URLs, timeouts, retry policies
- Logging settings: Log levels, file paths, output formats
- Storage configuration: Backend type, paths, connection strings
These changes require restarting specific protocol adapters (~1-2 second interruption for affected networks only):
- Network topology: Bind addresses, bind ports
- Adding/removing networks: New adapters started or old ones stopped
- WireGuard configuration: Interface names, peer settings
- Protocol-specific settings: TLS certificates, connection pool sizes
File watching is enabled by default when you run Harmony:
cargo run -- --config config/config.toml
# or
./harmony --config config/config.tomlSimply edit config/config.toml and save - changes will be detected and applied automatically.
Example 1: Zero-Downtime Change
# Add middleware to existing config
[middleware.my_transform]
type = "transform"
[middleware.my_transform.options]
spec_path = "transforms/my_spec.json"Result: Atomic config swap, next request uses new middleware. No downtime.
Example 2: Adapter Restart
# Change HTTP port
[network.default.http]
bind_address = "127.0.0.1"
bind_port = 8081 # Changed from 8080Result: HTTP adapter for "default" network restarted on new port. DIMSE adapter unaffected. Brief interruption (~1-2s) for HTTP requests on "default" network only.
Example 3: Network Addition
# Add new network
[network.secondary]
interface = "eth1"
[network.secondary.http]
bind_address = "0.0.0.0"
bind_port = 8082Result: New adapters started for "secondary" network. Existing "default" network unaffected.
Example 4: Adding HTTP/3 to a Network
# Add HTTP/3 listener alongside existing HTTP
[network.default.http3]
bind_address = "0.0.0.0"
bind_port = 443
cert_path = "/etc/harmony/certs/fullchain.pem"
key_path = "/etc/harmony/certs/privkey.pem"Result: Http3Adapter started on UDP port 443. Existing HTTP adapter on TCP port 8080 continues running. Both adapters serve the same pipelines.
If the new configuration is invalid:
- Validation errors are logged with details
- Old configuration is retained - application continues running
- No service interruption
Example log output:
❌ Config reload failed: Configuration validation failed
Reason: Network 'default' has invalid bind port
If adapter restart fails:
- Error logged with network name
- Old adapter continues running if possible
- Other networks unaffected
Watch the logs for reload events:
📡 Watching config file for changes: config/config.toml
✓ Config reloaded successfully
Zero-downtime changes: ["middleware", "endpoints"]
Or for adapter restarts:
✓ Config reloaded successfully
Networks restarted: ["default"]
Zero-downtime changes: ["backends"]
- Test config changes locally before deploying to production
- Use zero-downtime changes when possible (middleware, routes, backends)
- Schedule network topology changes during low-traffic periods
- Monitor logs after config changes to verify successful reload
- Keep backups of previous config versions for quick rollback
- Staged rollout: Change non-critical settings first, then network topology
- In-flight requests: Requests active during adapter restart may fail
- No connection draining: Adapters shut down immediately (future enhancement)
- No automatic rollback: Failed partial reloads keep old config but may leave inconsistent state
- No audit trail: Config changes not logged/tracked (future enhancement)
Config changes not detected?
- Verify file watcher is active (check logs for "📡 Watching config file")
- Ensure 200ms debounce period has elapsed
- Check file permissions
Reload failed?
- Check logs for validation errors
- Verify config syntax with
cargo run -- --config config/config.toml --validate(future feature) - Ensure referenced files (transforms, certs) exist
Adapters not restarting?
- Verify network name matches config
- Check for port conflicts
- Review adapter-specific logs
For more details on the hot-reload architecture, see docs/config-reload.md.
Status: Available since v0.4.0
Harmony Proxy provides optional integration with Runbeam Cloud for centralized configuration management. This integration is controlled by the [runbeam] configuration section and is disabled by default.
[runbeam]
enabled = false # Set to true to enable cloud integration
cloud_api_base_url = "https://api.runbeam.cloud" # Optional, defaults to this URL
poll_interval_secs = 30 # Optional, defaults to 30 (valid range: 5-3600)| Field | Type | Default | Description |
|---|---|---|---|
| enabled | bool | false | Enable Runbeam Cloud integration |
| cloud_api_base_url | string | "https://api.runbeam.cloud" | Runbeam Cloud API endpoint |
| poll_interval_secs | u64 | 30 | Cloud polling interval (5-3600 seconds) |
Important: When enabled = false (default):
- No token loading from environment or storage
- No cloud polling at startup
/admin/authorizeendpoint returns 403 Forbidden- Gateway runs in standalone mode without cloud connectivity
Harmony Proxy can automatically poll Runbeam Cloud for configuration changes when running in managed mode. This enables centralized configuration management through the Runbeam Cloud dashboard.
When authorized with a gateway token, Harmony automatically polls the Runbeam Cloud API for pending configuration changes at regular intervals (default: 30 seconds). Changes are downloaded, validated, applied to the local filesystem, and reported back to the Cloud.
Changes are retrieved from the /api/harmony/config-changes endpoint and processed in oldest-first order to maintain correct configuration state progression. This ensures that configuration updates are applied in the sequence they were created.
- Queued: Change is created on Runbeam Cloud and waiting to be fetched by the gateway
- Acknowledged: Gateway has successfully fetched the change details and acknowledged receipt
- Applied: Change successfully validated and applied to gateway configuration
- Failed: Change application failed - error message and details reported back to Cloud
- gateway: Gateway-level configuration (main config file at
/etc/harmony/harmony-config.toml) - pipeline: Pipeline-specific configuration (individual pipeline files in
pipelines/directory)
- Gateway polls Cloud API every 30 seconds (configurable via
--poll-intervalflag) - API returns list of pending changes for this gateway
- Changes processed sequentially in chronological order (oldest first)
- For each change:
- Fetch full change details (including TOML content)
- Acknowledge receipt to Cloud
- Extract and download transforms (if configuration references transform middleware)
- Write TOML config to appropriate file location
- File watcher detects change and triggers hot reload
- Report success/failure back to Cloud
When a cloud-sourced configuration references transform middleware (via spec_path in middleware options), Harmony automatically downloads the JOLT specifications before applying the configuration:
- Extract Transform IDs: Parse the TOML configuration to find all transform middleware sections
- Download Specifications: For each transform ID, call the Runbeam Cloud Transform API to retrieve the JOLT specification
- Write to Disk: Save transform files to the configured
transforms_pathdirectory (default:transforms/) - Overwrite Existing: Transform files with the same ID are overwritten with the latest version
- Validate Before Apply: If any transform download fails, the entire config change is marked as failed and reported to Cloud
This ensures that all transform specifications are available and up-to-date before the configuration is applied, preventing runtime errors due to missing transform files.
Example Middleware Configuration:
[middleware.patient_transform]
id = "01k81xgtn1hnbkfseyd82nar0m"
type = "transform"
[middleware.patient_transform.options]
spec_path = "01k81xczrw551e1qj9rgrf0319.json" # Transform ID - automatically downloaded
apply = "both"
fail_on_error = trueThe gateway will automatically download the JOLT specification for transform 01k81xczrw551e1qj9rgrf0319 and save it to transforms/01k81xczrw551e1qj9rgrf0319.json before applying the pipeline configuration.
Cloud polling starts automatically when the gateway is authorized:
# Start harmony with management API enabled
./harmony --config /etc/harmony/harmony-config.toml
# Authorize the gateway (via Management API)
curl -X POST http://localhost:9090/admin/authorize \
-H "Authorization: Bearer <jwt_token>" \
-H "Content-Type: application/json" \
-d '{"gateway_code":"your-gateway-code"}'
# Cloud polling starts automatically after successful authorizationConfiguration Options:
# Enable Runbeam Cloud integration
[runbeam]
enabled = true
cloud_api_base_url = "https://api.runbeam.cloud"
poll_interval_secs = 30 # Optional: polling interval (default: 30, range: 5-3600)
# Management API configuration
[management]
enabled = true
base_path = "/admin"
network = "default"Watch for cloud polling events in logs:
INFO 🌥️ Starting cloud config polling (interval: 30s)
INFO Processing change: id=01k8vdq9..., type=gateway, status=queued, gateway_id=01k8ek6...
INFO ✓ Successfully applied config change 01k8vdq9...
Errors are also logged:
ERROR ✗ Failed to apply config change 01k8vdq9...: Invalid TOML syntax
Validation Failures:
- Invalid TOML configurations are rejected before file system operations
- Error message and details reported back to Cloud
- Previous valid configuration remains active
- Gateway continues processing remaining changes
Network Failures:
- Transient network errors trigger exponential backoff (2s, 4s, 8s, ...up to 5 minutes)
- Gateway continues polling when connectivity restored
- Successful poll resets error counter
Authorization Failures:
- 401/403 errors stop cloud polling (gateway needs re-authorization)
- Token expiry detected automatically
- Warning logged with instructions to re-authorize
Cloud-sourced configuration changes trigger the same hot-reload mechanism as file-based changes:
- Gateway changes: Full config reload with diff computation
- Pipeline changes: Selective reload of affected pipelines
- Zero-downtime changes: Applied immediately without service interruption
- Adapter restarts: Only affected networks restarted
See Hot Configuration Reload for reload behavior details.
- Machine tokens: Stored securely using encrypted filesystem (age X25519 encryption)
- Token validation: Tokens checked for expiry before each poll
- HTTPS required: All Cloud API communication uses TLS
- Configuration integrity: TOML validated before applying to prevent malformed configs
See security.md for comprehensive security guidance.
Polling not starting?
- Verify gateway is authorized: check for
🌥️ Starting cloud config pollingin logs - Check token storage: look for token file in
~/.runbeam/<proxy_id>/auth.json - Verify management API is enabled in config
Changes not applying?
- Check logs for validation errors
- Verify TOML syntax is valid
- Ensure file permissions allow writing to config directory
- Check Cloud dashboard for change status and error messages
Token expired?
- Re-authorize via Management API
/admin/authorizeendpoint - Token expiry logged as warning with instructions
Polling stopped unexpectedly?
- Check for authorization errors (401/403) in logs
- Verify network connectivity to Cloud API
- Check for token validation failures
For more details on cloud polling architecture, see docs/config-reload.md.
Harmony supports several environment variables that affect runtime behavior. Most of these are runtime settings rather than configuration overrides - they don't replace TOML configuration but provide additional context for security, logging, and storage.
Purpose: Provides encryption key for secure machine token storage (encrypted filesystem).
Interaction with Configuration:
- Does not override TOML configuration
- Affects how machine tokens are stored (see Management API authorization)
- Recommended for persistent token storage across restarts
- Typical in container environments
When to Set:
- Production container deployments (recommended)
- Headless/CI environments
- When persistent token storage is needed
See: Security Documentation for generation examples and best practices.
Purpose: Shared secret for validating JWT tokens from Runbeam Cloud during gateway authorization.
Interaction with Configuration:
- Does not override TOML configuration
- Used by Management API
/authorizeendpoint - Falls back to development default if not set (logs warning)
When to Set:
- Required for production Runbeam Cloud integration
- Must match secret configured in Runbeam Cloud
See: Security Documentation for generation and rotation procedures.
Purpose: Controls logging verbosity via tracing filter directives.
Interaction with Configuration:
- Overrides
logging.log_levelsetting in TOML configuration - Environment variable takes precedence when both are set
- More flexible than TOML (supports per-module filtering)
Common Values:
# Override log level for all Harmony modules
export RUST_LOG=harmony=debug
# Per-module filtering (overrides TOML log_level)
export RUST_LOG=harmony::router=trace,harmony::middleware=debug,harmony=info
# Global debug (very verbose)
export RUST_LOG=debugPrecedence: RUST_LOG environment variable > logging.log_level in TOML.
Settings with Environment Variable Override:
- Logging:
RUST_LOGenvironment variable overrideslogging.log_levelin TOML
Settings Without Override (environment variables are supplemental):
- Network configuration: TOML only (bind addresses, ports, WireGuard settings)
- Pipeline definitions: TOML only (endpoints, backends, middleware chains)
- Service configuration: TOML only (service types, options)
- Storage backend: TOML only (filesystem path, backend type)
- Token encryption:
RUNBEAM_ENCRYPTION_KEYsupplements TOML (provides encryption key) - JWT validation:
RUNBEAM_JWT_SECRETsupplements TOML (provides validation secret)
Development:
# Override log level for detailed debugging
export RUST_LOG=harmony=debug,info
# Use TOML for all other configuration
cargo run -- --config examples/basic-echo/config.tomlProduction Containers:
# Set security-sensitive values via environment
export RUNBEAM_ENCRYPTION_KEY=$(cat /run/secrets/encryption-key)
export RUNBEAM_JWT_SECRET=$(cat /run/secrets/jwt-secret)
export RUST_LOG=harmony=info
# Use TOML for application configuration
./harmony --config /etc/harmony/config.tomlWhy This Design?
- Security: Secrets in environment variables (not committed to version control)
- Configuration: Application structure in TOML (version controlled, hot-reloadable)
- Flexibility: Log levels easily adjustable without config file changes
- 12-Factor App: Environment-specific config via environment, app config via files
Notes
- Prefer ./tmp for temporary files rather than /tmp
- For realistic JWT auth configuration, see docs/middleware.md
- For comprehensive environment variable documentation, see Security Documentation