OpenClaw EnterpriseDOCSGitHub

Agent Workspace Files Flow

Overview

OCC privately stages authenticated creation inputs: AGENTS.md, SOUL.md, IDENTITY.md, and USER.md. Compute initializes durable storage before execution; activation retains completion metadata.

Subsequent file operations authorize the exact active Agent and use its Compute-resolved private endpoint through Envoy Gateway.

Dedicated execution uses Kubernetes Codex; see workspace and launcher boundaries. Dedicated OpenClaw worker execution remains pending.

See two-cluster transport for CP/DP routing.

Entry Points

Live access requires the Agent's private HTTPRoute and native gateway. Operators configure Envoy Gateway, native trust, and network restrictions through deployment; see the routing contract for transport and credentials. By default, the chart requests a private CA and listener certificate from cert-manager and uses a derived Service DNS hostname. Operators can provide an existing issuer and explicit hostname instead.

Flow

graph TD
  subgraph Initial["Creation and first deployment"]
    S["Create Agent with initial files"] --> T["Authorize and stage exact-Agent input"]
    T --> U["Separate deploy request"]
    U --> V["Compute initializes durable workspace"]
    V --> W{"Setup complete?"}
    W -->|no| X["Block execution; retain pending input"]
    W -->|yes| Y["Start runtime; activate revision"]
    Y --> Z["Clear staged bytes; retain completion metadata"]
  end
  A["GET or PUT Agent workspace file"] --> B["OCC authenticates and validates request"]
  B --> C["Authorize exact Agent and select active revision"]
  C --> D["Compute derives private Agent URL"]
  D --> E["OCC reads service key and opens WSS"]
  E --> F{"Envoy authenticates OCC?"}
  F -->|no| G["503 dependency unavailable"]
  F -->|yes| H["Overwrite identity and real IP; route to Agent Service"]
  H --> I["Native gateway authorizes service identity"]
  I --> J["Native file get or set"]
  J --> K{"Result"}
  K -->|read| L["Return name and content"]
  K -->|write| M["Audit metadata and return name and size"]
  K -->|missing| N["404 NOT_FOUND"]
  K -->|unavailable| G
  K -->|write uncertain| O["Audit UNKNOWN_OUTCOME; never replay"]

Execution Trace

1. Creation validates and privately stages the inputs

apps/controller/src/console/agents/create.mjs fills four textareas from workspace-defaults.mjs and submits their values with WORKSPACE_DEFAULTS_ID. apps/controller/src/index.ts:createFastifyApp rejects a stale defaults identity; packages/contracts/src/workspace-setup.ts:normalizeInitialWorkspaceFiles rejects unknown names, invalid Unicode, NUL, and values above 16 KiB UTF-8. An absent or empty map creates no setup state. The HTTP create route has a 448 KiB default body limit; a configured controller limit takes precedence.

packages/occ/src/index.ts:createAgent checks Namespace-scoped Agent creation, exact Configuration read, and the existing binding permissions. Its transaction creates a stopped Agent and, when keys were supplied, a private workspaceSetups record keyed by exact Namespace/Agent. No AgentRevision is created. Inputs do not enter the Agent, Configuration, revision snapshot, public response, or metadata-only create audit. The original API strings are preserved; Console textarea values use LF newlines.

2. Deployment initializes storage before execution

apps/controller/src/worker.ts reads private setup state while resolving ComputeRevisionContext. A selected Driver without supportsWorkspaceSetup returns WORKSPACE_SETUP_UNSUPPORTED. The existing deployment worker owns the Agent's serialized startup and passes workspaceSetup to Compute.

The bundled Drivers deliver inputs to the shared apps/controller/src/drivers/compute/workspace-setup-runtime.ts:WORKSPACE_SETUP_RUNTIME: Kubernetes uses an owned Secret and an init container on the workspace owner (Gateway for embedded execution; Harness for dedicated execution); Docker uses a separate setup container and Agent-owned durable volumes; SSH uses the protected exact-Agent directory and remote helper. Delivery does not put document strings in container arguments or environment values. Dedicated Harness startup must also verify completion before execution. Unsupported workspace placement fails instead of writing outside the Agent's managed storage. Provider-owned Sandbox startup cannot carry this init container and rejects workspace setup rather than dropping initialization.

The runner validates identity, paths, OpenClaw 2026.9.6, and the rendered template digest against Console defaults. Defaults identities must match; links and conflicts fail. Without a completion marker, native setup initializes the workspace and Git without starting the Gateway. The Kubernetes initializer uses the configured Gateway resource budget because it loads the native CLI, even when it runs in the dedicated Harness Pod. It atomically replaces supplied files, including empty strings, when existing content is absent, stock, or already submitted. It runs native setup again so native BOOTSTRAP.md lifecycle sees the submitted profile, verifies the results, then atomically writes .oce-workspace-setup.json.

Matching markers skip application after lost acknowledgement. Incomplete writes retry with the same safety checks. A divergent file or missing/mismatched marker after recorded completion blocks startup; it never authorizes replay over later user edits. Native setup output and failure details are suppressed at the delivery boundary to avoid disclosing contents.

3. Activation clears staged contents and keeps completion metadata

apps/controller/src/worker.ts completes setup in the activation-completion transaction only after checking the exact active revision and work claim. workspaceSetups.complete removes document bytes and retains identity and completion metadata. Drivers remove or replace private delivery bytes with metadata; subsequent startup verifies the durable workspace marker.

Failed or never-deployed Agents retain pending inputs. Agent deletion removes the private setup record through packages/occ/src/index.ts:deleteAgent and Driver cleanup owns the Agent's runtime storage. There is no public setup read or update endpoint. Creation without supplied keys follows ordinary startup. Once an Agent is active, live edits follow the independent path below and do not update the original setup record.

