Repository navigation
Proxy-mode baseline enrichment overrides include_workdir: false — workdir added to read_write unconditionally #905
Description
Activity
🏗️ build-plan
Implementation Plan
Issue type:
fix
Complexity: Low
Confidence: High — clear pathSummary
The regression is in proxy-mode baseline filesystem enrichment inside
crates/openshell-sandbox/src/lib.rs. The fix should preserve explicitread_onlyintent when a baseline read-write path like/sandboxis already present inread_only, so proxy enrichment no longer promotes that path to writable access in either the proto or local-policy code paths.Scope
crates/openshell-sandbox/src/lib.rs: update proxy baseline enrichment so explicitread_onlyentries take precedence over baselineread_writeadditions, and keep the proto and localSandboxPolicyenrichment flows consistent.crates/openshell-sandbox/src/lib.rstests: add regression coverage for policies that setinclude_workdir: falseand explicitly place/sandboxinread_only, ensuring enrichment does not add it toread_write.architecture/sandbox.mdandarchitecture/security-policy.md: document that baseline enrichment skips system-injectedread_writepromotions when the same path is explicitly configured asread_only.
Implementation Steps
- Adjust the proxy baseline enrichment logic so a baseline
read_writepath is skipped when that path already exists inread_only, preserving explicit operator intent. - Apply the same precedence rule to both
enrich_proto_baseline_paths()andenrich_sandbox_baseline_paths()so gRPC-delivered and local-file policies behave the same way. - Add unit tests covering the
/sandboxregression and the general "explicit read-only beats baseline read-write" behavior. - Update the relevant architecture docs to describe the precedence rule.
Test Plan
- Unit tests: Extend
crates/openshell-sandbox/src/lib.rstests to verify enrichment leaves/sandboxread-only when it is explicitly configured there, and that no overlappingread_only/read_writeentry is introduced by enrichment. - Integration tests: N/A — the behavior is isolated to enrichment helpers and existing unit-test coverage is the right level.
- E2E tests: N/A — no
e2e/changes are expected for this fix.
Risks & Open Questions
- The main risk is fixing only the proto path and leaving the local-file
SandboxPolicyenrichment path inconsistent. The implementation should keep both helpers aligned. /tmpshould remain baseline writable unless a policy explicitly marks it read-only; the change should not reduce baseline access more broadly than intended.
Documentation Impact
- Update
architecture/sandbox.mdandarchitecture/security-policy.mdto reflect that explicitread_onlypolicy entries override system-injected baselineread_writeenrichment.
Revision 1 — initial plan
- addedstate:agent-readyApproved for agent implementationApproved for agent implementationstate:in-progressWork is currently in progressWork is currently in progress
on Apr 21, 2026 🏗️ build-from-issue-agent
Implementation Complete
PR: #910
What was built
Proxy-mode baseline enrichment now preserves explicit
read_onlyfilesystem intent instead of promoting the same path intoread_write. The fix covers both proto-backed and local-file policy enrichment and adds regression tests for each code path.Tests
- Unit: 2 tests added
- Integration: N/A
- E2E: N/A
Docs updated
architecture/sandbox.mdarchitecture/security-policy.md
The issue will auto-close when the PR is merged.
- addedstate:pr-openedPR has been opened for this issuePR has been opened for this issueand removedstate:in-progressWork is currently in progressWork is currently in progressstate:review-readyReady for human reviewReady for human review
on Apr 21, 2026 - added a commit that references this issue
on Apr 21, 2026 - added a commit that references this issue
on Apr 22, 2026
Summary
When a sandbox policy sets
include_workdir: falseand places the workdir (e.g./sandbox) inread_only, the proxy-mode baseline enrichment inenrich_proto_baseline_paths()unconditionally adds/sandboxtoread_write, defeating the policy's read-only intent.Landlock grants the union of matching rules, so
/sandboxappearing in bothread_onlyandread_writeresults in full write access — the opposite of what the policy requested.Related
prepare()correctly respectsinclude_workdir: false, but the enrichment runs beforeprepare()and doesn't check the flag.Root Cause
The hardcoded proxy baseline in
enrich_proto_baseline_paths():This adds
/sandboxtoread_writeif it's not already in theread_writelist. It does not check:include_workdirisfalseread_only(indicating deliberate read-only intent)Flow
/sandboxinread_only,include_workdir: false,rw: 4pathsenrich_proto_baseline_paths()adds/sandboxtoread_write→rw: 5(logged asCONFIG:ENRICHED)prepare()checksinclude_workdir— it'sfalse, so it doesn't add workdir again (but it's already there from step 2)/sandboxin bothread_onlyandread_write→ Landlock union =read_writerestrict_self()enforces — Landlock is active but/sandboxis writableEvidence from Testing (OpenShell 0.0.29, NemoClaw sandbox)
Landlock IS enforced (confirming #810 fix works):
But workdir is writable despite read_only policy intent:
Policy delivered by gateway (correct):
Policy after enrichment (incorrect):
Startup log confirms no fallback to container-disk policy:
Suggested Fix
In
enrich_proto_baseline_paths(), before adding a baseline path toread_write:include_workdirisfalseand the path matches the workdir — if so, skip itread_only— if so, respect the explicit read-only intent and don't promote itOption 2 is more general and handles cases beyond just the workdir.
Environment