OpenClaw EnterpriseDOCSGitHub

Render installation profiles

Installation profiles generate the two trusted files used by a production OpenClaw Enterprise install: a Helm values overlay and the Installation startup YAML mounted into the controller. Use a profile when you want the standard OpenClaw or Codex defaults without editing the production examples by hand.

Profiles only render configuration for an already prepared environment. They do not create clusters, Secrets, databases, DNS, certificates, hosted plugin credentials, ChatGPT service accounts, repository registries, or Slack consumers.

Choose a profile

Use openclaw for embedded OpenClaw Agents with the bundled OpenClaw PluginDriver. Operators select plugins manually or through the API. Embedded OpenClaw cannot enable external Slack channels; the Standard OpenClaw preset must leave channels disabled.

Use codex for dedicated Codex Agents with the bundled Codex PluginDriver. By default, hosted plugin discovery and Codex runtime authentication both use a codex_pat token that you supply later: add a same-Namespace Secret or enter the PAT during Agent creation. The renderer does not create the token or make catalog discovery ready.

Both profiles enable:

Seeding both Presets does not change the profile's PluginDriver. An Agent created from the other profile's Preset still needs a compatible driver, runtime, harness mode, credentials, and channel support.

To seed additional Presets, add "presets": { "files": ["/app/deploy/presets/devday.json"] } to the input JSON and rerender. This example adds SWE Agent alongside the standard Presets. Both controller processes must be able to read the files at startup; the renderer validates the list but does not read container files. See Preset initialization for path resolution and startup validation.

Repository support is optional. When enabled, the renderer wires the broker container, GitHub Backend, Repo Driver, and Compute peer. The repository registry needs Namespace IDs that only exist after the first bootstrap, so most installs render with repositories disabled, bootstrap the platform, create the registry, then rerender with repository.enabled: true.

Prepare inputs

Create a JSON file outside the repository or under an ignored local output directory. The renderer rejects any field it does not consume: unsupported fields fail preflight.

json
{  "controlPlane": {    "releaseName": "oce",    "namespace": "openclaw-system",    "clusterName": "production-west",    "controllerImage": "registry.example/openclaw-enterprise/controller@sha256:<64-hex>",    "authBaseUrl": "https://console.example.internal",    "adminEmail": "admin@example.invalid",    "bootstrapPasswordClaimName": "occ-bootstrap-admin-password",    "apiClients": [{ "namespace": "operator-tools", "podLabels": { "app": "operator" } }],    "databaseCidrs": ["10.45.0.12/32"],    "clusterCidrs": ["10.43.0.1/32"],    "dns": { "namespace": "kube-system", "podLabels": { "k8s-app": "kube-dns" } },    "gatewayClassName": "eg",    "gatewayApiKeySecretName": "occ-private-gateway-key",    "agentNativeAdminDomain": "agents.example.internal",    "sharedCookieDomain": "example.internal",    "gatewayTrustedProxyCidrs": ["10.46.0.0/24"],    "pluginStatusProxySourceCidrs": ["10.47.0.10/32"],    "nodeSelector": { "oce-role": "control" }  },  "runtime": {    "image": "registry.example/openclaw-enterprise/runtime@sha256:<64-hex>",    "gatewayStorageClassName": "occ-gateway-rwo",    "nodeSelector": { "oce-role": "agents" },    "gatewayNodeSelector": { "oce-role": "control" },    "transportSecretPrefix": "openclaw-agent-transport"  },  "channels": {    "managedSlackProxy": true  }}

For the codex profile, merge the reviewed Codex seccomp profile and model discovery egress into the base input:

json
{  "runtime": {    "codexSeccompProfile": "openclaw/codex-0.158.0-<profile-sha256>.json"  },  "codex": {    "modelDiscoveryCidrs": ["198.51.100.20/32"]  }}

To have OCE issue managed ChatGPT service-account runtime credentials, add the optional managed ServiceAccount binding. Do this only after you qualify the ChatGPT Backend admin credential path:

json
{  "codex": {    "managedServiceAccounts": {      "workspaceId": "11111111-1111-4111-8111-111111111111",      "adminSecretName": "occ-chatgpt-admin",      "adminSecretKey": "admin-key",      "providerCidr": "198.51.100.30/32"    }  }}

Managed issuance is separate from the default codex_pat path. The rendered Backend and ServiceAccount Driver wiring does not prove that live service-account creation works.

To show Installation administrators an external Observability console link, set controlPlane.observabilityUrl. The renderer writes it as observability.url and rejects URLs the controller would reject at startup.

External sign-in and trusted proxies

Activation of GitHub or Google sign-in is one-way, so keep these inputs in every later rerender. Adding controlPlane.github or controlPlane.google ({} uses the chart's Secret defaults) renders auth.github or auth.google with enabled: true and agentNativeAdmin.enabled: false; remove agentNativeAdminDomain and sharedCookieDomain. recoveryUserId and an HTTPS authBaseUrl are required. Follow Enable GitHub browser sign-in. Behind a proxy that adds forwarded headers, such as ingress-nginx, set trustedProxy (presets); it works with or without external sign-in.

json
{  "controlPlane": {    "recoveryUserId": "<administrator user ID>",    "github": {      "secretName": "occ-github-login",      "egressCidrs": ["140.82.112.0/20"]    },    "google": { "allowedDomains": ["example.com"] },    "trustedProxy": { "preset": "ingress-nginx", "cidrs": ["10.42.0.0/16"] }  }}

github and google also accept clientIdKey and clientSecretKey; trustedProxy accepts clientAddressHeader, required for the generic preset.

If you opt in to repositories, add the broker inputs:

json
{  "repository": {    "enabled": true,    "image": "registry.example/openclaw-enterprise/repository-credentials@sha256:<64-hex>",    "backendId": "github-primary",    "registryConfigMapName": "occ-repository-registry-v1",    "serviceConfigSecretName": "occ-repository-service-config",    "appKeySecretName": "occ-repository-app-key",    "tlsSecretName": "occ-repository-tls",    "publicCaSecretName": "occ-repository-public-ca",    "serviceName": "git",    "upstreamCidrs": ["198.51.100.0/24"]  }}

serviceName is optional. When omitted, the renderer leaves it out of values.yaml: a new installation gets the chart's git Service, and a Helm upgrade fails until you set it. When upgrading an installation whose broker Service has another name, set serviceName to that current name so TLS and active repository sessions keep working, then switch it deliberately after sessions drain.

Render files

Run the renderer from the repository root with Node.js 24 or newer:

sh
node scripts/render-installation-profile.mjs \  --profile codex \  --input .build/profile-inputs/codex.json \  --out-dir .build/profile-renders/codex

On success, the output directory contains:

After validating the CLI arguments, the renderer deletes these three files from the output directory before it reads the input. It keeps other files. If required input is missing or unsupported input is present, it writes preflight.json with ok: false and only the report path in outputs, leaves both YAML files absent, and exits nonzero. If the input JSON is unreadable or malformed, it exits without writing a preflight report.

Use rendered files

Set OCC_INPUT_DIRECTORY to the output directory, then complete the production shell and context setup. Skip both configuration-generation branches and continue at the shared bootstrap PVC and configuration checks. The runbook covers Secret creation, Helm installation, bootstrap key retrieval, and authenticated API verification.

If rendering fails or either YAML file is absent, stop and fix the input. Do not copy manual examples into the same output directory. Rerender successfully so values.yaml, installation.yaml, and controlPlane.installationChecksum stay paired.

Required environment checks

The renderer does not check these prerequisites. Verify them before you treat the install as ready:

Search documentation