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:
- Native admin UI and private gateway routing.
- Standard OpenClaw and Standard Codex Preset seeding.
- Kubernetes Compute, Kubernetes Configuration, Kubernetes Secrets, native IAM, private metrics, digest-pinned images, DNS policy, trusted proxy CIDRs, and plugin-status proxy CIDRs.
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.
{ "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:
{ "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:
{ "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.
{ "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:
{ "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:
node scripts/render-installation-profile.mjs \ --profile codex \ --input .build/profile-inputs/codex.json \ --out-dir .build/profile-renders/codexOn success, the output directory contains:
values.yaml: Helm values fordeploy/helm/openclaw-enterprise, includingcontrolPlane.installationChecksumcomputed from the exact renderedinstallation.yamlbytes.installation.yaml: Installation startup YAML for theocc-installation-startupSecret.preflight.json: rendered output paths, warnings, prerequisites, and next steps.
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:
- Kubernetes 1.35 or later, enforced NetworkPolicies, and exact API/database egress destinations.
- Envoy Gateway, cert-manager, and, unless external sign-in disables native admin, wildcard DNS and TLS for native admin and the shared cookie parent domain.
- A default ReadWriteOnce storage class for dedicated Codex workspace claims and
runtime.gatewayStorageClassNamefor gateway state. - For Codex, the configured localhost seccomp profile installed and verified on
every node selected by
runtime.nodeSelector. - For Slack, a proxy route for both gateway runtime traffic and Console
directory lookup. The managed proxy serves both; external proxies need both
URLs. Rendering proxy wiring does not enable a Slack consumer. Either profile
can install the managed
proxy for API directory lookup and dedicated gateway use, but Slack-enabled
Agents require dedicated Codex execution. The example input sets
managedSlackProxy: trueto use the chart-managed proxy Service. Its network policy allows public IPv4 HTTPS, excluding private and reserved ranges, and the proxy authorizes Slack hostnames, so connectivity survives Slack DNS rotation. For an external proxy, omitmanagedSlackProxyand provide literal IPv4runtimeProxyUrlanddirectoryProxyUrlinputs. - For Codex hosted plugin discovery and runtime authentication, a
same-Namespace
codex_pattoken Secret or a PAT entered during Agent creation. - For optional OCE-managed ChatGPT service-account runtime credentials, the admin Secret, workspace authority, and app connections described in Configure the ChatGPT Backend. Treat managed issuance as unverified until the admin credential flow is separately proven.
- For repositories, create the registry ConfigMap after the first bootstrap
creates Namespace IDs, then rerender with repository support enabled.
Preserve the existing installation's approved GitHub ranges in
repository.upstreamCidrs. For a new installation, obtain the current API and Git IPv4 ranges from GitHub Meta, following the repository installation guide. Do not replace provider ranges with a snapshot of DNS answers: GitHub rotates addresses within those ranges. Both profiles pass these CIDRs through unchanged.
