OpenClaw EnterpriseDOCSGitHub

Develop a Driver

Use this guide to add an implementation of an existing OpenClaw Control Plane (OCC) Driver contract. The Installation selects Drivers; an individual Agent or tenant cannot install or switch them. Start with the contract for the capability you are changing.

1. Choose the contract

The shared TypeScript contracts define the methods and data each Driver exchanges with OCC. The base Driver types are separate from each capability's drivers/<capability>/index.ts. Each reference links its interface file, explains who calls those methods, what each implementation must enforce, and which failures must stop the operation:

Installed npm packages can implement Compute, Configuration, IAM, or Sandbox. A Sandbox package can also provide Credential Proxy through one registration; follow the Credential Proxy walkthrough for that paired capability and its profile limits. Secret, Plugin, and ServiceAccount have bundled selections only. If you need one of those capabilities, change the existing platform implementation; adding an npm package alone will not make it selectable. Use the supported selections and repository layout to find its owner. Bundled infrastructure implementations live under apps/controller/src/drivers/; native IAM lives in packages/iam/. Composition lives in apps/controller/src/composition/.

Use the contracts in a separate Driver project

From the OpenClaw Enterprise repository root, with dependencies installed via pnpm install --frozen-lockfile, pack both packages from the same revision. Set archives to the absolute path of the vendor directory in your Driver project.

sh
archives=/absolute/path/to/driver-project/vendormkdir -p "$archives"pnpm --dir packages/utils pack --out "$archives/utils.tgz"pnpm --dir packages/contracts pack --out "$archives/contracts.tgz"

In the Driver project's root pnpm-workspace.yaml, add this entry to the top-level overrides mapping. The path is relative to the workspace root.

yaml
overrides:  "@openclaw-enterprise/utils": "file:./vendor/utils.tgz"

From that same root, run pnpm add ./vendor/contracts.tgz. The override resolves the contracts package's dependency on @openclaw-enterprise/utils to the local archive. Your TypeScript code can then import from @openclaw-enterprise/contracts.

2. Implement and register it

For an installed implementation, export a closed configurationSchema, validateConfiguration, and createDriver from a precompiled JavaScript ESM entry point. The platform validates structure before calling the semantic validator, which returns a readonly field-error list (empty on success), as described in configuration definitions; factories consume the original validated input. Callbacks receive an isolated, frozen copy and cannot replace configuration values. Declare runtime contributions only when a resource-owner binding supplies their authorization and lifecycle. A Sandbox advertising networkPolicy must contribute (agent, sandbox-network-policy). Return the selected id and implementation, the expected capability, and its required methods on each capability object. For paired capabilities, return one DriverRegistration with shared lifecycle hooks instead of independent instances. The controller must declare the package as a direct production dependency at an exact version; update the lockfile with it. For a bundled implementation, follow the existing capability directory and wire it into controller composition. Consult the package and factory contract for the complete loader rules.

Implement the failure paths as carefully as the successful ones. OCC owns platform authorization and resources; an execution Driver acts on the admitted scope it receives. Check backend ownership before changing a resource, make retried operations safe where the contract requires it, and fail rather than silently switching backends or broadening access. An installed package runs with control-plane authority, so its publisher and code need review. Startup validation can reject the wrong shape; it cannot establish that the code protects tenant boundaries.

3. Verify and document the change

Run the following from the repository root with dependencies installed:

sh
pnpm typecheckpnpm test:files -- tests/integration/driver-plugin-installation.test.ts

The second command exercises package installation and controller admission for fixture Drivers. It does not verify your backend. Extend the relevant conformance and integration coverage and exercise your implementation through its normal API or worker caller, with the real backend needed to prove the behavior. Cover consequential failures such as an unavailable backend, access outside the admitted scope, or cancellation where supported.

Update the capability reference or implementation guide and the owning runtime flow when behavior changes. Use the contributor documentation guide for placement and writing conventions.

Check protected static Secret reads

Copy the test-only helper into your Node.js 24 test project with packed contracts types. Call await assertProtectedStaticSecretRead(t, driver, identity, isIdentityRefusal, 1_000) inside test("protected read", { timeout: 5_000 }, async (t) => { /* call here */ }); run it with node --test your-adapter.test.ts. Supply a disposable Driver, valid SecretIdentity, and exact adapter error matcher. All reads share the supplied millisecond budget; Node's finite enclosing timeout fails hung reads and runs cleanup. The helper creates, rotates, and deletes one synthetic Secret. A create without a returned reference cannot be cleaned up. Cancellation does not prove I/O drained. This local check does not certify a backend or enable external Secret installation.

Search documentation