4. Composition configures private access

apps/controller/src/server.mjs:start validates the optional absolute OCC_GATEWAY_API_KEY_PATH before opening the database. Production and PostgreSQL development composition bind the selected Compute Driver to createWorkspaceFilesAccess. The worker uses the same mounted service key for native node enrollment. Node loads any NODE_EXTRA_CA_CERTS trust bundle at startup.

For the chart's automatic CA, API and worker Pods wait for cert-manager's generated root Secret and receive only its public certificate. They do not receive the CA signing key. An explicit external issuer uses the configured public CA bundle, or Node's existing trust store when no bundle is configured.

Kubernetes derives endpoints from admitted IDs and Installation routing. Drivers without endpoint support cannot serve workspace files.

5. OCC admits one exact-Agent file operation

apps/controller/src/index.ts:createFastifyApp requires a valid user session or scoped service API key. Native Agent credentials cannot invoke this administration surface. GET needs Agent read; PUT needs Agent operate and, for session callers, passes the browser CSRF boundary. OCC resolves the active AgentRevision before Compute endpoint resolution.

Only the four names are accepted. PUT accepts only { "content": "..." }, rejects NUL and unpaired UTF-16 surrogates, enforces 16 KiB of UTF-8 content, and uses a 48 KiB request-body limit. The deadline and disconnect signal cover admission and native access.

6. Compute resolves a route and OCC loads the current key

apps/controller/src/composition/workspace-files.ts:createWorkspaceFilesAccess uses ComputeDriver.getGatewayEndpoint(revision) to resolve wss://<hostname>[:<endpointPort>]/namespaces/<namespaceId>/agents/<agentId>. Hostname defaults to Helm's Service DNS, port to 443; resolution does not prove readiness.

kubernetes/index.ts:reconcileGatewayRoute provisions operator routing and a separate exact /node HTTPRoute and SecurityPolicy for dedicated runtimes. Only operator routes allow native admin UI subpaths. Both strip authorization and cookies; node routes also strip administrative identity headers and use native device authentication. Preparation repairs the serving revision's node route before candidate activation. Activation transfers ownership after replacing Gateway. Stop and retirement check ownership and UID, then remove that revision's endpoint before its policy. See the node endpoint contract.

prepareWorkspaceNode calls gateway/node-enrollment-client.ts:createGatewayNodeEnrollment after Gateway readiness. An Agent-owned Secret per Harness kind keeps the setup code and device ID; preparation renews expired setup codes. A Codex Harness reads the code from an optional Secret volume, so enrollment restarts neither workload (Harness storage). Other Harnesses are replaced, restarting their Gateway.

The chart supplies worker credentials/public trust and Compute installs node access to Envoy. Memory uses node duplex with existing native file workers; index and embedding configuration stay on Gateway. Skills uses remote discovery, reads and policy-checked dependency installation. Each host initializes its own image assets; Gateway-provided Skills stay local. See the ownership table. Remote channel menus remain deferred to #241.

Only Harness mounts dedicated workspace/generated-image storage. Gateway sessions use its private PVC; Codex's existing remote-media reader transfers reply artifacts before cleanup. Embedded storage is unchanged. New Harness PVCs use RWO; owned existing RWX claims retain their data. The worker stops predecessors before dedicated preparation and suppresses their maintenance. The storage contract owns downtime and recovery limits. These contracts require matching runtime images; local checks do not prove deployed acceptance.

The API reads the mounted key for each operation, so new connections pick up Secret rotation without a restart. Missing routing, missing or invalid keys, expired deadlines, and unavailable targets fail closed. No URL or credential comes from caller JSON or headers.

7. Envoy authenticates and routes the native connection

apps/controller/src/gateway/workspace-files-client.ts:requestNativeWorkspaceFile opens WSS with only the service key in x-api-key. The client verifies the server hostname and CA; there is no leaf pin, device enrollment, native token, or client-certificate option. It connects as a backend operator with deviceIdentity: null and no self-asserted scopes.

The Gateway-level Envoy SecurityPolicy verifies and strips the key. The exact Agent HTTPRoute overwrites x-occ-identity, removes forwarded and native-scope headers, and sets X-Real-IP to Envoy's direct downstream socket address. It rewrites the upgrade path to / and selects the existing same-namespace Agent gateway Service. Namespace attachment labels, route ownership checks, and restricted Kubernetes RBAC protect this mapping.

Kubernetes Compute renders native trust from Installation network.gatewayTrustedProxyCidrs, fixing occ-workspace-files with operator.admin. Conflicting tenant trust settings fail deployment. allowRealIpFallback accepts its genuine nonloopback OCC connection address even within a shared Pod CIDR. NetworkPolicy admits only Envoy to the native gateway; the CIDR is not an independent authentication boundary. Native hello grants operator.admin; reads also accept operator.read.

8. Native file access returns a bounded result

apps/controller/src/gateway/workspace-files-client.ts:requestNativeWorkspaceFile

The client invokes agents.files.get or agents.files.set for native Agent main. Reads enforce the response content limit and return { name, content }; writes return { name, size }. There is no list, delete, compare-and-swap, generic RPC, chat bridge, or PostgreSQL file copy.

The Harness PVC retains the dedicated workspace across Pod replacement. Certificate renewal under the same trusted CA affects new WSS connections without restarting OCC. Root-CA replacement follows the trust rotation requirements.

Writes audit only the Agent resource, authorization action, outcome, reason when present, and file name. If a dispatched write has an unknown outcome, OCC returns 503 UNKNOWN_OUTCOME, attempts the corresponding audit, and never replays it. The native client closes in the operation's cleanup path.

Debugging and Verification

Search documentation