OpenClaw EnterpriseDOCSGitHub

Agent Plugin Deployment Flow

Overview

An authorized caller saves plugin selections, then deploys. OCC validates and snapshots policy, selections, and Driver. Startup resolves metadata, translates policy, and prepares the revision. Revision selection may precede cutover; the Harness owns tools and approvals.

Entry Points

apps/controller/src/index.ts:createFastifyApp

Flow

graph TD
  D0["Request discovery"] -->|Create Agent| D1["Authorize Agent create"]
  D0 -->|Existing Agent| E0["Authorize Agent read/update"]
  E0 -->|curated| D6
  E0 -->|hosted| E1["Resolve bound codex_pat Secret"]
  E1 --> E2["Authorize caller and Agent Secret operate"]
  E2 --> D6
  D1 -->|Secret reference| D2["Authorize exact Secret operate"]
  D2 --> D6["Check PluginDriver support"]
  D1 -->|transient token or no credential| D6
  D6 -->|unsupported| D7["Return unavailable capability"]
  D6 -->|Secret reference| D3["Read owned current value"]
  D6 -->|transient token or no credential| D4["Call selected PluginDriver"]
  D3 -->|Create Agent| D4
  D3 -->|Existing Agent| E3["Recheck grants and binding"]
  E3 --> D4
  D4 --> D5["Return safe catalog metadata"]
  A["Authorize and validate policy"] -->|valid| S["Save Agent selections"]
  A -->|unsupported| Y["Reject write"]
  S --> B["Revalidate and snapshot revision"]
  B --> C["Resolve native metadata"]
  C --> D["Attempt selected installs"]
  D -->|install rejection or auth required| E["Disable failed selections; collect warnings"]
  D -->|success| T["Resolve owned tools; translate policy"]
  E --> T
  T --> F["Verify native identity and effective policy"]
  F -->|invalid or unsafe| X["Keep runtime unready"]
  F -->|verified| G["Publish current startup status"]
  G --> H["Apply matching gateway configuration"]
  H -->|ready| I["Compute returns readiness and warnings"]
  I --> J["Worker completes deployment under live claim"]
  G -->|runtime restart| C

Execution Trace

Credential-scoped discovery

Create discovery accepts transient PATs, same-Namespace Secrets, or supported credential-free access. OCC checks Namespace Agent create and caller Secret operate before Driver support; unsupported discovery reads no Secret.

Existing-Agent discovery requires active Agent read/update; inputs are queries, cursors, or plugin IDs. Hosted discovery resolves bound codex_pat and rechecks binding and caller/Agent Secret operate inside SecretDriver.withValue. Curated discovery needs no Secret. Missing, denied, or unavailable Secrets fail before discovery. Nontransactional reads may precede rotation; discovery persists neither state nor credentials.

The Codex Driver hydrates hosted identity, searches q, and pages GLOBAL entries with opaque cursors. Console discovery preloads page one for Create Agent PATs and bound PATs in editable Agent Plugins tabs. The picker reuses prefetch; credential changes clear discovery, preserving selections. Search marks loading and invalidates old responses before the delay; Enter/paging bypass it. Closing, configured view, credential changes, and view cancellation abort requests. Tools (null: unknown) load on demand; supported entries then become selectable. Unsupported releases remain unavailable. Curated catalogs filter bundled entries without verifying tools/account access.

Bounded hosted reads forbid redirects. OCC returns no-store metadata, rejects credential echoes, and suppresses upstream errors/artifacts. Selections exclude Driver links/setup guidance. Connections remain unverified; HTTPS logos omit referrers and default to initials.

1. Validate desired state under exact-Agent authority

apps/controller/src/index.ts:createFastifyApp

HTTP contracts validate input before OpenClawController checks the exact Namespace and Agent. Reads require Agent read; create/PATCH stores the plugins map. Shared validators check the nested selection shape. OpenClawController.validatePluginPolicies calls the selected Driver's validatePolicies before Agent create/update and provisioning writes. Unsupported controls, reviewer scopes, and combinations return 400 INVALID_REQUEST; a missing selected Driver returns 501 NOT_IMPLEMENTED. Validation is static: native app mapping, authentication, and release/tool metadata remain startup checks. Agent mutations store desired state and audit evidence atomically without changing the reusable Configuration or active runtime. On update, omission preserves the map, {} clears it, and a nonempty map replaces it.

Installation readers use GET /installation; Agent editors use GET .../plugins/capabilities with Agent read/update. Both return policy capabilities.

2. Admit an immutable plugin deployment

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

Deployment revalidates selections and Configuration, records the Driver and policy-only plugin map in AgentRevision, and queues it. Native app mapping, release metadata, and configuration resolve later.

3. Deliver requested state through Compute preparation

apps/controller/src/drivers/compute/plugin-runtime.ts:pluginRuntimeSpecForRevision

Compute validates admitted state, Driver, and Harness. Kubernetes projects the nonsecret request; Docker uses bounded environment delivery.

SSH Compute rejects nonempty plugin maps and Agent default plugin approver policies before host effects.

Initial embedded Kubernetes gateway preparation applies exact-Agent HTTPS egress before installation. For existing gateways, prepareRevision avoids duplicate Agent database access. activateRevision uses Recreate, stopping the old gateway before installation. Revision files stay private and the native registry stays in the Agent-owned database. Docker keeps native state in the container's private temporary home.

4. Prepare native runtime state and hand off readiness

