Configuration
OpenClaw Control Plane (OCC) keeps Agent settings and platform settings in separate places. Agent settings live in a reusable Configuration in the Agent's Namespace. Saving a change does not affect a running Agent; deploy each Agent that should use it. Platform operators set Installation and Driver options in trusted startup YAML, not in Agent Configurations.
- To reuse launch settings when creating Agents, use Presets.
- To change a model or other Agent settings and put them into use, follow Agent revisions.
- To choose Agent credentials or enable a channel, see Configuration secrets and channels.
- To set platform options, see Installation startup configuration and controller and PostgreSQL settings.
Every Agent Configuration has the required, immutable kind: "agent". Its
values holds the native OpenClaw document, including env, file, and exec
SecretRefs. The optional secretBindings field binds exact Namespace-owned
Secrets to selected gateway environment variables; the Secret Driver stores the
values separately. A reviewed Configuration Driver, bundled or installed, stores
the native document in development and production. The bundled Kubernetes Driver
uses one openclaw.json ConfigMap entry, so values must serialize to less than
1 MiB; a save over that is refused with
400 INVALID_REQUEST and a message naming the limit. Configuration POST/PATCH
bodies allow six times 1 MiB plus 32 KiB (6.2 MiB), room for the values and the
envelope in six-byte JSON escapes; a caller without the create or update grant
is refused before the body is read.
Console presentation uses a separate API-only theme bundle,
selected with OCC_CONSOLE_THEME_DIR. It does not change persisted Installation
or Agent configuration.
Installation startup configuration
Set OCC_CONFIG_PATH to the absolute path of a trusted YAML file. Production
requires this setting; development can omit it to retain its existing local
defaults. When provided, both API and worker processes must read the same file.
The production Kubernetes deployment guide
owns the complete bundled-Driver Installation example, including immutable
images, workload isolation, and projected ServiceAccount credentials. The
Driver package installation guide
owns the installed IAM, Compute, and Configuration selection contract. The
Backend reference defines the optional backend array and its
required related Driver membership. Backend configuration never enters native
Agent Configuration documents. The optional presets.includeDefaults boolean
adds bundled Agent Presets to Namespaces; it defaults to false. A
presets.files entry named like a bundled default replaces that default with a
startup warning. See
Preset initialization for permissions,
restart behavior, and preservation of existing copies.
OCC resolves its persisted singleton Installation internally; Configuration and Secret Driver operations do not include Installation management. Installed Drivers remain trusted, unsandboxed controller code. Invalid production YAML, unsupported settings, and unavailable Drivers stop startup before requests run.
The optional sandboxNetworkPolicyCeiling array delegates bounded per-Agent
network additions. It grants no default access; an absent or empty array delegates
none. See
Sandbox policies for
its grant schema and authorization boundaries.
The optional iam block declares the
Default users
Roles, Groups, and bindings.
The optional observability block sets one external console destination:
observability: url: https://grafana.example.com/d/occ-observabilityurl must be an absolute HTTP or HTTPS URL without embedded credentials or a
fragment. An IPv4 host must be four decimal octets from 0 to 255 with no
leading zeros; shorthand, hex, a single integer, a leading zero, or any @
before the host stops API and worker startup with log code
OBSERVABILITY_URL_INVALID until you correct the URL and restart. A tab, newline,
or a backslash before the query is refused the same way; a backslash in the query
stays. A DNS name is unchanged. Unknown fields
fail startup. The API exposes the URL only after an
Installation administer check; the console hides the link when unset or
unauthorized. The destination handles its own authentication. This setting does
not select an OpenTelemetry exporter or embed a dashboard. Compose development
can use this block alone with its default Drivers; mount the same file into API
and worker containers.
The optional runtime block declares a custom runtime image with dedicated
native OpenClaw support:
runtime: nativeWorkerSupport: custom-imagecustom-image is the only declaration value; no API or Agent Configuration
field can set it. The pinned runtime already supplies native-worker support,
so its Dedicated OpenClaw flow needs no declaration. Use this optional block
only for a separately selected custom image with automatic required worker
placement and node-local inference. It does not add runtime features or waive
the required provisioning SandboxDriver and its containment facets. See
Native worker support.
Create, read, update, and delete
POST /namespaces/:namespaceId/configurations creates one reusable native
Agent Configuration. A representative request body is:
{ "kind": "agent", "values": { "agents": { "defaults": { "skipBootstrap": true } } }}Successful creation returns HTTP 201. The response's data contains its
server-generated id, owning namespaceId, kind: "agent", initial
generation: 1, unchanged values, optional secretBindings, and
createdAt; meta.requestId identifies the request. Add secretBindings only
after the referenced Namespace-owned Secrets exist.
OCC generates the cfg_ identifier and derives ownership from the exact route
Namespace; callers cannot select either field. GET, PATCH, and DELETE operate
on /namespaces/:namespaceId/configurations/:configurationId. A PATCH body
requires the replacement values and may also set secretBindings and
expectedGeneration. For a Configuration last read at generation 1, send:
{ "values": { "agents": { "defaults": { "skipBootstrap": false } } }, "expectedGeneration": 1}GET and PATCH return HTTP 200. PATCH replaces the whole values document, so
omitted models and secrets sections disappear. Omitting secretBindings
preserves the existing bindings; send {} to clear them. Use the generation OCC
returns: it normally advances by one, but recovery from an interrupted write can
skip a number. Do not send kind, generation, or ownership fields in a PATCH.
Successful DELETE returns HTTP 204 with no body.
expectedGeneration is an optional positive safe integer from the caller's last
GET. OCC compares it with the current generation while holding the Configuration
lock. A mismatch returns 409 RESOURCE_CONFLICT without replacing values or
Secret bindings or incrementing the generation. Read the Configuration again,
merge the intended edits with its current values, and submit that generation;
do not retry the stale body with a newer number. Omitting expectedGeneration
replaces whichever generation is current, without this freshness check. The
console's Configuration and channel saves include it.
Creation requires kind: "agent"; missing or unsupported kinds are rejected.
values must be a JSON object. It can contain the nested objects,
arrays, strings, finite numbers, booleans, and nulls used by native OpenClaw
configuration. OCC preserves the native document without interpreting its
fields or resolving SecretRefs, except that Configuration create and update,
Agent provisioning and Preset saves check each model provider's baseUrl and
api, and those of its models entries: baseUrl must be an absolute http
or https URL, and api must be a model API the pinned OpenClaw runtime supports, such as
openai-responses, openai-completions, anthropic-messages, or ollama.
A blank provider baseUrl and values with ${VAR} references are left to the
runtime (a $${VAR} escape is no reference), and a Preset baseUrl or api
that waits on a variable without a default is checked once filled. At save, such
a baseUrl needs a literal http or https scheme, or one a variable
completes, and each variable stands for one host, port, IPv6 address or path
token. The 400 names the field as a JSON pointer within values, and says
when the host's numeric or 0x last label makes the URL parser refuse it as
IPv4. They also refuse a models that is not a list and a headers
or request.headers name that is not a valid HTTP field name, naming the
setting and the header; a Preset header name that waits on such a variable
is checked once filled, on every Compute.
Create and update also refuse, with the 400 Kubernetes Compute deployment
gives, an agents roster the pinned OpenClaw Gateway rejects on every topology:
a non-object agents, agents.defaults, agents.entries or entry; any
agents.list except an empty one beside an empty roster; an Agent ID OpenClaw
rejects, or two it normalizes to one; an entry's default; agents.ownership
other than explicit; more than one entry without it; or explicit with no
entry. The message names the setting and the rule. Preset saves refuse them
too; an Agent ID or agents.ownership that waits on a variable is checked as
far as its written text goes, and in full once filled. A Configuration saved before
this check still reads, and Kubernetes deployment still refuses it; only a write
that keeps the roster is refused. SSH Compute deployment does not check rosters.
Topology rules, such as dedicated execution's main Agent rules, stay at
deployment: a Configuration does not fix a topology.
Every write and Preset save also refuses, with the 400 every deployment gives,
an agents.defaults.model or agents.entries.<id>.model primary or fallback
that is not <provider>/<model> (OpenClaw's openrouter:auto included),
fallbacks that are not a list, a non-boolean agents.defaults.skipBootstrap,
agents.defaults.skipOptionalBootstrapFiles names outside OpenClaw's
optional file list, an agents.defaults.sandbox.mode or
agents.entries.<id>.sandbox.mode other than off, a tools.exec.host or
agents.entries.<id>.tools.exec.host other than auto, gateway or node,
a plugins.allow or plugins.deny that is not a list of text items,
and a $include key at any depth, naming the setting. A
Preset value that waits on a variable
is checked as far as its written text goes, and in full once filled. A
Configuration saved before these checks still reads; deployment refuses it, and
only a write that keeps the value is refused.
OCC also refuses security.preset. Remove it and set the controls you need.
OpenClaw's doctor --fix removes the field without translating its restrictions.
See OpenClaw's repair behavior.
Creation requires create permission for Configurations in the
exact parent Namespace. Reads, updates, and deletes require the corresponding
permission for the exact Configuration. Unauthenticated requests return 401.
Credentials and channels
Never put plaintext credentials in Configuration values. Use unresolved native SecretRefs and authorized same-Namespace Secret bindings for gateway credentials; select model credentials through Agent harnessAuth. See Configuration secrets and channels for binding permissions, complete examples, runtime delivery, and supported Slack/Teams settings.
Agent references and immutable versions
An Agent references one Configuration in its own Namespace:
{ "name": "support-agent", "configurationId": "cfg_123e4567-e89b-42d3-a456-426614174000"}Updating the Agent can replace its configurationId; OCC rejects references
outside the Agent's Namespace or to a Configuration whose kind is not
"agent". Agent creation, update, and deployment separately require read
permission for the exact referenced Configuration. Deployment deeply
snapshots its admitted native document, including unresolved inline SecretRefs,
into the AgentRevision.configuration field and records
configurationId, configurationKind, and configurationGeneration beside
it. A selected SandboxDriver may
transform a copy through configureAgent before admission; the reusable
Configuration and its generation remain unchanged. The snapshot adds the
Agent display name to that document;
its metadata names the source generation. Where unset, OCC sets
tools.exec.applyPatch.workspaceOnly: true and agents.defaults.sandbox.mode: "off".
OCE isolates the Agent and has no Gateway approval screen. Unless tools.exec
sets security or ask, OCC defaults tools.exec.mode to "full" and, in that
mode, tools.exec.strictInlineEval to false. With a channel enabled, OCC
also sets an unset session.dmScope
to "per-account-channel-peer".
Later Configuration updates change no running gateway or existing version
until the next deployment. Deleting a Configuration still referenced by an Agent
returns 409.
Database constraints require the supported Configuration kind, a positive
generation, matching Agent ownership, and a valid immutable saved version
snapshot. The native configuration document keeps its existing root-object
shape without a wrapper, reserved persistence key, or reconstruction from
environment-variable names. secretBindings remain separate from values so
OCC can authorize, validate, and freeze delivery references without rewriting
the native OpenClaw document.
AgentRevisions also keep the selected Compute Driver identity. Compute runtime settings come from Installation startup YAML and are not in the snapshot; see the Agent revision contract for the fields admission freezes.
Kubernetes storage
The Kubernetes Configuration Driver stores live native documents in tenant ConfigMaps. Compute creates separate immutable version snapshots. See Kubernetes Configuration storage for placement, readiness, ownership, and exact RBAC requirements.
Failure semantics and limitations
- Startup rejects
OCC_CONFIG_PATH: Use an absolute path to a readable, valid YAML file shared by the API and worker. Remove unknown Driver settings; verify every selected implementation is available. - Configuration create or update returns
400: Create withkind: "agent"and provide a JSON object invalues. Do not sendkind,generation, or ownership fields in an update. When the message names abaseUrlorapifield, correct that model provider setting; when it names anagentssetting, fix the roster as it says. - Configuration operation returns
403: Verify exact-Namespacecreateor exact-Configurationread,update, ordeletepermission; check the selected Kubernetes identity's namespaced ConfigMap Role separately. - Configuration operation returns
404: Confirm the Configuration ID belongs to the Namespace in the request path. - Configuration update returns
409 RESOURCE_CONFLICT: A detail at/expectedGenerationmeans your copy is stale. Read the Configuration again, merge your changes, and send the generation you just read. In the console, choose Reload draft, review the result, and save only the changes you still intend. Rereading does not clear a provisioning reservation, which also returns409but has no/expectedGenerationdetail. - Configuration deletion returns
409: An Agent still references that Configuration. Reassign every referencing Agent, or delete the Agents and wait for teardown before retrying. A Configuration created by guided Agent provisioning stays referenced until that provisioning succeeds and its Agent selects another Configuration. - Configuration operation returns
503: Confirm the selected Driver and IAM service are available, Kubernetes authentication and TLS are valid, tenant placement is ready, exact namespaced ConfigMap access exists, and the tenant-owned ConfigMap contains one validopenclaw.jsondocument.
Gateway tool policy
Dedicated OpenClaw on Kubernetes and Codex on Kubernetes or Docker apply the
Gateway policy after plugin grants; embedded OpenClaw applies a policy only when the
Configuration sets one. Model access requires concrete names in
tools.gatewayPolicy.allow. Plugin approval and tools.alsoAllow alone grant
no model tools.
Select reviewed task tools, for example:
{ "tools": { "gatewayPolicy": { "allow": ["sessions", "read", "diffs"], "actions": { "sessions": ["patch"] } } }}Enable Diffs as a plugin. Omitting the policy uses the
baseline;
empty allow withholds Gateway tools. Action-bearing tools, such as dashboard,
require explicit allowed actions. Baseline actions can only narrow; administrative tools and
additional baseline actions are rejected. Profiles, denies and Codex dynamic-tool
exclusions still apply. Save and deployment refuse such a policy; a running
revision keeps an older one until its next deployment.
Dedicated composition also sets automations.scope: "caller" and
allowCommandJobs: false under tools.gatewayPolicy, plus agents.defaults.modelSelectionScope: "session" and
cron.triggers.enabled: false.
Deploy a revision to change the saved policy after old work ends. Gateway managed mode governs local allowlist changes. The deployment flow details compatibility checks.
Related
- Quickstart
- Development and production deployment
- Controller and PostgreSQL configuration
- Controller worker lifecycle
- Update and deploy Agent revisions
- Agent Configuration, versions, and deployment
- Kubernetes Compute Driver
- Identity and access management
- Configuration lifecycle implementation
- Local testing
- Kubernetes testing
