Skip to content

Policy: add sandbox posture conformance checks#85572

Merged
giodl73-repo merged 6 commits into
openclaw:mainfrom
giodl73-repo:policy-sandbox-posture-conformance
May 29, 2026
Merged

Policy: add sandbox posture conformance checks#85572
giodl73-repo merged 6 commits into
openclaw:mainfrom
giodl73-repo:policy-sandbox-posture-conformance

Conversation

@giodl73-repo

@giodl73-repo giodl73-repo commented May 23, 2026

Copy link
Copy Markdown
Contributor

Follow-up for reviewer feedback: centralizes the sandbox rule descriptors used by strictness metadata, shape validation, rule detection, and unobservable container-posture evidence so the sandbox policy keys have one shared source.

Adds config-level Policy conformance checks for sandbox posture:

{
  "sandbox": {
    "requireMode": ["all", "non-main"],
    "allowBackends": ["docker", "openshell"],
    "containers": {
      "denyHostNetwork": true,
      "denyContainerNamespaceJoin": true,
      "requireReadOnlyMounts": true,
      "denyContainerRuntimeSocketMounts": true,
      "denyUnconfinedProfiles": true
    },
    "browser": {
      "requireCdpSourceRange": true
    }
  }
}

This stays in the config-conformance lane: it checks authored OpenClaw config and reports drift through policy/doctor findings. It does not inspect live containers, host filesystem permissions, process state, or network state, and it does not add runtime enforcement.

The policy contract is conceptual container posture. The evidence OpenClaw can observe today comes from Docker-backed sandbox config (agents.*.sandbox.docker.*) plus sandbox browser container config (agents.*.sandbox.browser.*). That is why findings may point at Docker config paths even though policy authors write sandbox.containers.*. If a sandbox.containers.* rule is enabled for a sandbox backend that cannot observe that field, policy emits policy/sandbox-container-posture-unobservable against the backend setting instead of silently passing. This finding means the workspace is not conformant to the authored policy: the policy requires a container posture field that the selected backend cannot evidence.

The PR also extends the named scopes.<scopeName> overlay model from #85817 so sandbox posture can be scoped to explicit runtime agentIds. Scope names are descriptive buckets; matching uses the selector values inside the scope. agentIds supports tools, agents.workspace, and sandbox. To express different sandbox posture for Docker, OpenShell, or future backends, define separate agent groups/scopes and leave unsupported container rules unset or false where the backend cannot evidence them:

{
  "scopes": {
    "release-workspace": {
      "agentIds": ["release-agent", "review-agent"],
      "agents": {
        "workspace": { "allowedAccess": ["none", "ro"] }
      }
    },
    "release-lockdown": {
      "agentIds": ["release-agent"],
      "tools": {
        "exec": {
          "allowHosts": ["sandbox"],
          "allowSecurity": ["deny", "allowlist"],
          "requireAsk": ["always"]
        },
        "denyTools": ["exec", "process", "write", "edit", "apply_patch"]
      },
      "sandbox": {
        "requireMode": ["all"],
        "allowBackends": ["docker"],
        "containers": {
          "denyHostNetwork": true,
          "requireReadOnlyMounts": true
        }
      }
    },
    "shell-sandbox": {
      "agentIds": ["shell-agent"],
      "sandbox": {
        "allowBackends": ["openshell"],
        "containers": {
          "requireReadOnlyMounts": false
        }
      }
    }
  }
}

Verification

  • pnpm exec oxfmt --check --threads=1 docs/cli/policy.md docs/plugins/reference/policy.md extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts extensions/policy/src/policy-state.ts
  • pnpm tsgo:extensions
  • node scripts/run-bundled-extension-oxlint.mjs
  • pnpm docs:check-mdx docs/cli/policy.md docs/plugins/reference/policy.md
  • checked for stale sandboxBackends references in the touched policy docs/source/tests
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-85572-sandbox-cut node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot --testTimeout=30000 -> 2 files, 207 tests passed
  • git diff --check
  • ~/.codex/skills/codex-review/scripts/codex-review --mode branch -> no accepted/actionable findings

Real behavior proof

Behavior addressed: Policy can now express sandbox posture requirements for mode, backend, host container networking, container namespace joins, read-only container mounts, container runtime socket mounts, unconfined container profiles, sandbox browser CDP source range, agent-scoped sandbox overlays, and unobservable container-posture findings for backends that cannot evidence enabled container rules.

