OpenClaw EnterpriseDOCSGitHub

Harness Authentication Binding Flow

Overview

An operator stores an OpenAI or Anthropic API key, or a service account token, as an OCC Secret or separately issues a ChatGPT account credential, then selects that source through Agent harnessAuth. Deployment freezes the authorized binding; the worker rechecks it and Kubernetes renders the credential only into the model-executing workload. This flow ends at runtime authentication and the existing guarded activation handoff. Issuance and source storage retain their existing owners. With { "method": "runtime" }, the operator supplies credentials directly on an SSH host instead; OCC freezes only the method and performs gateway readiness without model authentication.

Entry Points

Flow

graph TD
  A["Store key or separately issue account credential"] --> B["Save Agent harnessAuth reference"]
  R["Operator provisions protected host env"] --> B
  D -->|runtime| S["SSH starts embedded gateway using host env"]
  S --> T["Check gateway readiness; model auth remains unverified"]
  B --> C["Authorize and freeze binding in revision"]
  C --> D["Worker rechecks grants and source ownership"]
  D -->|denied or changed source| E["Reject candidate before projection"]
  D -->|valid managed source| F["Kubernetes prepares explicit login mode and projections"]
  F --> G{"Admitted topology"}
  G -->|embedded API key| H["Create or replace shared gateway with projected key"]
  G -->|dedicated key or account| I["Only Codex receives model credential"]
  I --> J{"Login and primary model turn succeed?"}
  J -->|first model subprocess timeout| P["Wait one second within startup budget"]
  P --> Q{"Second model probe succeeds?"}
  Q -->|yes| L
  Q -->|no| K["Candidate remains unready"]
  J -->|login or nonretryable failure| K
  J -->|yes| L["Runtime readiness and guarded activation"]
  H --> M{"Native primary model probe succeeds?"}
  M -->|no| N["Gateway stays unready; replacement may interrupt service"]
  M -->|yes| O["Gateway becomes ready; complete activation"]

Execution Trace

1. Save one source without issuing credentials

Before saving, Console can call the selected Compute Driver's apps/controller/src/drivers/compute/model-discovery.ts:discoverHarnessModels to discover models without storing the credential. OpenAI API-key discovery omits models whose valid shutdown_date is today or earlier in UTC, using the provider's model-list contract. Missing, null, malformed, or future dates remain in the list; model age and IDs do not imply expiry. This filter does not apply to Anthropic or the service account token catalog. Discovery does not prove that a model call will succeed.

packages/occ/src/index.ts:OpenClawController.createAgent, updateAgent, authorizeHarnessAuthSource

Creation omission stores null; PATCH omission preserves the binding and explicit null clears it. API-key and codex_pat sources use stable OCC Secret references; the method remains distinct even for the same Secret. The actor needs exact Secret operate; a ChatGPT binding needs exact account read. Namespace locks serialize source reference changes against deletion. Missing or foreign sources fail closed. Binding never selects a different model, Backend, Harness, or execution mode and cannot issue an account credential.

The Secret storage flow owns value storage; account issuance owns upstream credentials and their private Backend binding. Initial runtime provisioning creates only transport/channel groups and cannot supply model authentication.

2. Freeze the admitted source and compatibility

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

Deployment requires a nonnull binding, exact Agent deploy, and Configuration read. For a key or service account token, OCC checks the actor and Agent principal's Secret operate, resolves the backend through the selected Secret Driver, and freezes the stable reference and Driver identity. For a ChatGPT account, it verifies the issued access-token reference and private Backend, member Driver, and workspace ownership. runtime needs no source grant, lookup, or delivery metadata. The selected Compute validates the combination: SSH accepts only embedded OpenClaw with runtime; Kubernetes continues to require managed authentication.

A runtime revision records only { "method": "runtime" }. Host credential changes can affect that revision after restart without redeployment; see the SSH lifecycle.

The revision contains references and safe internal metadata, never credential bytes. Public revision serialization exposes the binding while omitting backend locators and private account ownership. A later account credential cannot replace the admitted reference; changing the draft affects the next explicit deployment.

3. Reauthorize the immutable revision before effects

apps/controller/src/worker.ts:ControllerWorker.resolveRevisionBackend, resolveRevisionSecretContext

