openclaw - ✅(Solved) Fix Need documented config keys for disabling plugin/tool/channel/owner-elevated surfaces for proposal-only mode [2 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#80081Fetched 2026-05-11 03:18:57
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
2
Author
Timeline (top)
commented ×2mentioned ×2subscribed ×2cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #80407: Policy: add conformance system with channel checks

Description (problem / solution / changelog)

Policy: add conformance system with channel checks

Branch: policy-channels-consumer GitHub base: main Current draft: https://github.com/openclaw/openclaw/pull/80407 Draft status: channels-first policy PR

Title

Policy: add conformance system with channel checks

Summary

This PR adds policy as a bundled extension for enterprise conformance. It gives operators a workspace artifact for expressing required posture, uses existing OpenClaw settings as the enforcement target, and produces auditable proof that the workspace still matches the requirements.

This draft uses channels as the first concrete policy area:

  • policy.jsonc defines the authored channel requirement, such as denying a provider.
  • When the policy extension is enabled, it registers channel health checks with the shared health registry. Doctor then runs the registered checks; doctor does not load plugins itself.
  • OpenClaw observes current channels.* config as evidence.
  • doctor --lint reports non-conforming settings, and doctor --fix can repair the owned setting when repairs are enabled.
  • policy check --json emits the recordable audit tuple: policyHash + evidenceHash + findingsHash + checkedAt -> attestationHash.

Policy is only a conformance layer here. channels.* remains the runtime configuration. Findings identify both sides of the decision: target points to the observed setting, such as oc://openclaw.config/channels/telegram, and requirement points to the authored policy rule, such as oc://policy.jsonc/channels/denyRules/#0.

Motivation

Operators already use config to decide which communication surfaces exist, but there is not a small, auditable way to say "this workspace must not enable this surface" and then prove that setting is still true. That shows up in adjacent requests for protected config changes, proposal-only disabling of plugin/tool/channel surfaces, and doctor dry-run/diff behavior:

This PR keeps the answer narrow. It does not add runtime channel enforcement or a second channel config system. It adds a way to prove which policy file was checked against which observed channel evidence, what findings were returned, and when that check happened.

Maintainer Input Requested

  1. Is policy-as-health the right architecture?

    This draft treats policy as a set of health checks over existing OpenClaw surfaces. policy.jsonc defines requirements, the enabled policy extension registers the relevant checks, and doctor --lint remains the shared conformance gate over already-registered checks. Doctor does not load plugins itself. Is that the right shape, or should policy own a separate check/evaluation loop?

  2. Where should policy settings live?

    The draft uses policy.jsonc for authored requirements and plugins.entries.policy.config for operator toggles such as enabled, workspaceRepairs, expectedHash, and the policy path. Is that split right, or should more of this be expressed through normal OpenClaw config?

  3. Is the attestation shape useful and sufficient?

    policy check --json emits policy.hash, workspace.hash over the observed evidence payload, findingsHash, checkedAt, and attestationHash. Is that the right durable audit tuple for policy checks, or should the evidence/result model be different before runtime consumers start recording it?

  4. Is api.js the right cross-extension API boundary?

    This draft calls bundled extension APIs through their public api.js artifact: policy registers health checks through its api.js, and policy imports oc-path through @openclaw/oc-path/api.js instead of reaching into extension internals. Is that the intended convention for cross-extension calls, or should this use a different public API boundary before more bundled extensions depend on each other this way?

What Changed

  • Added the bundled policy extension and its config schema.
  • Added policy check.
  • Added policy.jsonc as the workspace-owned policy artifact.
  • Added observed channel evidence, hashes, and an attestation hash to policy check --json.
  • Added policy finding target and requirement fields so reviewers can see the observed setting and authored policy rule behind each finding.
  • Added the small oc-path document API seam used to parse and address policy documents through one stable extension boundary.
  • Added bounded policy health registration for doctor lint/fix.
  • Added health findings for missing policy, hash mismatch, and denied enabled channel providers.
  • Added opt-in repair for denied enabled channels.

Policy Shape

{
  "channels": {
    "settings": {
      "checkChannels": true,
    },
    "denyRules": [
      {
        "id": "no-telegram",
        "when": { "provider": "telegram" },
        "reason": "Telegram is not approved for this workspace.",
      },
    ],
  },
}

Safety

doctor --lint and policy check are read-only. The audit value comes from policy check --json, which records:

policy hash + evidence hash + findings hash + checkedAt -> attestation hash

doctor --fix only changes channel config when plugins.entries.policy.config.workspaceRepairs is explicitly enabled. The repair is intentionally narrow: it disables denied channels and leaves all other channel material intact.

This draft does not add a channel runtime enforcement hook. If a later channel gateway hook uses policy to block, approve, or annotate a channel interaction, the audit message should include the attestation hash from the last clean policy check. That attestation binds the policy hash, observed evidence hash, findings hash, and checked timestamp so operators can correlate the runtime decision with the exact policy file, workspace evidence, and clean result that produced it.

Real Behavior Proof

Behavior addressed: Policy channel checks produce lint findings, repair the owned setting when allowed, and end with a clean policy check --json attestation over the updated evidence.

Real environment tested: Local Windows source checkout with a temporary OpenClaw config and workspace. The policy extension was enabled in config, policy.jsonc denied provider telegram, and the OpenClaw config had channels.telegram.enabled=true.

Exact steps or command run after fix:

  1. Authored policy.jsonc with channels.denyRules[{ when: { provider: "telegram" } }].
  2. Ran openclaw policy check --json to emit channel evidence plus policy, evidence, findings, and attestation hashes.
  3. Ran openclaw doctor --lint --only policy/channels-denied-provider --json.
  4. Ran openclaw doctor --fix --yes --non-interactive --only policy/channels-denied-provider.
  5. Reran openclaw doctor --lint --only policy/channels-denied-provider --json after the fix.
  6. Reran openclaw policy check --json to emit the final clean attestation.

Evidence after fix:

Policy channel lint/fix proof

Observed result after fix: The first lint command reports the enabled Telegram channel with target=oc://openclaw.config/channels/telegram and requirement=oc://policy.jsonc/channels/denyRules/#0. doctor --fix --yes --non-interactive --only policy/channels-denied-provider disables channels.telegram.enabled. The after-fix lint command validates clean with zero findings, and the final policy check --json emits a clean attestation over the updated channel evidence.

What was not tested: No live channel gateway was started. This PR only changes policy conformance checks and config repair; it does not add runtime channel enforcement.

Testing

Focused tests cover bounded policy health registration, policy check attestation output, missing policy reporting, hash mismatch reporting, deny-rule findings, disabled-channel allowance, and denied-channel repair.

pnpm exec vitest run extensions/policy/src/doctor/register.test.ts extensions/policy/src/cli.test.ts src/flows/bundled-health-checks.test.ts --reporter=dot
pnpm exec vitest run extensions/oc-path/src/oc-path/tests/document.test.ts --reporter=dot
pnpm format:docs:check

Follow-Up

Tool metadata conformance is scoped as a follow-up PR. It uses the same authored-policy plus observed-evidence model without reintroducing generated policy: https://github.com/openclaw/openclaw/pull/80056

Changed files

  • .github/labeler.yml (modified, +6/-0)
  • docs/.generated/plugin-sdk-api-baseline.sha256 (modified, +2/-2)
  • docs/.i18n/glossary.zh-CN.json (modified, +33/-2)
  • docs/cli/doctor.md (modified, +133/-1)
  • docs/cli/index.md (modified, +1/-1)
  • docs/cli/path.md (modified, +11/-0)
  • docs/cli/policy.md (added, +220/-0)
  • docs/gateway/doctor.md (modified, +55/-0)
  • docs/plugins/reference/policy.md (added, +106/-0)
  • docs/plugins/sdk-subpaths.md (modified, +1/-0)
  • extensions/oc-path/api.ts (added, +5/-0)
  • extensions/oc-path/src/cli.ts (modified, +75/-50)
  • extensions/oc-path/src/oc-path/dispatch.ts (modified, +3/-7)
  • extensions/oc-path/src/oc-path/document.ts (added, +73/-0)
  • extensions/oc-path/src/oc-path/index.ts (modified, +17/-14)
  • extensions/oc-path/src/oc-path/tests/document.test.ts (added, +53/-0)
  • extensions/policy/api.ts (added, +1/-0)
  • extensions/policy/index.ts (added, +26/-0)
  • extensions/policy/openclaw.plugin.json (added, +41/-0)
  • extensions/policy/package.json (added, +25/-0)
  • extensions/policy/src/cli.test.ts (added, +190/-0)
  • extensions/policy/src/cli.ts (added, +159/-0)
  • extensions/policy/src/doctor/register.test.ts (added, +284/-0)
  • extensions/policy/src/doctor/register.ts (added, +458/-0)
  • extensions/policy/src/jsonc-value.ts (added, +20/-0)
  • extensions/policy/src/policy-state.ts (added, +100/-0)
  • package.json (modified, +4/-0)
  • pnpm-lock.yaml (modified, +12/-0)
  • scripts/lib/plugin-sdk-doc-metadata.ts (modified, +3/-0)
  • scripts/lib/plugin-sdk-entrypoints.json (modified, +1/-0)
  • src/cli/command-catalog.ts (modified, +7/-1)
  • src/cli/command-path-policy.test.ts (modified, +4/-0)
  • src/cli/program/preaction.test.ts (modified, +16/-2)
  • src/cli/program/preaction.ts (modified, +1/-3)
  • src/cli/program/register.maintenance.test.ts (modified, +41/-1)
  • src/cli/program/register.maintenance.ts (modified, +21/-0)
  • src/commands/doctor-lint.test.ts (added, +114/-0)
  • src/commands/doctor-lint.ts (added, +142/-0)
  • src/flows/bundled-health-checks.test.ts (added, +66/-0)
  • src/flows/bundled-health-checks.ts (added, +29/-0)
  • src/flows/doctor-core-checks.test.ts (added, +143/-0)
  • src/flows/doctor-core-checks.ts (added, +232/-0)
  • src/flows/doctor-health-contributions.test.ts (modified, +12/-0)
  • src/flows/doctor-health-contributions.ts (modified, +35/-0)
  • src/flows/doctor-lint-flow.test.ts (added, +65/-0)
  • src/flows/doctor-lint-flow.ts (added, +100/-0)
  • src/flows/doctor-repair-flow.test.ts (added, +160/-0)
  • src/flows/doctor-repair-flow.ts (added, +116/-0)
  • src/flows/health-check-registry.ts (added, +30/-0)
  • src/flows/health-checks.ts (added, +82/-0)
  • src/plugin-sdk/health.ts (added, +31/-0)
  • test/vitest/vitest.shared.config.ts (modified, +4/-0)
RAW_BUFFERClick to expand / collapse

Environment

  • Windows
  • OpenClaw 2026.5.7
  • OpenClaw dashboard endpoint: [local loopback OpenClaw dashboard endpoint]
  • LM Studio provider (OpenAI-compatible)
  • LM Studio endpoint: [local LM Studio OpenAI-compatible endpoint]
  • Model google/gemma-3-4b
  • API adapter openai-responses

Goal

Run OpenClaw in proposal-only mode with no file/system/tool/channel/automation authority.

What Works

  • Dashboard works after LM Studio context increase.
  • Proposal-only prompt passes.
  • tools.web.search.enabled was disabled.
  • LM Studio provider works using openai-responses.
  • Thinking default is low.

Prior Blocker Fixed

  • n_keep around 29k exceeded n_ctx 4096.
  • Reloading LM Studio with larger context fixed dashboard response.

Current Blocker

  • Exact config key paths for disabling remaining plugin/tool/channel/owner-elevated surfaces are unclear.
  • Codex safely stopped instead of guessing config keys.

Surfaces Needing Authoritative Key Mapping

  • browser
  • device-pair
  • file-transfer
  • memory-core
  • phone-control
  • talk-voice
  • channels
  • cron/automation
  • MCP
  • hooks
  • apps
  • owner-only commands
  • exec approvals
  • dangerous action approvals

Safety Requirements

  • no guessing config keys
  • backup-first edits only
  • no read-only mode until surfaces are locked down
  • no tools/hooks/MCP/apps/channels/automation
  • no file/system authority
  • Codex validates any execution

Maintainer Questions

  1. What exact config keys disable each listed surface?
  2. Is there a native proposal-only/no-tools mode?
  3. Is there a native read-only mode?
  4. How do we disable owner-elevated commands and approvals?
  5. How do we disable or isolate browser/file/phone/voice/plugin sidecars?
  6. How do we prevent doctor from auto-enabling plugins or shrinking config?
  7. How do we validate no tools/channels/automation are active?
  8. Which surfaces are mandatory for dashboard-only chat?
  9. Which surfaces can be safely disabled without breaking dashboard chat?

Redacted Evidence Summary

  • No tokens, API keys, bearer values, cookies, or session IDs included.
  • No full raw local config included.
  • OpenClaw dashboard and proposal-only checks pass under current provider state.
  • Remaining blocker is authoritative key mapping for capability lockdown fields.

What We Need Before Proceeding

  • authoritative config key map
  • second lockdown execute plan
  • second lockdown execution
  • dashboard retest
  • proposal-only retest
  • read-only manual test plan after lockdown

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING