OpenClaw EnterpriseDOCSGitHub

Configuration Driver and Agent Revision Flow

Overview

Authenticated API requests create, read, replace, or delete exact Namespace-owned native OpenClaw configuration documents through the selected bundled or installed Configuration Driver. The bundled Kubernetes implementation persists each document in a tenant-owned ConfigMap. Each Configuration requires immutable kind: "agent" and a server-managed generation; documents preserve unresolved inline SecretRefs without interpreting them. Agent deployment authorizes the separate Secret bindings, applies any selected Sandbox Driver transformation, and saves the validated values in the Agent revision. Configuration identity, kind, generation, and Secret references are recorded separately. This flow stops when OCC persists that version and hands off workload reconciliation; the selected Compute Driver then owns the Agent gateway, while worker execution and secret resolution remain outside this flow's scope.

Entry Points

Flow

graph TD
  A["API or worker startup"] -->|reads absolute path| B["Trusted Installation YAML"]
  B --> C{"Closed Driver schemas valid?"}
  C -->|no| X["Reject startup"]
  C -->|yes| D["Construct selected Compute and Configuration Drivers"]
  D --> E["Resolve singleton Installation and construct IAM"]
  E --> G["Accept exact Namespace Configuration request"]
  G --> H{"IAM authorizes exact resource?"}
  H -->|no| Y["Reject without cross-Namespace access"]
  H -->|yes| I["Lock PostgreSQL ownership metadata"]
  I --> J["Validate agent kind and generation; invoke the selected Configuration Driver"]
  J --> K{"Agent deployment references Configuration?"}
  K -->|no| L["Return authorized Configuration response"]
  K -->|yes| M["Authorize and lock exact Configuration"]
  M --> P["Authorize Secret bindings and verify backend references"]
  P --> Q["Apply optional Sandbox transform; validate configuration and Harness"]
  Q --> N["Freeze admitted values, Configuration metadata, and Secret references"]
  N --> O["Hand off saved version to reconciliation"]

Execution Trace

1. Construct the selected Installation Configuration Driver

apps/controller/src/composition/installation-config.ts:loadInstallationConfiguration

The API and worker load trusted Installation selections and validate the chosen Configuration Driver's schema and implementation-owned rules before constructing its bundled or installed implementation. OCC receives that exact capability and identity; invalid settings or a mismatched factory reject startup. Installation settings never come from a Configuration Driver. The Driver package loading flow owns package identity, validation, trust boundaries, and IAM construction.

2. Resolve singleton state and select Drivers

apps/controller/src/composition/production.ts:composeProduction

Production composition loads the sole persisted Installation from PostgreSQL platform state. Both processes use the same startup document and Installation identity. The Driver loading flow traces process-local construction and the selected Secret, Sandbox, and ServiceAccount branches. Existing AgentRevisions retain their selected Compute identity and immutable admitted configuration; subsequent Configuration edits apply only to later deployments.

Provisioning's KubernetesConfigurationDriver.createExact and inspectExact use the same verified CP namespace as ordinary Configuration CRUD. Recovery checks the exact identity and document there; an adopted data-plane namespace does not change canonical Configuration ownership. When a create's outcome is unknown and inspectExact still finds nothing 90 seconds after the provisioning effect began (database clock), the worker fences again and sends the same create under the same effect; earlier attempts wait without spending a retry, and a Namespace deletion keeps waiting meanwhile. The Driver's write deadline is 10 seconds and the API server's default request timeout 60 seconds, so a late original then fails AlreadyExists. The window covers the first send only: later attempts resend at once. A failed resend settles the effect only if inspectExact finds the exact Configuration.

3. Authorize the exact Namespace Configuration operation

packages/occ/src/index.ts:OpenClawController.createConfiguration

Configuration route contracts define requests the controller request handler dispatches to createConfiguration, getConfiguration, updateConfiguration, or deleteConfiguration in OCC. OCC resolves the server-owned Namespace and checks the selected IAM Driver before accessing tenant data. Create checks Configuration permission at Namespace scope. Read, update, and delete target the exact Configuration in that Namespace.

POST and PATCH accept up to 6 × (1 MiB + 32 KiB) for the Kubernetes Driver's 1 MiB of values and the envelope in six-byte JSON escapes. onRequest runs authorizeConfigurationWrite before reading the body. Without the grant, callers get 403 before body errors. OCC rechecks in the transaction. For every JSON route, createFastifyApp registers apps/controller/src/http/json-depth.ts:tooDeepJsonPath to scan raw text once. A value more than 24 levels below the root gets 400 INVALID_REQUEST with TOO_DEEP before parsing or validation. Otherwise Fastify parses the JSON. The text validator visits one entry at a time and checks each key before its value. It stops at the first NUL (INVALID_FORMAT) or unpaired UTF-16 surrogate (INVALID_VALUE) and returns 400 INVALID_REQUEST with a capped JSON Pointer. To identify caller-supplied IDs for a denial, the controller checks at most 4,096 path, query, and body entries, including reference-list items.

