Technical article
Hardened by default: runtime configuration keys and CLI confirmation semantics
LightESB keeps one platform-level runtime configuration file, ships every optional capability switched off, and makes the CLI ask for --yes on every write. This article condenses the configuration reference and the CLI command reference into the keys, switches, and boundaries that matter for a hardened deployment.
One platform file, strict ownership
Runtime configuration lives in lightesb-camel-app/lightesb-config.properties and can be overridden at startup with java -Dlightesb.config.file=/opt/lightesb/lightesb-config.properties -jar lightesb-camel.jar. It starts the server, loads service packages, connects databases, and enables AI capabilities — and it must never leak into a service package: common.config.properties and service.config.properties describe only that service's own routes, ports, components, and business parameters.
Secrets follow one rule: real API keys, tokens, passwords, certificate paths, and intranet addresses are injected through environment variables or site-controlled secure configuration, never committed to the delivery repository. Service XML reads environment values only through the explicit {{env:ENV_NAME}} form; a plain {{key}} placeholder resolves only against the same service version's common/service configuration — never the platform file, never the environment.
The key landscape: capabilities stay off until enabled
Core runtime
lightesb.route.enabled=true turns on the dynamic route loader and route management API; lightesb.route.directory points at the service-package root. Startup loads routes concurrently on JDK 21 virtual threads (startup.virtual-thread.enabled=true, startup.max-concurrency=16), and hot reload checks file stability first (file-stable-wait-ms=100, file-stable-max-attempts=10).
Off until explicitly enabled
Action catalog, security, audit, allowlist, short-lived tokens, bounded approval, authorization, and execution all default to false and gate each other. So do transformds.enabled, robot.dispatcher.enabled, robot.ai.approval.enabled, ai.logging.enabled, ai.agents.chat.memory.enabled, and poc.h2-fallback.enabled.
Hardened production posture
Turn the H2 console and web-allow-others off. Deployment uploads stay inside quotas: 2000 archive entries, 50 MB per entry, 200 MB extracted total, depth 16. ai.route.model.log-payload stays false outside temporary troubleshooting; per-service log.redaction.enabled scrubs logs before they are persisted.
Environment placeholders only
The bundled template binds secrets to environment variables — dashscope.api-key=${DASHSCOPE_API_KEY:}, mysql.url=${LIGHTESB_MYSQL_URL:}, dispatcher.broker-uri=${ROBOT_MQTT_BROKER_URI:}. Real values never enter the repository.
A hardened excerpt from the reference template:
spring.h2.console.enabled=false
spring.h2.console.settings.web-allow-others=false
lightesb.poc.h2-fallback.enabled=false
lightesb.robot.dispatcher.enabled=false
lightesb.robot.dispatcher.broker-uri=${ROBOT_MQTT_BROKER_URI:}
lightesb.ai.models.default.dashscope.api-key=${DASHSCOPE_API_KEY:}Candidate files and message fields keep their boundaries
Route-sibling resources
For ai route validate/apply, a bare --resource-file name resolves beside the candidate route XML. This lets a prepared directory remain self-contained. Remote apply still requires both properties files and every referenced .ds or fixed schema; session ID and scope digest must be supplied together.
External JSON aliases
Message definitions keep a validated internal nodeName and may add alias for an external field such as same_as_shipping. Schema and sample generation prefer the alias, while persistence and node lookup retain nodeName; sibling names and aliases must remain unique.
CLI semantics: every write is confirmed
Remote CLI commands call the control-plane API — they never host a Camel runtime and never bypass the server-side state machine. Every write operation requires --yes, validates real path boundaries, and replaces target files atomically.
lightesb action build --app-root lightesb-camel-app --out build/action-index.json --yes
lightesb deploy upload ./DemoSrv.zip --yes
lightesb route reload-service --service-name DemoSrv --service-version 1.0.0 --yesThe exit-code contract is stable enough for automation gates: 0 success, 64 missing argument or confirmation, 65 input-file or business-field error (action validate/build add stable ACTION_* codes here), 69 HTTP or server error, 74 IO or network failure, 78 configuration error or failed doctor check.
service start/stop waits for the real Camel context state. The CLI grants it a 130-second HTTP timeout to cover the server's 120-second maximum transition wait; an opposite-direction, failed, or timed-out transition returns HTTP 409 and never rolls back server.running. Automation should query service state or runtime diagnostics before deciding the next step — idempotent=true and transitionReused=true in the result say exactly what the server reused.
Automation boundaries and troubleshooting
action validate/build are fully offline: no server connection, no Camel startup, no hot reload, and build refuses to write its index into any service version directory. doctor runs environment and read-only API checks only. diagnostics snapshot/warnings calls exactly one endpoint — GET /api/diagnostics/runtime-snapshot — and never reads the remote filesystem, triggers reloads or cleanups, or changes log levels.
For scoped troubleshooting, lightesb.route.temp-only-service=PlatformHttp,RobotMqttCommandSrv loads only the named service directories, and startup fails if any of them is missing — no silent fallback to a full load. In a no-MySQL POC, lightesb.poc.h2-fallback.enabled=true moves instance logs, JsonKeyword queries, and the robot command ledger to H2 fallback; confirm it with lightesb diagnostics snapshot --component instance-log --output json and expect pocH2FallbackEnabled=true.
Failure hygiene is part of the contract: HTTP error summaries keep status, error code, and actionable details while redacting token, password, secret, authorization, and apiKey; route config shows sensitive values and absolute paths as <redacted>. When a remote ai route apply ends FAILED, FAILED_ROLLED_BACK, or ROLLBACK_FAILED, the CLI prints the operationId, deleted files, restored state, and logs, then exits 69 — it keeps the local candidate and never retries on its own.