Summary
In plain English: plugin config (plugins.entries.<id>.config) is sourced from openclaw.json at startup — and that file is in a directory that NemoClaw makes read-only by Landlock policy at runtime. So a plugin like <observability-plugin> that needs per-deployment config (OTLP endpoint, service name, etc.) cannot be reconfigured after the sandbox is built; every config change requires a full image rebuild. There's no env-var override path and no writable-overlay path documented.
Companion issue planned against NVIDIA/NemoClaw to make plugin config writable from the policy side; this is the OpenClaw-core angle on the same problem.
Problem
The OpenClaw config schema currently sources plugin config from a single location: plugins.entries.<id>.config in openclaw.json. That file is in /sandbox/.openclaw/openclaw.json in NemoClaw, which is Landlock-RO at runtime per sandbox security policy. So:
- Editing the file at runtime → EACCES, no useful diagnostic.
- Plugin code can't read overrides from anywhere else.
- Change config = full image rebuild (~5–10min).
For plugins that follow OTel ecosystem conventions, this is particularly awkward: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, etc. are well-established standard env-vars, and the OpenTelemetry SDK reads them automatically. But the plugin can't pass them through if OpenClaw's config layer doesn't surface them — and OpenClaw's plugin-config schema currently has no env-var overlay support.
Suggested fix (in priority order)
1. Env-var overrides for plugin config
Allow plugins to declare which env vars override which config keys. Either:
- Schema-level:
plugins.entries.<id>.configEnv: { endpoint: "OTEL_EXPORTER_OTLP_ENDPOINT" } — OpenClaw resolves env-vars at startup, applies to config.
- Or: pass
process.env through to plugin's register(api) so the plugin can read its own env-vars.
2. Writable-overlay path for plugin config
Allow plugin config to source from a writable path AS WELL AS openclaw.json. e.g., /sandbox/.openclaw-data/plugin-config.json (which IS writable in NemoClaw) overlaid on top of openclaw.json. Plugin sees the merged result.
3. (Minimum) document the build-time-only constraint
If neither of the above is acceptable, at least document that plugin config is build-time-only in policy-locked environments and explain how plugins should be developed accordingly (e.g., consume only env vars, or expose a runtime config endpoint).
Repro
# 1. Build a NemoClaw sandbox with deep-observability plugin baked in (per
# project setup; openclaw.json baked at build time with plugin config block).
# 2. Try to edit openclaw.json at runtime:
openshell sandbox exec -n nemoclaw-deepobs -- /bin/bash -c '
sed -i "s|http://172.17.0.1:14318|https://example.com|" /sandbox/.openclaw/openclaw.json
'
# Output: sed: cannot rename /sandbox/.openclaw/sed3iy3v: Operation not permitted
# 3. The OPS path is to rebuild the image. Multi-minute round-trip per config tweak.
Why it matters
This compounds with the deploy/docker-compose architectural mismatch — when users debug span-not-landing issues under NemoClaw, they want to try different OTel endpoint configurations. Each attempt is a full image rebuild. The iteration cost discourages diagnosis. Eight cycles of "tweak endpoint → rebuild → test → no change" is what we did during this run; it didn't have to be that painful.
Alternatives considered
- Hot-reload of openclaw.json: doesn't help if the file is RO at runtime.
- Plugins read their own config independently from openclaw.json: breaks the unified-config contract that's already established.
Test plan
After fix #1 (env-var overrides):
- Plugin config has
endpoint: "http://default-endpoint" baked in.
- Set
OTEL_EXPORTER_OTLP_ENDPOINT=http://override.example.com in the sandbox env (via openshell sandbox-create env injection).
- Plugin's actual exporter URL should be
http://override.example.com/v1/traces.
- Restart sandbox → endpoint persists per env, no image rebuild.
Risk / blast radius
- Env-var overrides: medium risk for plugins that read config without expecting env-overlay (could surprise on existing deployments). Mitigated by making it opt-in at the plugin level (plugin declares which keys are env-overridable).
- Writable-overlay: small risk; opt-in via config schema change.
- Docs-only: zero risk.
Open questions for maintainers
- Is there architectural intent to keep plugin config strictly file-based? If so, what's the path forward for policy-locked environments?
- Companion: a
NVIDIA/NemoClaw issue is planned suggesting NemoClaw expose a writable overlay path for plugin config. Which fix-side is preferred?
- The OTel ecosystem env-var conventions (
OTEL_EXPORTER_OTLP_ENDPOINT, etc.) are well-established. Acceptable to lean on those rather than invent OpenClaw-specific ones?
Tested-against
- OpenClaw v2026.4.9
- NemoClaw v0.0.26 / OpenShell 0.0.36 (sandbox provider with Landlock RO)
Severity
Medium. Doesn't block functionality, but it's a development-velocity tax that compounds with other plugin issues. Anyone iterating on plugin config under NemoClaw will hit it.
Summary
Problem
The OpenClaw config schema currently sources plugin config from a single location:
plugins.entries.<id>.configinopenclaw.json. That file is in/sandbox/.openclaw/openclaw.jsonin NemoClaw, which is Landlock-RO at runtime per sandbox security policy. So:For plugins that follow OTel ecosystem conventions, this is particularly awkward:
OTEL_EXPORTER_OTLP_ENDPOINT,OTEL_SERVICE_NAME, etc. are well-established standard env-vars, and the OpenTelemetry SDK reads them automatically. But the plugin can't pass them through if OpenClaw's config layer doesn't surface them — and OpenClaw's plugin-config schema currently has no env-var overlay support.Suggested fix (in priority order)
1. Env-var overrides for plugin config
Allow plugins to declare which env vars override which config keys. Either:
plugins.entries.<id>.configEnv: { endpoint: "OTEL_EXPORTER_OTLP_ENDPOINT" }— OpenClaw resolves env-vars at startup, applies to config.process.envthrough to plugin'sregister(api)so the plugin can read its own env-vars.2. Writable-overlay path for plugin config
Allow plugin config to source from a writable path AS WELL AS
openclaw.json. e.g.,/sandbox/.openclaw-data/plugin-config.json(which IS writable in NemoClaw) overlaid on top ofopenclaw.json. Plugin sees the merged result.3. (Minimum) document the build-time-only constraint
If neither of the above is acceptable, at least document that plugin config is build-time-only in policy-locked environments and explain how plugins should be developed accordingly (e.g., consume only env vars, or expose a runtime config endpoint).
Repro
Why it matters
This compounds with the deploy/docker-compose architectural mismatch — when users debug span-not-landing issues under NemoClaw, they want to try different OTel endpoint configurations. Each attempt is a full image rebuild. The iteration cost discourages diagnosis. Eight cycles of "tweak endpoint → rebuild → test → no change" is what we did during this run; it didn't have to be that painful.
Alternatives considered
Test plan
After fix #1 (env-var overrides):
endpoint: "http://default-endpoint"baked in.OTEL_EXPORTER_OTLP_ENDPOINT=http://override.example.comin the sandbox env (via openshell sandbox-create env injection).http://override.example.com/v1/traces.Risk / blast radius
Open questions for maintainers
NVIDIA/NemoClawissue is planned suggesting NemoClaw expose a writable overlay path for plugin config. Which fix-side is preferred?OTEL_EXPORTER_OTLP_ENDPOINT, etc.) are well-established. Acceptable to lean on those rather than invent OpenClaw-specific ones?Tested-against
Severity
Medium. Doesn't block functionality, but it's a development-velocity tax that compounds with other plugin issues. Anyone iterating on plugin config under NemoClaw will hit it.