Real environment tested: WSL Ubuntu 24.04 checkout at /root/src/openclaw-policy-sandbox-posture, using focused policy doctor and CLI tests.

Exact steps or command run after this patch: see Verification commands above.

Evidence after fix: focused tests cover failing sandbox config, passing sandbox config, inherited defaults, per-agent sandbox posture, scoped agentIds overlays, invalid-scope isolation, browser container network posture, browser mount inheritance, sandbox policy typo rejection, unobservable container posture on non-Docker backends, inactive container/browser scoped fallback behavior, mixed-case backend normalization, and strictness metadata for scoped sandbox rules. Docs now cover scoped overlay syntax in docs/cli/policy.md and remove the separate docs/plan/policy-agent-scoped-overlays.md plan page.

Observed result after fix: the focused policy test suite passes with the new scopes.<scopeName>.sandbox.* and agentIds behavior, and the touched code and CLI/plugin docs use the current top-level named scope syntax.

What was not tested: live Docker/browser containers were not launched because this PR intentionally checks config conformance only, not runtime sandbox behavior.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation scripts Repository scripts extensions: openai extensions: policy size: XL maintainer Maintainer-authored PR labels May 23, 2026
@socket-security

socket-security Bot commented May 23, 2026

Copy link
Copy Markdown

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

@giodl73-repo giodl73-repo requested a review from galiniliev May 23, 2026 01:42
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 28, 2026, 11:58 PM ET / 03:58 UTC.

Summary
The PR adds Policy plugin sandbox-posture policy.jsonc keys, sandbox posture evidence scanning, new policy/sandbox-* doctor findings, scoped sandbox overlays, docs, and focused tests.

PR surface: Source +1222, Tests +1077, Docs -74. Total +2225 across 6 files.

Reproducibility: not applicable. this is a feature PR rather than a bug report. The changed behavior is supported by redacted policy-check output and focused Policy doctor/CLI tests.

Review metrics: 1 noteworthy metric.

  • Policy surfaces added: 8 added policy keys; 9 added doctor check IDs. These are new public Policy plugin semantics that can change policy-check results for opted-in workspaces.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] Merging adds new public policy.jsonc sandbox posture keys and new policy/sandbox-* error findings, so opted-in operators can see policy-check failures for existing authored config.
  • [P1] The security posture contract is intentionally config-conformance only; it reports authored config drift and unobservable backends but does not inspect live containers or enforce runtime sandbox state.

Maintainer options:

  1. Land With Accepted Contract (recommended)
    Maintainers can accept the risk after CI because the PR and discussion now explicitly scope sandbox posture to authored-config conformance and unobservable-backend findings.
  2. Tighten Wording First
    If maintainers want less security-boundary ambiguity, require one more docs/body pass emphasizing that the checks do not inspect live containers or enforce runtime state.

Next step before merge

  • [P2] Protected maintainer label plus public Policy/security contract changes make this a human landing decision, not an automated repair lane.

Security
Cleared: No concrete supply-chain, secret-handling, or sandbox-bypass defect was found in the diff; the remaining security issue is an accepted product contract risk.

Review details

Best possible solution:

Land after normal CI once maintainers accept the explicit config-only sandbox posture contract and keep the PR body or squash message clear about the new Policy surface.

Do we have a high-confidence way to reproduce the issue?

Not applicable; this is a feature PR rather than a bug report. The changed behavior is supported by redacted policy-check output and focused Policy doctor/CLI tests.

Is this the best way to solve the issue?

Yes with maintainer acceptance; the Policy plugin is the right owner, and the docs/body clearly frame the feature as config conformance rather than runtime enforcement.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3c8ad8cbaa1b.

Label changes

Label justifications:

  • P2: This is a normal-priority Policy plugin feature with bounded scope but public config/security semantics.
  • merge-risk: 🚨 compatibility: New policy.jsonc sandbox keys and doctor findings can make existing opted-in policy checks fail on upgrade.
  • merge-risk: 🚨 security-boundary: The new sandbox posture language describes security conformance while deliberately limiting enforcement to authored config evidence.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR includes after-fix WSL policy-check output, redacted JSON findings, and focused test results for the config-conformance behavior.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR includes after-fix WSL policy-check output, redacted JSON findings, and focused test results for the config-conformance behavior.