apps/controller/src/drivers/compute/kubernetes/runtime-entrypoints.ts:installOpenClawPlugins

Embedded OpenClaw validates selections against its bundled catalog and policy. Grants enter nonempty tools.allow, otherwise tools.alsoAllow, preserving denies and profiles. A tool's enabled override precedes toolDefaults.enabled; disabled tools emit native denies. Master disable and operator denies prevail; provider_default and none add no Diffs review step. Revision-private configuration uses --pin --force --no-enable, preserving enablement and allow/deny lists. Preparation refreshes the registry and verifies admitted configuration; the pinned runtime release lacks this flag. Native inspection verifies plugin ID, package name, runtime/install version, recorded integrity, and the runtime source's containment in the install path. Failure prevents gateway readiness. Confirmed install rejection disables the optional selection and removes its managed tool allowance before startup.

Selected Codex plugins enable apps/plugins/remote_plugin in isolated CODEX_HOME and configure the bridge with codexPlugins.enabled:true, allow_all_plugins:false, and an entry per selection. apps._default.enabled:false applies; disabled selections cannot execute app tools.

After plugin/list, runtime-entrypoints.ts:readCodexPluginDetails reads up to four selections concurrently, preserving selection order; batches drain before retries. Install and configuration writes stay sequential; post-install reads use the same batching before final policy verification. codexRuntimeArtifact uses concrete detail.apps, excluding appTemplates. codexInstallPlan validates component support and policy before installation. Account-wide skill restrictions remain unsupported. Install rejections or missing app authentication warn. Explicit tool policies require mcpServerStatus/list's codex_apps inventory; codexAppToolSettings binds catalog action IDs through _meta._codex_apps.resource_uri. Native IDs work. Unknown, unowned, ambiguous, or duplicate IDs fail startup.

codexRuntimeArtifact applies the native policy mappings.

writeCodexAppConfiguration reads merged workspace settings, disables unselected apps, and writes inherited tool/account approvals; table replacement leaves lower-layer descendants. Unspecified tool enablement stays unset; native requirements remain enforced. config/batchWrite replaces local app subtrees. Readback checks identity/version/app mapping; failed apps are disabled and disabled selections skip installation/status.

Workspace-aware readback rejects policy conflicts before readiness. Disabled apps may retain inherited fields. Categories resolve app → global → native true; equivalent values/nulls pass. Tool enablement cannot bypass categories.

runtime-entrypoints.ts:verifyCodexReviewerConfiguration checks explicit app/link reviewers and configRequirements/read, rejecting forbidden reviewers, incompatible automatic-review settings, or conflicting model requirements. Startup checks do not cover later workspace/session/model changes or strict review. Codex 0.156 readback omits managed app/tool requirements applied during execution; native effective-policy introspection remains required. See remaining proof.

For Compute-owned Kubernetes workloads, only an admitted {pluginId, code} warning results from a selected OpenClaw install's normal nonzero exit, a matching Codex plugin/install error, or a successful Codex install needing app authentication. Transport loss, timeouts, signals, malformed responses, discovery failures, and policy failures retain ordinary startup failure behavior. Provider-owned Harnesses keep their existing startup path.

After configuration verification, the runtime exposes private startup status. Kubernetes Compute validates workload, revision, startup instance, selection keys, and warning codes for readiness, recomputing status on restart.

Dedicated Codex runs separately and receives runtime-binary reads even without plugins. Startup symlinks /home/node/.openclaw/plugin-skills to /home/node/openclaw-runtime-assets/plugin-skills, preserving relative files without gateway state/credentials.

Gateway blocks failed bridge selections before serving and prevents retry during turns. It refreshes effective configuration when Agent startup changes; untrusted status cannot establish readiness. Requested revision selections remain unchanged.

Compute installs status NetworkPolicies before the first dedicated gateway and creates it only when the Agent and plugin status are ready and its Service selects the revision. Existing gateways and full runtime policies retain their activation boundary.

The Agent and gateway derive an app-server credential from the transport Secret, revision ID, and Agent startup ID. The gateway receives it after matching status and rendering exclusions. After restart, the old gateway cannot authenticate while its supervisor awaits status. A changed peer makes the supervisor publish non-ready status and restart only OpenClaw, reporting ready once it serves. While peer status is unavailable, the gateway stays unready; if it exits during that wait, the wrapper exits so the container can recover.

5. Complete revision reconciliation

apps/controller/src/worker.ts:finalizeRevision

Before the worker commits activeRevisionId, preparation failure leaves the prior pointer unchanged. After commit, activation/finalization failure retains the candidate pointer and records REVISION_FINALIZATION_INCOMPLETE for retry. Embedded Kubernetes replacement runs after commit; the old gateway may already be stopped. The previous revision remains stored, without pointer rollback or an availability guarantee during cutover. See the controller worker flow.

Successful completion reports REVISION_ACTIVATED or REVISION_ALREADY_ACTIVE. A candidate pointer alone is not readiness evidence. Agent turns use native policy; the workspace and gateway database remain Agent-owned.

The worker stores current plugin warnings in the successful work result under its live claim; the worker flow explains persistence and the deployment status projection. Claim loss prevents a stale completion write; a later worker reads current readiness again. There is no receipt acknowledgment, failed-plugin shutdown, or permanent failure latch. Saved deployment warnings describe the completed deployment attempt rather than ongoing runtime health.

Debugging and Verification

Search documentation