Creation requires kind: "agent" and a native JSON object. Missing or unknown kinds and malformed requests fail with 400. Updates require the complete replacement values document and accept optional secretBindings and expectedGeneration, refusing a stale one under the row lock with an /expectedGeneration 409 detail. On Kubernetes Compute, requireChannelSecretBindings rejects enabled channels' unbound credential references and Slack token SecretRefs unreadable by the Slack Channel Driver. kind, generation, and ownership remain server-owned. Preset admission defers renderer-located whole-string Gateway-password variables; Configuration writes and deployment require concrete references. Malformed, generation-mismatched, or ownership-invalid ConfigMaps fail with 503. Authorization denial fails with 403, a missing exact resource with 404, an Agent dependency conflict with 409, and unavailable IAM or storage with 503. OCC checks operate on each bound Secret, including bindings retained when PATCH omits secretBindings. An empty object ({}) clears the bindings. A binding with a reserved or invalid destination, or a Secret reference to another Namespace, fails with 400 INVALID_REQUEST and a message naming the rule. A reserved destination is also named, with a /secretBindings/<key> detail; a malformed one is not echoed. A Secret the Namespace does not hold stays 404. The Configuration reference owns the binding contract, and the Secret flow traces storage and delivery. Secret Broker substitution remains unimplemented.

4–5. Persist Configuration and freeze its version

apps/controller/src/drivers/configuration/filesystem/index.ts:FilesystemConfigurationDriver.write

Default Compose development uses the filesystem Driver. Each write exclusively creates a private temporary file under the exact Namespace directory. It sets the open file to 0600 before writing so umask cannot make a successful replacement unreadable. It then writes the approved document, closes the file, and atomically renames it to the Configuration path. A finally block removes only that write's temporary file, including after partial writes such as ENOSPC or a failed rename. The prior destination stays intact until rename succeeds, and other writers' temporary files remain untouched. Storage and cleanup failures propagate to the caller; this does not add automatic retries or alter OCC's metadata transaction and compensation boundary.

Configuration persistence and version snapshots traces metadata locking, Driver effects, Agent reference resolution, and snapshot validation after request authorization.

Ordinary deployment retains validated Configuration and Driver identities. Admission rejects changed Agent bindings, Configuration content or generation, or selected Drivers before recording revisions and work. Provider calls remain outside the transaction.

Debugging and Verification

tests/integration/occ-api.test.mjs listens on loopback and uses Slack validation with a synthetic sender. It covers one revision/work/success audit, receipt recovery without extra calls, ordinary and disabled-Slack deployment, Secret authority, Configuration/Driver drift, and late dependency failures.

tests/integration/postgres-platform-state.test.ts separately proves persisted recovery through a reopened adapter, reconcile counts, and one successful deploy audit. Its sender is synthetic.

Run focused Configuration conformance and integration checks:

bash
node --test tests/conformance/configuration-occ.test.ts tests/conformance/kubernetes-configuration.test.ts tests/conformance/filesystem-configuration.test.tsnode --test tests/integration/configuration-controller.test.mjs tests/integration/postgres-platform-state.test.tsnode --test tests/integration/postgres-platform-state-kubernetes.test.ts

PostgreSQL integration requires configured database URLs; skipped cases do not prove live persistence. Live ConfigMap and least-privilege RBAC proof requires a disposable Kubernetes cluster and tenant credentials; client fixtures do not replace that evidence. Startup emits structured startup-error or worker.startup-error events for invalid YAML and unavailable dependencies. Verify missing or unknown kinds are rejected, creation starts at generation 1, updates advance it once without permitting a kind change, requests preserve the exact native document and inline references, and ConfigMaps store exactly one openclaw.json entry. Verify denials against exact Namespace and Configuration identity. Prove snapshot safety by changing a nested Configuration value after deployment and confirming the prior Agent revision's native document, Configuration identity, kind, and generation remain unchanged while a later deployment observes the new generation. Verify same-Namespace Agents receive separate gateways only when an eligible development worker prepares their versions. Kubernetes conformance verifies immutable Agent-owned configuration projection without a live cluster; dedicated-cluster coverage of the changed projection remains unverified when its optional integration is skipped.

Search documentation