The worker authorizes the original deploying actor and required Agent Secret grants against the admitted revision. It verifies current source ownership and matches managed-account credential and Backend metadata against the frozen snapshot. Revocation or a changed source rejects work before provisioning. For runtime, worker Agent/Configuration authorization still runs but credential source authorization and lookup do not. The dispatch context carries only the method; SSH does not read the operator credential file or issue a model probe.

For an API key or directly supplied service account token, the worker resolves backend ownership from OCC state and passes an ephemeral ComputeRevisionContext. It does not read credential bytes or rewrite the revision. Compute subsequently reads the canonical CP source, verifies the admitted Secret UID or managed-account ownership, and delivers only selected fields into the DP revision Secret. Missing or replaced sources fail preparation. ChatGPT retains the exact account token/workspace source. Inactive revision history keeps references without indefinitely retaining their sources; drafts, active revisions, and pending deployments block source deletion.

4. Prepare and place the one credential projection

apps/controller/src/drivers/compute/kubernetes/index.ts:prepareHarnessAuth, KubernetesComputeDriver.prepareRevision

One internal workload-rendering step converts validated references to supported Secret projections and a closed login mode. Embedded OpenClaw receives the key in its combined workload as OPENAI_API_KEY or ANTHROPIC_API_KEY, derived from the immutable native model Configuration. Admission requires all selected models and fallbacks to use the same supported provider. Dedicated Codex receives the key or account token/workspace through a revision-owned DP projection. A directly supplied service account token delivers only CODEX_ACCESS_TOKEN as the model credential; its separate Gateway receives no model credential. Canonical sources remain in CP. Configuration secret bindings remain gateway-only and cannot choose model auth.

The selected Sandbox consumes these already-rendered HarnessWorkloadRequirements, including the explicit login mode and projections. It does not select or look up another credential. An upstream runtime unable to honor genuine Secret projection fails explicitly. Network policies retain the provider-login egress required by the admitted auth method. Gateway transport and Kubernetes workload identity remain separate credentials.

5. Authenticate during runtime startup

apps/controller/src/drivers/compute/kubernetes/runtime-entrypoints.ts:AGENT_RUNTIME_ENTRYPOINT, GATEWAY_RUNTIME_ENTRYPOINT

Codex consumes explicit CODEX_LOGIN_MODE: API-key login receives the key through stdin; managed account login forces the admitted workspace. Direct service account token login uses --with-access-token without a caller-supplied workspace; native whoami validates and hydrates identity. Credential environment variables are deleted before the probe and app-server start. Missing or conflicting inputs and failed login prevent app-server startup. A bounded native turn against the primary model must then complete successfully. The probe ignores user rules and configuration, disables execution and external tools, and applies read-only filesystem policy without approval grants. Tool events fail the probe. Login state remains in the bounded ephemeral home.

startAuthenticatedCodex gives probeCodexAuthentication a maximum of two attempts within one monotonic 61-second budget. Only the subprocess's ETIMEDOUT result schedules the second attempt after a one-second timer; an unexplained SIGKILL is a nonretryable failure. The next process timeout is the smaller of 30 seconds and the remaining budget. No termination handler is installed during the delay, so stopping the launcher prevents the second call. Only successful validation starts the app-server and publishes readiness.

Embedded OpenClaw consumes the selected provider's native API key and runs one bounded native primary-model probe in the actual gateway startup, with tools and fallback disabled. Its 16-token output limit meets the provider's minimum request size. Initial and replacement deployments use this same startup path. For replacement, activation first updates the shared gateway's Recreate Deployment, which can stop the serving gateway before the new process validates credentials. Invalid credentials or provider failure hold the replacement unready, leaving the Agent unavailable until repair and restart or a new deployment. No automatic rollback restores the predecessor.

Both runtimes capture native output and hold final failures unready with a fixed message. Codex additionally logs allowlisted per-attempt timing, exit classification, and outcome, without raw output. It publishes the existing runtime failure only after retry exhaustion or a nonretryable result. Readiness polling does not repeat provider calls; restart or deployment starts a new bounded startup check. These requests may incur usage charges and check only the primary model. See probe limitations.

The existing activation and recovery flow completes activation after readiness. Auth selection and successful storage do not establish provider acceptance. Updating a Secret leaves existing process environments and DP runtime copies unchanged until preparation: deploy each consumer, verify a real turn, then revoke the previous key upstream. Revision history cannot restore historical Secret values.

Debugging and Verification

Search documentation