Skip to content

Plugin config (plugins.entries.<id>.config in openclaw.json) is policy-locked at runtime — every config change requires multi-minute image rebuild #2544

@mayank6136

Description

@mayank6136

Summary

In plain English: OpenClaw plugins read their config from plugins.entries.<id>.config in /sandbox/.openclaw/openclaw.json. NemoClaw's sandbox policy makes that whole directory read-only at runtime (Landlock-enforced). So a plugin like <observability-plugin> 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.<id>.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.<id>.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.<id>.config structure, only specifying overrides:

{
  "plugins": {
    "entries": {
      "<observability-plugin>": {
        "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:

openshell sandbox create --name foo --env "OTEL_EXPORTER_OTLP_ENDPOINT=https://..." --from <Dockerfile>

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/<plugin-id>.json): requires changes to every plugin's loader; not portable.

Repro

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: policyNetwork policy, egress rules, presets, or sandbox policyintegration: openclawOpenClaw integration behavior
    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions