



























11---
2-summary: "CLI reference for `openclaw policy` channel conformance checks"
2+summary: "CLI reference for `openclaw policy` conformance checks"
33read_when:
44 - You want to check OpenClaw settings against an authored policy.jsonc
55 - You want policy findings in doctor lint
@@ -10,14 +10,23 @@ title: "Policy"
1010# `openclaw policy`
11111212`openclaw policy` is provided by the bundled Policy plugin. Policy is an
13-enterprise conformance layer over existing OpenClaw settings: `policy.jsonc`
14-defines authored requirements, OpenClaw observes the active workspace as
15-evidence, and policy health checks report drift through `doctor --lint`.
16-17-This first policy slice manages configured channels. For example, IT can record
18-that Telegram is not approved, then `doctor --lint` reports any enabled Telegram
19-channel and `doctor --fix` can turn it off when workspace repairs are explicitly
20-enabled.
13+enterprise conformance layer over existing OpenClaw settings. It does not add a
14+second configuration system. `policy.jsonc` defines authored requirements,
15+OpenClaw observes the active workspace as evidence, and policy health checks
16+report drift through `doctor --lint`. The final conformance signal is a clean
17+`doctor --lint` run; policy contributes findings to that shared lint surface
18+instead of creating a separate health gate.
19+20+Policy currently manages configured channels and governed tool declarations.
21+For example, IT or a workspace operator can record that Telegram is not an
22+approved channel provider, require governed tools to carry risk and sensitivity
23+metadata, then use `doctor --lint` as the shared conformance gate.
24+25+Use policy when a workspace needs a durable statement such as "these channels
26+must not be enabled" or "governed tools must declare approval metadata" and a
27+repeatable way to prove that OpenClaw still conforms to that statement. Use
28+regular config and workspace docs alone when you only need local behavior and
29+do not need policy findings or attestation output.
21302231## Quick start
2332@@ -32,7 +41,7 @@ arbitrary plugins. The plugin remains enabled if `policy.jsonc` is missing, so
3241doctor can report the missing artifact.
33423443Policy is authored, not generated from the user's current settings. A minimal
35-channel policy looks like this:
44+policy for channels and tool metadata looks like this:
36453746```jsonc
3847{
@@ -45,12 +54,16 @@ channel policy looks like this:
4554 },
4655 ],
4756 },
57+"tools": {
58+"requireMetadata": ["risk", "sensitivity", "owner"],
59+ },
4860}
4961```
50625163The rules are the authority. A category block is only a namespace; checks run
5264when a concrete rule is present. OpenClaw reads current `channels.*` settings
53-and reports settings that do not conform.
65+and `TOOLS.md` declarations as evidence, then reports observed state that does
66+not conform.
54675568Run policy-only checks during authoring:
5669@@ -122,12 +135,64 @@ Policy config lives under `plugins.entries.policy.config`.
122135Set `plugins.entries.policy.config.enabled` to `false` to disable policy checks
123136for a workspace while leaving the plugin installed.
124137138+Tool metadata requirements are authored in `policy.jsonc` with
139+`tools.requireMetadata`, for example `["risk", "sensitivity", "owner"]`.
140+125141## Accept policy state
126142127-The attestation hash identifies the stable claim: policy hash, evidence hash,
128-findings hash, and whether the result was clean. It intentionally does not
129-include `checkedAt`, so the same policy state produces the same attestation
130-across repeated checks.
143+Example JSON output:
144+145+```json
146+{
147+"ok": true,
148+"attestation": {
149+"checkedAt": "2026-05-10T20:00:00.000Z",
150+"policy": {
151+"path": "policy.jsonc",
152+"hash": "sha256:..."
153+ },
154+"workspace": {
155+"scope": "policy",
156+"hash": "sha256:..."
157+ },
158+"findingsHash": "sha256:...",
159+"attestationHash": "sha256:..."
160+ },
161+"evidence": {
162+"channels": [
163+ {
164+"id": "telegram",
165+"provider": "telegram",
166+"source": "oc://openclaw.config/channels/telegram",
167+"enabled": false
168+ }
169+ ],
170+"tools": [
171+ {
172+"id": "deploy",
173+"source": "oc://TOOLS.md/tools/deploy",
174+"line": 12,
175+"risk": "critical",
176+"sensitivity": "restricted",
177+"capabilities": ["IRREVERSIBLE_EXTERNAL"]
178+ }
179+ ]
180+ },
181+"checksRun": 6,
182+"checksSkipped": 0,
183+"findings": []
184+}
185+```
186+187+The policy hash identifies the authored rule artifact. The evidence block
188+records the observed OpenClaw state used by the policy checks. The
189+`workspace.hash` value identifies that evidence payload for the checked scope.
190+The findings hash identifies the exact finding set returned by the check.
191+`checkedAt` records when the evaluation ran. The attestation hash identifies
192+the stable claim: policy hash, evidence hash, findings hash, and whether the
193+result was clean. It intentionally does not include `checkedAt`, so the same
194+policy state produces the same attestation across repeated checks. Together,
195+these form the audit tuple for this policy check.
131196132197If a later gateway or supervisor uses policy to block, approve, or annotate a
133198runtime action, it should record the attestation hash from the last clean policy
@@ -146,20 +211,71 @@ If policy rules change intentionally, update both accepted hashes from a clean
146211check. If workspace settings change intentionally but policy stays the same,
147212only `expectedAttestationHash` usually changes.
148213214+`openclaw policy watch` runs the same check repeatedly and reports when the
215+current evidence no longer matches `expectedAttestationHash`:
216+217+```bash
218+openclaw policy watch --json
219+```
220+221+Use `--once` in CI or scripts that only need one drift evaluation. Without
222+`--once`, the command polls every two seconds by default; use `--interval-ms` to
223+choose a different interval.
224+149225## Findings
150226151227Policy currently verifies:
152228153-| Check id | Finding |
154-| ---------------------------------- | ------------------------------------------------------------------- |
155-| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
156-| `policy/policy-jsonc-invalid` | Policy cannot be parsed or has malformed rules. |
157-| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
158-| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
159-| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
229+| Check id | Finding |
230+| ---------------------------------------- | ------------------------------------------------------------------- |
231+| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
232+| `policy/policy-jsonc-invalid` | Policy cannot be parsed or has malformed rules. |
233+| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
234+| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
235+| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
236+| `policy/tools-missing-owner` | A governed tool declaration is missing owner metadata. |
237+| `policy/tools-missing-risk-level` | A governed tool declaration is missing risk metadata. |
238+| `policy/tools-missing-sensitivity-token` | A governed tool declaration is missing sensitivity metadata. |
239+| `policy/tools-unknown-risk-level` | A governed tool declaration uses an unknown risk value. |
240+| `policy/tools-unknown-sensitivity-token` | A governed tool declaration uses an unknown sensitivity value. |
241+242+Policy findings can include both `target` and `requirement`. `target` is the
243+observed workspace thing that does not conform. `requirement` is the authored
244+policy rule that made it a finding. Both values are addresses today, usually
245+`oc://` paths, but the field names describe their policy role rather than the
246+address format.
247+248+Example JSON finding:
249+250+```json
251+{
252+"checkId": "policy/channels-denied-provider",
253+"severity": "error",
254+"message": "Channel 'telegram' uses denied provider 'telegram'.",
255+"source": "policy",
256+"path": "openclaw config",
257+"ocPath": "oc://openclaw.config/channels/telegram",
258+"target": "oc://openclaw.config/channels/telegram",
259+"requirement": "oc://policy.jsonc/channels/denyRules/#0",
260+"fixHint": "Telegram is not approved for this workspace."
261+}
262+```
160263161-Policy findings can include `target` and `requirement`: the observed workspace
162-thing that does not conform, and the authored rule that made it a finding.
264+Example tool finding:
265+266+```json
267+{
268+"checkId": "policy/tools-missing-risk-level",
269+"severity": "error",
270+"message": "TOOLS.md tool 'deploy' has no explicit risk classification.",
271+"source": "policy",
272+"path": "TOOLS.md",
273+"line": 12,
274+"ocPath": "oc://TOOLS.md/tools/deploy",
275+"target": "oc://TOOLS.md/tools/deploy",
276+"requirement": "oc://policy.jsonc/tools/requireMetadata"
277+}
278+```
163279164280## Repair
165281@@ -190,5 +306,12 @@ configured channel:
190306191307## Exit codes
192308193-`policy check` exits `0` when there are no findings at the threshold, `1` when
194-findings are present, and `2` for argument or runtime failures.
309+| Command | `0` | `1` | `2` |
310+| -------------- | ----------------------------------------- | ------------------------------------------------ | ---------------------------- |
311+| `policy check` | No findings at the threshold. | One or more findings met the threshold. | Argument or runtime failure. |
312+| `policy watch` | No findings and accepted hash is current. | Findings exist or accepted attestation is stale. | Argument or runtime failure. |
313+314+## Related
315+316+- [Doctor lint mode](/cli/doctor#lint-mode)
317+- [Path CLI](/cli/path)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。