Skip to content

Proxy-mode baseline enrichment overrides include_workdir: false — workdir added to read_write unconditionally #905

@prekshivyas

Description

@prekshivyas

Summary

When a sandbox policy sets include_workdir: false and places the workdir (e.g. /sandbox) in read_only, the proxy-mode baseline enrichment in enrich_proto_baseline_paths() unconditionally adds /sandbox to read_write, defeating the policy's read-only intent.

Landlock grants the union of matching rules, so /sandbox appearing in both read_only and read_write results in full write access — the opposite of what the policy requested.

Related

Root Cause

The hardcoded proxy baseline in enrich_proto_baseline_paths():

PROXY_BASELINE_READ_WRITE: ["/sandbox", "/tmp"]

This adds /sandbox to read_write if it's not already in the read_write list. It does not check:

  • Whether include_workdir is false
  • Whether the path is already in read_only (indicating deliberate read-only intent)

Flow

  1. Gateway delivers policy: /sandbox in read_only, include_workdir: false, rw: 4 paths
  2. enrich_proto_baseline_paths() adds /sandbox to read_writerw: 5 (logged as CONFIG:ENRICHED)
  3. prepare() checks include_workdir — it's false, so it doesn't add workdir again (but it's already there from step 2)
  4. Ruleset built with /sandbox in both read_only and read_write → Landlock union = read_write
  5. restrict_self() enforces — Landlock is active but /sandbox is writable

Evidence from Testing (OpenShell 0.0.29, NemoClaw sandbox)

Landlock IS enforced (confirming #810 fix works):

$ touch /dev/shm/test    → Permission denied  (DAC 1777, not in any policy list)
$ touch /var/tmp/test     → Permission denied  (DAC 1777, not in any policy list)

But workdir is writable despite read_only policy intent:

$ touch /sandbox/test               → OK  (should be blocked)
$ touch /sandbox/.openclaw/test     → OK  (should be blocked)
$ touch /sandbox/.local/test        → OK  (should be blocked)

Policy delivered by gateway (correct):

include_workdir: false
read_only: [/sandbox, /sandbox/.openclaw, ...]
read_write: [/tmp, /dev/null, /sandbox/.openclaw-data, /sandbox/.nemoclaw]  # 4 paths

Policy after enrichment (incorrect):

CONFIG:ENRICHED — ro:9 rw:5  (one path added to rw)

Startup log confirms no fallback to container-disk policy:

2026-04-21T16:59:25.188Z INFO openshell_sandbox: Fetching sandbox policy via gRPC
2026-04-21T16:59:25.210Z INFO openshell_sandbox: CONFIG:ENRICHED ...
2026-04-21T16:59:25.212Z INFO openshell_sandbox: CONFIG:PROBED ro:9 rw:5

Suggested Fix

In enrich_proto_baseline_paths(), before adding a baseline path to read_write:

  1. Check if include_workdir is false and the path matches the workdir — if so, skip it
  2. Or: check if the path already exists in read_only — if so, respect the explicit read-only intent and don't promote it

Option 2 is more general and handles cases beyond just the workdir.

Environment

  • OpenShell: 0.0.29
  • Kernel: Linux 6.8.0-1053-gcp (Landlock ABI v4)
  • NemoClaw: alpha (prekshi/openshell-0.0.29-landlock branch)

Metadata

Metadata

Assignees

Labels

state:agent-readyApproved for agent implementationstate:pr-openedPR has been opened for this issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions