Plugin config (plugins.entries.<id>.config in openclaw.json) is policy-locked at runtime — every config change requires multi-minute image rebuild
- Dominant language
- TypeScript
- Stars
- 22.5k
- Forks
- 3.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 715
Description
## Summary
> **In plain English:** OpenClaw plugins read their config from `plugins.entries..config` in `/sandbox/.openclaw/openclaw.json`. NemoClaw's sandbox policy makes that whole directory read-only at runtime (Landlock-enforced). So a plugin like `` that requires per-deployment config (OTLP endpoint, service name, etc.) cannot be reconfigured after the sandbox is built — every config change requires a multi-minute image rebuild. NemoClaw should expose a writable overlay path for plugin config so users can iterate without rebuilds.
> Companion issue planned against `openclaw/openclaw` for the OpenClaw-side angle (env-var overrides). This is the NemoClaw-side angle (writable overlay).
## Problem
What a user expects (typical OpenClaw deployment):
1. Edit `openclaw.json` `plugins.entries..config` to point at a different OTel endpoint.
2. Restart the gateway.
3. Done.
What actually happens on NemoClaw:
1. `sed -i` against `openclaw.json` returns `Operation not permitted` (Landlock RO).
2. User has no idea why — no error message, no docs surface mentioning that plugin config is locked.
3. User eventually figures out the file is RO, reconfigures by rebuilding the image.
Worse, the bifurcation is unintuitive: NemoClaw's auto-load from `/sandbox/.openclaw-data/extensions/` works for the *plugin code* (writable). But the plugin's CONFIG lives in the read-only `openclaw.json` next door. Same conceptual asset, two locations, opposite mutability.
## Suggested fix (in priority order)
### 1. Writable overlay for plugin config
Source `plugins.entries..config` from a writable overlay path that overlays on top of `openclaw.json`. e.g.:
```
/sandbox/.openclaw/openclaw.json (RO — base)
/sandbox/.openclaw-data/plugin-config-overlay.json (RW — overlay)
```
Plugin loader merges the overlay onto the base at startup. Users can edit the overlay file at runtime, restart the gateway, get new config — no image rebuild.
The overlay file format mirrors the base's `plugins.entries..config` structure, only specifying overrides:
```json
{
"plugins": {
"entries": {
"": {
"config": {
"endpoint": "https://override.example.com"
}
}
}
}
}
```
Could also support full overrides (flatten everything) if simpler.
### 2. Env-var overrides
Allow the sandbox to inject env vars at create time that override plugin config keys:
```bash
openshell sandbox create --name foo --env "OTEL_EXPORTER_OTLP_ENDPOINT=https://..." --from
```
Plugin config sources from env-var first, then from `openclaw.json`. This is the standard OTel ecosystem pattern (`OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_SERVICE_NAME` are well-known) — leverages established conventions.
This needs OpenClaw-core support (the plugin layer would need to surface env-vars to plugin config); companion issue planned against `openclaw/openclaw`.
### 3. (Minimum) document the build-time-only constraint
If neither overlay nor env-var lands quickly, document explicitly:
- "Plugin config in NemoClaw sandboxes is build-time only."
- "To change plugin config, rebuild the sandbox image."
- "EACCES on `openclaw.json` is by design — Landlock protects the runtime config directory."
This alone removes the "I edited the file, why didn't it work?" confusion.
## Alternatives considered
- **Open up `/sandbox/.openclaw/` to writable in dev-mode preset (companion to A3):** broader; the overlay approach is more surgical.
- **Plugins read config from a different source per plugin (e.g., `/sandbox/.openclaw-data/.json`)**: requires changes to every plugin's loader; not portable.
## Repro
```bash
openshell sandbox exec -n nemoclaw-deepobs -- /bin/bash -c '
sed -i "s|http://172.17.0.1:14318|https://override.example.com|" /sandbox/.openclaw/openclaw.json
'
# Output: sed: cannot rename /sandbox/.openclaw/sed3iy3v: Operation not permitted
# To actually change the config, rebuild the image. ~5–10 min.
```
## Test plan
After fix #1 (overlay):
- Create overlay file in `/sandbox/.openclaw-data/plugin-config-overlay.json` with an endpoint override.
- Restart gateway.
- Plugin's exporter URL should reflect the override, not the base config.
- Restart sandbox without changing the overlay → endpoint persists.
After fix #2 (env-vars):
- Set `OTEL_EXPORTER_OTLP_ENDPOINT=https://...` at sandbox-create.
- Plugin's exporter URL should be the env-var value.
- This works WITHOUT an image rebuild — just sandbox recreate with new env.
## Risk / blast radius
- Overlay path: small; new code path in plugin-config loader, opt-in via overlay file presence.
- Env-var path: requires OpenClaw-core changes (cross-repo coordination).
- Docs-only: zero.
## Open questions for maintainers
1. Companion: a `openclaw/openclaw` issue is filed for env-var overrides. Which side should drive the fix — NemoClaw policy (overlay) or OpenClaw runtime (env-var)? Both?
2. Overlay file location — should it live in `/sandbox/.openclaw-data/` (writable, sandbox-scoped) or `/sandbox/.nemoclaw/` (writable, NemoClaw-scoped)? `.openclaw-data/` matches plugin code's location.
3. Multiple overlays: would users want to layer multiple overlay files (e.g., `dev.json`, `prod.json`, switch via env)? Probably overkill for v1; flag for later.
## Tested-against
- NemoClaw v0.0.26 (Landlock RO at `/sandbox/.openclaw/`)
- OpenClaw v2026.4.9
## Severity
ENHANCEMENT. Workaround (rebuild every change) exists; the iteration cost is the user-pain.
Contributor guide
Assessment
This issue has not been assessed yet.