openclaw policy
openclaw policy is provided by the bundled Policy plugin. It is an enterprise
conformance layer over existing OpenClaw settings, not a second configuration
system. You author requirements in policy.jsonc; OpenClaw observes the active
workspace as evidence; policy reports drift through doctor --lint. Policy
does not enforce tool calls or rewrite runtime behavior at request time, and it
does not attest per-agent credential stores such as auth-profiles.json.
Policy checks configured channels, MCP servers, model providers, network SSRF
posture, ingress/channel access, Gateway exposure and node command posture,
agent workspace access, sandbox posture, data-handling posture, secret
provider/auth profile posture, and governed tool metadata (TOOLS.md). Use it
when a workspace needs a durable, checkable statement such as “Telegram must
not be enabled” or “governed tools must declare risk and owner metadata.” If
you only need local behavior with no attestation or drift detection, plain
config is enough.
Quick start
policy.jsonc is missing, so doctor can
report the missing artifact instead of silently skipping checks.
Author policy.jsonc by hand; it is not generated from current settings. Each
top-level section is a rule namespace: a check only runs when a concrete rule
is present under it (unsupported sections or keys fail as
policy/policy-jsonc-invalid instead of being silently ignored). Minimal
example covering every supported section:
- Omitting
gateway.bindwhile denying non-loopback binds means you accept the runtime default; setgateway.bind: "loopback"for strict conformance. - For a read-only agent, set sandbox
modetoallornon-mainon the applicable defaults/agent andworkspaceAccesstononeorro. Missing oroffsandbox mode does not satisfy a read-only policy. agents.workspace.denyToolsacceptsexec,process,write,edit,apply_patch. The config tool-deny groupsgroup:fs(file mutation) andgroup:runtime(shell/process) satisfy the equivalent posture.- Exec-approvals checks read the live
exec-approvals.jsonartifact only when anexecApprovalsrule is present; a missing or invalid artifact is unobservable evidence, not a synthetic pass. - Secret and auth-profile evidence records provider/source posture and
SecretRef metadata only, never raw values. Policy does not read or attest
per-agent credential stores such as
auth-profiles.json. - Data-handling evidence is config-level posture only (redaction mode, telemetry capture toggle, session maintenance mode, transcript-indexing setting). It does not inspect logs, telemetry exports, transcripts, or memory files, and a clean result does not prove that no personal data or secrets exist in them.
Policy rule reference
Every rule below is optional; a check runs only when the rule is present. The observed state is existing OpenClaw config or workspace metadata.Scoped overlays
Usescopes.<scopeName> when specific agents or channels need stricter policy
than the top-level baseline. The scope name is just a label; matching uses the
selector inside the scope. Overlays are additive: the global rule still runs,
and the scoped rule can add its own finding against the same evidence.
If an
agentIds entry is not present in agents.list[], OpenClaw evaluates
the scoped rule against inherited global/default posture for that runtime
agent id instead of skipping it.
sandbox.containers.*) are checked only against
evidence the matched agent’s sandbox backend can expose. If a backend cannot
observe a rule you enabled for it, policy reports
policy/sandbox-container-posture-unobservable instead of passing; scope
container rules to the agent groups that use a backend which can expose them.
Top-level ingress.session.requireDmScope stays global; session.dmScope is
not channel-attributable evidence, so it cannot be scoped by channelIds.
Every scope present in policy.jsonc must be valid and enforceable.
Channels
MCP servers
Model providers
Network
Ingress and channel access
Gateway
gateway.nodes.denyCommands is an exact, case-sensitive deny-superset rule.
Use it when policy must prove that privileged node commands are explicitly
denied by OpenClaw config. A deployment that intentionally allows a privileged
node command should update policy.jsonc after review instead of relying on
gateway.nodes.allowCommands alone.
Agent workspace
Sandbox posture
Policy treats missing
sandbox.mode as its implicit default off, so
sandbox.requireMode reports a fresh or unconfigured sandbox as outside an
allowlist such as ["all"].
Data Handling
Secrets
Exec approvals
Exec-approvals checks read the runtimeexec-approvals.json artifact:
~/.openclaw/exec-approvals.json by default, or
$OPENCLAW_STATE_DIR/exec-approvals.json when OPENCLAW_STATE_DIR is set.
Posture rules under execApprovals.defaults.* or execApprovals.agents.*
require readable artifact evidence; a missing or invalid artifact reports as
unobservable evidence rather than a best-effort pass. Once readable, omitted
fields inherit runtime defaults: missing defaults.security is full, and
missing agent security inherits that default. Evidence includes defaults,
agents.*, agents.*.allowlist[].pattern, optional argPattern, effective
autoAllowSkills posture, and entry source — never socket path/token,
commandText, lastUsedCommand, resolved paths, or timestamps.
Example: require the approvals artifact, deny permissive defaults, and allow
only reviewed exec approval posture for selected agents.
Auth profiles
Tool metadata
Tool posture
Run checks
Run policy-only checks during authoring:policy check runs only the policy check set and emits evidence, findings,
and attestation hashes. The same findings also appear in
openclaw doctor --lint when the Policy plugin is enabled.
Compare an operator policy file against an authored baseline:
policy compare checks policy-file syntax against policy-file syntax; it does
not inspect runtime state, evidence, credentials, or secrets. It uses the same
rule metadata that governs scoped overlays: allowlists must stay equal or
narrower, denylists must stay equal or broader, required booleans must keep
their value, ordered strings may only move toward the stricter end of the
configured order, and exact lists must match. The baseline can be an
organization-authored policy; the checked policy may add stricter values or
extra rules. A top-level checked rule can satisfy a scoped baseline rule when
it is equally or more restrictive. Scope names do not need to match between
files; comparison is keyed by selector (agentIds/channelIds) and field.
Clean compare (--json):
policy check --json output includes stable hashes an operator or
supervisor can record:
Configure policy
Policy config lives underplugins.entries.policy.config.
Set
plugins.entries.policy.config.enabled to false to disable policy
checks for a workspace while leaving the plugin installed.
Accept policy state
Example JSON output:attestation.policy.hash identifies the authored rule artifact. evidence
records the observed OpenClaw state used by the checks, and
workspace.hash identifies that evidence payload. findingsHash identifies
the exact finding set. checkedAt records when the check ran.
attestationHash identifies the stable claim (policy hash, evidence hash,
findings hash, and clean/dirty state) and deliberately excludes checkedAt,
so the same policy state always produces the same attestation hash. Together
these four values form the audit tuple for one policy check.
If a gateway or supervisor uses policy to block, approve, or annotate a
runtime action, it should record the attestation hash from the last clean
check. checkedAt stays in JSON output for audit logs but is not part of the
stable hash.
Lifecycle for accepting policy state:
- Author or review
policy.jsonc. - Run
openclaw policy check --json. - If clean, record
attestation.policy.hashasexpectedHash. - Record
attestation.attestationHashasexpectedAttestationHash. - Re-run
openclaw doctor --lintin CI or release gates.
expectedAttestationHash changes.
Enabling or upgrading agents.workspace rules adds agentWorkspace evidence
to the workspace hash and attestation hash; review the new evidence and
refresh accepted attestation hashes after enabling. Enabling or upgrading
tool posture rules adds toolPosture evidence the same way.
openclaw policy watch re-runs the check and reports when current evidence no
longer matches expectedAttestationHash:
--once in CI or scripts that need a single drift evaluation. Without
--once, it polls every two seconds by default; use --interval-ms to change
the interval.
Findings
A finding can include both
target (the observed workspace thing that does
not conform) and requirement (the authored rule that made it a finding).
Both are oc:// address strings today, but the field names describe policy
role rather than address format.
Example findings:
Repair
doctor --lint and policy check are read-only.
doctor --fix only edits policy-managed workspace settings when
workspaceRepairs is explicitly enabled; otherwise checks report what they
would repair and leave settings unchanged.
In this version, repair can disable channels denied by channels.denyRules and
apply the automatic narrowing repairs listed below. Enable workspaceRepairs
only after the policy file has been reviewed, because a valid rule can change
workspace config:
- set
tools.elevated.enabled=falsewhen a global policy forbids elevated tools - add missing required-deny tool ids to
tools.denyoragents.list[].tools.denywhen policy requires those tools to be denied - set insecure
gateway.controlUi.*toggles tofalse - set
gateway.mode=localwhen policy denies remote gateway mode - set reported
gateway.http.endpoints.*.enabledpaths tofalsewhen policy denies Gateway HTTP API endpoints - set reported channel ingress
groupPolicypaths toallowlistwhen policy denies open group ingress - set reported channel ingress
requireMentionpaths totruewhen policy requires group mentions - set
logging.redactSensitive=toolswhen policy requires sensitive logging redaction - set
diagnostics.otel.captureContent=false, ordiagnostics.otel.captureContent.enabled=falsefor object-form telemetry capture settings, when policy denies telemetry content capture
tools.deny, because adding the required tool to root config would affect
more than the scoped policy target. Agent-local required-deny repairs can update
the reported agents.list[].tools.deny path.
Scoped channel ingress repairs are skipped when the finding reports inherited
channels.defaults.*, because changing the shared channel default would affect
more than the scoped policy target. Gateway HTTP URL-fetch allowlist findings
remain manual because automatic repair cannot choose the correct endpoint URL
allowlist values.
Gateway bind and node-command findings stay review-required. When
policy/gateway-non-loopback-bind or policy/gateway-node-command-denied
can be mapped to a config path, doctor --fix reports the proposed
gateway.bind or gateway.nodes.denyCommands change as skipped preview
guidance. It does not apply the change, and the finding does not count as
repaired until an operator reviews and updates config or policy.