Evidence reviewed

PR surface:

Source +1222, Tests +1077, Docs -74. Total +2225 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 2 1227 5 +1222
Tests 1 1084 7 +1077
Docs 3 187 261 -74
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 2498 273 +2225

What I checked:

Likely related people:

  • giodl73-repo: Authored the merged Policy tool-posture and agent-scoped overlay PRs that this sandbox posture PR builds on. (role: feature-history owner; confidence: high; commits: 1e2e6147480c, fbb63405427a; files: extensions/policy/src/doctor/register.ts, extensions/policy/src/policy-state.ts, docs/cli/policy.md)
  • Peter Steinberger: Current-main blame on the central Policy files points to a recent broad refactor commit touching this area. (role: recent area contributor; confidence: medium; commits: 51b5f75b92f7; files: extensions/policy/src/doctor/register.ts, docs/cli/policy.md)
  • kevinslin: Reviewed this PR's sandbox runtime-socket semantics and identified the Docker-only detection gap that the current head addresses. (role: reviewer; confidence: medium; files: extensions/policy/src/doctor/register.ts, docs/cli/policy.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Pearl Review Wisp

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: finds missing screenshots.
Image traits: location proof lagoon; accessory shell-shaped keyboard; palette cobalt, lime, and pearl; mood mischievous; pose holding its accessory up for inspection; shell soft velvet shell; lighting soft studio lighting; background tiny artifact crates.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Pearl Review Wisp in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@giodl73-repo giodl73-repo force-pushed the policy-sandbox-posture-conformance branch from 74ff672 to 96ddb7a Compare May 23, 2026 22:09
@openclaw-barnacle openclaw-barnacle Bot removed scripts Repository scripts extensions: openai labels May 23, 2026
@giodl73-repo giodl73-repo force-pushed the policy-sandbox-posture-conformance branch 3 times, most recently from 6a58d74 to dc74127 Compare May 24, 2026 22:50

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updated this draft PR on top of the refreshed #85817 stack and addressed the contributor-facing review items.

What changed:

  • Kept sandboxPosture out of the initial no-rule/missing-policy evidence path with a focused assertion.
  • Rebased onto Policy: add agent-scoped policy overlays #85817 head 1b4cb8a53bd so the stack uses the generic agent-scope examples.
  • Updated the PR body with real openclaw policy check --json proof for both failing and passing sandbox posture cases.

Validation run locally in WSL from /root/src/openclaw-85572:

  • node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot -> 2 files, 194 tests passed
  • pnpm exec oxfmt --check docs/cli/policy.md docs/plugins/reference/policy.md docs/plan/policy-agent-scoped-overlays.md extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts extensions/policy/src/policy-state.ts
  • pnpm exec oxlint extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts extensions/policy/src/policy-state.ts
  • pnpm docs:check-mdx docs/cli/policy.md docs/plugins/reference/policy.md docs/plan/policy-agent-scoped-overlays.md
  • git diff --check refs/remotes/fork/policy-agent-scoped-design...HEAD

No merge performed; PR remains draft.

@clawsweeper

clawsweeper Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 24, 2026
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@omarshahine omarshahine left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against 5a33378f9c (the rebase base). Strong implementation — the unobservable-rule design (policy/sandbox-container-posture-unobservable) is the standout: refusing to silently pass when a container rule applies to a backend that can't expose the evidence is exactly the right safety bias for a security-boundary feature. Verbose-but-auditable one-function-per-rule pattern is the correct tradeoff here. Tests, docs, evidence/check separation, and the scoped-overlay extension all look great.

Two items before merge:

1. Missing CHANGELOG entry. Needs ## Unreleased### Changes. Suggested wording:

Policy: add sandbox posture conformance checks for sandbox.requireMode, sandbox.allowBackends, container host network / namespace-join / read-only mounts / runtime-socket-mounts / unconfined-profiles, and sandbox browser requireCdpSourceRange, plus scoped overlay support via scopes.<scopeName>.sandbox. Container rules on backends that cannot observe them surface policy/sandbox-container-posture-unobservable instead of silently passing. (#85572)

2. Windows Docker bind parser false-positives on drive-letter destinations. splitPolicyBindSpec / policyBindSeparatorIndex only skip the host-side drive-letter prefix. For a real-world Windows bind like C:\Users\foo:C:\container:ro:

  • policyBindSeparatorIndex correctly finds the : between foo and the destination C:\container:ro, so host = "C:\Users\foo" is right.
  • But rest = "C:\container:ro", then rest.indexOf(":") finds the : after the destination's C (index 1), so options = "\container:ro" instead of "ro", and mode = "rw" instead of "ro".

Result: a false-positive policy/sandbox-container-mount-mode-required finding for legitimately read-only Windows binds with drive-letter destinations. Fix options: (a) re-skip a drive-letter prefix in rest before indexOf(":"), (b) walk all : positions while recognizing the Windows drive pattern on both sides, or (c) document a constraint that Windows binds must use POSIX paths (/c/Users/foo:/c/container:ro). There are no Windows-bind tests today; adding one either way would lock the behavior.

Optional polish (non-blocking)

  • bindHostLooksLikeDockerSocket is Docker-only by name and by implementation. Worth a one-line comment naming the scope, since Podman (/var/run/podman/podman.sock) or containerd (/run/containerd/containerd.sock) would silently pass policy/sandbox-container-runtime-socket-mount if those backends are ever supported.
  • scopedSandboxDefaultDisabledForAgent correctly treats agents not in agents.list[] as "default applies" (matches the documented inheritance behavior), but the code path is identical to "agent in list with no sandbox override". A one-line comment naming both cases would help future readers.
  • pushSandboxPostureEvidence emits a mode entry with value "off" even for unconfigured sandboxes, so requireMode: ["all"] fires policy/sandbox-mode-unapproved against a fresh install. Tested as intentional via "reports sandbox posture denied by policy", which is the right safety bias — but worth saying explicitly in docs/cli/policy.md that policy treats missing sandbox.mode as the implicit default "off".

206 tests pass on the focused vitest run. Mergeable. Once F1 and F2 are addressed this is ready to land — proof: sufficient + ready for maintainer look labels are appropriate.

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed Omar's review on #85572:

  • Fixed policy bind parsing for Windows destination drive letters. C:\Users\foo:C:\container:ro now keeps ro as the mount mode instead of treating the destination drive colon as the options separator.
  • Added a focused regression test covering that bind shape under sandbox.containers.requireReadOnlyMounts.
  • Added the docs note that missing sandbox.mode is treated as implicit off, so sandbox.requireMode: ["all"] reports a fresh/unconfigured sandbox as non-conformant.
  • Added the requested code comment clarifying that the runtime-socket mount check currently observes Docker socket mounts only.

I did not leave a CHANGELOG.md edit in this contributor branch because the repo's release flow owns changelog updates during landing/release. Suggested release-note wording for pickup: Policy: add sandbox posture conformance checks for sandbox mode, backend allowlists, container network/mount/profile posture, browser CDP source ranges, and scoped overlays.

Proof after the fix:

OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-85572-windows-bind-3 OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot --testTimeout=30000
# 2 files passed, 207 tests passed

pnpm exec oxfmt --check --threads=1 docs/cli/policy.md extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts extensions/policy/src/policy-state.ts
# passed

pnpm tsgo:extensions
# passed

node scripts/run-bundled-extension-oxlint.mjs
# 0 warnings, 0 errors

pnpm docs:check-mdx docs/cli/policy.md docs/plugins/reference/policy.md
# passed

git diff --check
# passed

~/.codex/skills/codex-review/scripts/codex-review --mode local
# clean: no accepted/actionable findings reported

@clawsweeper

clawsweeper Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@galiniliev galiniliev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head 4669398b14011115ec5804b660415c820feb648c.

No blocking findings from my pass. The solution looks like the right owner-boundary fix for the stated goal: the Policy plugin observes authored OpenClaw config, reports config drift, and stays out of live container/runtime enforcement. The policy/sandbox-container-posture-unobservable path is also the right safety behavior for security-adjacent policy: a backend that cannot expose container evidence should fail the authored posture claim instead of silently passing it.

Code-quality verdict: I would not collapse the per-rule finding functions into a fully generic evaluator right now. The explicit functions in extensions/policy/src/doctor/register.ts make each security-sensitive rule auditable, and the tests cover the important backend, scope, browser, bind, and Windows-bind cases. That said, the sandbox rule names now repeat across POLICY_RULE_METADATA, shape validation, policyHasSandboxPostureRules, the unobservable-rule list, and the individual finding functions. A small follow-up refactor could define one typed sandbox rule descriptor table for the rule key, policy path, check id, strictness, and observed evidence kind, then keep the current explicit rule functions where they add behavior. That would reduce drift risk without hiding the policy decisions behind too much abstraction.

I could not run a fresh local test pass in this checkout because node_modules is missing and pnpm is not installed here. I reviewed the source, docs, scoped guides, existing review thread, and current CI/PR proof instead.

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@galiniliev thanks, agreed on keeping the explicit finding functions while reducing the repeated sandbox rule key lists.

Pushed 2644cb4b252 with a narrow cleanup:

  • added shared sandbox container rule descriptors for the policy key, check id, and unobservable-evidence label
  • derives sandbox strictness metadata for container rules from that descriptor table
  • reuses the same descriptor table for sandbox policy shape validation and policyHasSandboxPostureRules
  • left the rule-specific finding functions explicit so the individual posture decisions remain auditable

Validation after the change:

  • pnpm exec oxfmt --check --threads=1 extensions/policy/src/doctor/register.ts
  • pnpm tsgo:extensions
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-85572-sandbox-review node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot --testTimeout=30000 -> 2 files, 207 tests passed
  • git diff --check

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@kevinslin

Copy link
Copy Markdown
Contributor

can we expand to support non-docker sockets?

**Findings**

- **[major] `denyContainerRuntimeSocketMounts` only detects Docker sockets.**  
  `extensions/policy/src/doctor/register.ts:3603` filters runtime-socket findings through `bindHostLooksLikeDockerSocket`, and `extensions/policy/src/doctor/register.ts:3701` says it observes Docker sockets only. But the public policy field is documented as denying “container runtime socket mounts” generally in `docs/cli/policy.md:313`. A bind like `/run/containerd/containerd.sock:/sock:ro` or a Podman socket would not trip this check, and `requireReadOnlyMounts` would also pass because it is `ro`. Either broaden detection to known runtime sockets / blocked runtime directories, or narrow the policy name/docs to Docker sockets.

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@kevinslin agreed. I broadened this instead of narrowing the public policy wording.

Pushed signed commit dfda26c8d0, which changes denyContainerRuntimeSocketMounts to detect common container runtime socket mounts for Docker, containerd, and Podman:

  • /var/run/docker.sock
  • /run/docker.sock
  • /run/containerd/containerd.sock
  • /var/run/podman/podman.sock
  • /run/podman/podman.sock
  • matching socket basenames such as docker.sock, containerd.sock, and podman.sock

I also added focused coverage so read-only containerd/Podman socket binds still fail policy/sandbox-container-runtime-socket-mount. That keeps the policy semantics as "deny container runtime socket mounts" rather than accidentally making it Docker-only.

Proof on current PR head:

pnpm exec oxfmt --check --threads=1 extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts
# passed

git diff --check
# passed

OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-85572-runtime-sockets-head OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot --testTimeout=30000
# 2 files passed, 209 tests passed

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updated signed head: dfda26c8d0.

Change since last review:

  • Broadened sandbox.containers.denyContainerRuntimeSocketMounts from Docker-only socket detection to common container runtime sockets, including Docker, containerd, and Podman socket paths/basenames.
  • Added focused coverage that read-only containerd/Podman socket binds still fail policy/sandbox-container-runtime-socket-mount.

Proof:

  • pnpm exec oxfmt --check --threads=1 extensions/policy/src/doctor/register.ts extensions/policy/src/doctor/register.test.ts
  • git diff --check
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-85572-runtime-sockets-head OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts -- --reporter=dot --testTimeout=30000 -> 2 files, 209 tests passed

@clawsweeper

clawsweeper Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

Copy link
Copy Markdown
Contributor Author

Maintainer approval: I explicitly accept the config-only sandbox posture contract for this PR. The new policy.jsonc sandbox posture keys and policy/sandbox-* findings are intended to evaluate authored OpenClaw config and report unobservable posture for unsupported backends; they do not claim live container inspection or runtime enforcement. The compatibility/security-boundary risk is understood and accepted for this Policy plugin conformance surface.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation extensions: policy maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants