Skip to content

add codex oauth option#183

Closed
sallyom wants to merge 1 commit into
codeready-toolchain:masterfrom
sallyom:add-codex-oauth
Closed

add codex oauth option#183
sallyom wants to merge 1 commit into
codeready-toolchain:masterfrom
sallyom:add-codex-oauth

Conversation

@sallyom

@sallyom sallyom commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

This adds codex oauth option. Most who use OpenAI models use OAuth.

Summary by CodeRabbit

  • New Features

    • Added Codex OAuth authentication support for OpenAI integration via Kubernetes Secret configuration.
    • Enabled model selection and profile customization for Codex OAuth credentials.
    • Added ChatGPT.com domain passthrough support.
  • Documentation

    • Updated setup instructions with Codex OAuth configuration examples and best practices.

Signed-off-by: sallyom <somalley@redhat.com>
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds Codex OAuth support to the Claw operator, enabling deployments to authenticate with ChatGPT using Codex CLI credentials. A new CodexOAuthSpec API contract is introduced and validated early during reconciliation. OAuth token data is extracted from a Kubernetes Secret, injected into the operator.json config with auth profiles and agent model mappings, mounted into the init container, and imported into per-agent credential profiles at pod startup. The gateway Deployment is mutated to reference the OAuth secret and inject the normalized profile ID. The proxy config is updated to allow passthrough for ChatGPT API backend endpoints.

Changes

Codex OAuth Support

Layer / File(s) Summary
API schema and contract
api/v1alpha1/claw_types.go, api/v1alpha1/zz_generated.deepcopy.go, config/crd/bases/claw.sandbox.redhat.com_claws.yaml
CodexOAuthSpec type is introduced with kubebuilder validation requiring secretRef, and optional fields for profileID, model, and models. ClawSpec is extended with an optional codexOAuth field. Deepcopy methods are autogenerated. The CRD schema is updated to enforce the structure and validation rules.
OAuth validation and normalization
internal/controller/claw_codex_oauth.go (constants, helpers, validation)
Codex OAuth constants define default profile IDs, model names, and volume/mount identifiers. Helper functions normalize profile IDs and model references. A validation method fetches the referenced Secret, extracts and validates the required auth.json payload, ensuring auth mode is "chatgpt" and tokens are present.
Config injection and deployment mutation
internal/controller/claw_codex_oauth.go (config injection, deployment mutation), internal/assets/manifests/claw/configmap.yaml (init script)
The injectCodexOAuthConfig function updates operator.json with plugin allowlists, auth profiles, and agent model mappings with runtime IDs. The configureClawDeploymentForCodexOAuth function mutates the gateway Deployment to mount the OAuth secret and inject the profile ID env var. The init script now decodes JWT payloads, validates auth.json structure, collects agent IDs, and imports OAuth credential profiles into per-agent auth-profiles.json files with 0o600 permissions.
Controller reconciliation wiring
internal/controller/claw_resource_controller.go
The reconcile loop validates Codex OAuth config early and sets Ready=False on failure. The injectCodexOAuthConfig call is inserted into the operator.json enrichment pipeline. The configureClawDeploymentForCodexOAuth call is added to the deployment configuration sequence. Secret change-to-reconcile mapping now includes the Codex OAuth Secret.
Tests, documentation, and proxy updates
internal/controller/claw_codex_oauth_test.go, internal/controller/claw_proxy.go, internal/controller/claw_proxy_test.go, README.md, docs/user-guide.md
Tests validate the full reconciliation flow (ConfigMap content, token redaction, Deployment mounting), failure cases for missing/invalid Secrets, and Secret-to-reconcile mapping. The proxy config is updated to allow chatgpt.com passthrough restricted to /backend-api/. The README and user guide document OAuth secret creation, manifest configuration, validation behavior, and profile ID defaults.

Sequence Diagram

sequenceDiagram
  participant Reconcile as Reconcile Loop
  participant Validate as validateCodexOAuthConfig
  participant Inject as injectCodexOAuthConfig
  participant Deploy as configureClawDeploymentForCodexOAuth
  participant InitScript as merge.js InitScript
  
  Reconcile->>Validate: validate Secret + auth.json
  Validate->>Validate: extract tokens, verify auth_mode
  Reconcile->>Inject: inject OAuth config to operator.json
  Inject->>Inject: set auth profiles, plugin allowlist, agent models
  Reconcile->>Deploy: mutate Deployment for OAuth
  Deploy->>Deploy: add secret mount + profile ID env var
  Deploy->>InitScript: secret mounted to init container
  InitScript->>InitScript: decode auth.json, import profiles to auth-profiles.json
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • codeready-toolchain/claw-operator#143: Refactors the enrichConfigAndNetworkPolicy pipeline in internal/controller/claw_resource_controller.go to support map-based config merging, which is the same call-site where this PR injects injectCodexOAuthConfig.

Suggested labels

feature, test, documentation

Suggested reviewers

  • alexeykazakov
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'add codex oauth option' is vague and generic, using non-descriptive phrasing that doesn't clearly convey the scope or significance of the changes. Consider a more descriptive title such as 'Add Codex OAuth support for OpenAI provider' or 'Support OpenAI OAuth configuration via Claw CR' to better communicate the feature addition.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation feature New feature or request test Work that adds, fixes, or maintains automated tests or coverage (unit, integration, e2e, flakiness) labels Jun 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/assets/manifests/claw/configmap.yaml`:
- Around line 134-161: The importCodexOAuthProfiles function currently only
upserts store.profiles[codexOAuthProfileId] and never removes operator-managed
Codex entries, so disabling spec.codexOAuth or changing profileID leaves stale
credentials in each agent's auth-profiles.json; update importCodexOAuthProfiles
(and the logic that runs when codexOAuthPath is missing) to iterate
configuredAgentIds(config) and, for each agent storePath, remove the old
operator-managed profile key(s) (at minimum the previous codexOAuthProfileId and
the current codexOAuthProfileId when spec.codexOAuth is absent or profileID
changed), then write back the store (or delete the file if profiles becomes
empty) preserving file permissions (mode 0o600); use the existing symbols
codexOAuthProfileId, configuredAgentIds, and storePath to locate and prune
entries.

In `@internal/controller/claw_proxy_test.go`:
- Around line 698-707: The test "should order exact matches before suffix
matches" in TestGenerateProxyConfig expects a hard-coded domain order that was
changed by adding a new exact-match route ("chatgpt.com"); update the expected
domain list in that test (the assertion that compares generated routes from
generateProxyConfig) to include "chatgpt.com" among the exact-match entries (so
it appears before suffix matches like "clawhub.ai") and adjust the assertion
accordingly so exact matches are still asserted to come before suffix matches.

In `@README.md`:
- Around line 199-225: The example manifest only sets spec.codexOAuth which will
replace the resource's spec and drop any existing spec.credentials; update the
README example to show a safe approach that preserves existing
credentials—either include existing spec.credentials alongside spec.codexOAuth
in the sample Claw manifest (so the apply is additive) or demonstrate using a
merge/patch operation (e.g., oc/kubectl patch or a strategic merge) to add
spec.codexOAuth without overwriting spec.credentials; reference the Claw
resource and the spec.codexOAuth and spec.credentials fields in the instructions
so users know which keys must be preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: e32d4951-53ee-480a-8327-03e226c54750

📥 Commits

Reviewing files that changed from the base of the PR and between a24a2ae and a2b5e45.

📒 Files selected for processing (11)
  • README.md
  • api/v1alpha1/claw_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/claw.sandbox.redhat.com_claws.yaml
  • docs/user-guide.md
  • internal/assets/manifests/claw/configmap.yaml
  • internal/controller/claw_codex_oauth.go
  • internal/controller/claw_codex_oauth_test.go
  • internal/controller/claw_proxy.go
  • internal/controller/claw_proxy_test.go
  • internal/controller/claw_resource_controller.go
📜 Review details
🧰 Additional context used
📓 Path-based instructions (7)
internal/controller/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Set owner references on all created resources via controllerutil.SetControllerReference

Files:

  • internal/controller/claw_proxy.go
  • internal/controller/claw_proxy_test.go
  • internal/controller/claw_resource_controller.go
  • internal/controller/claw_codex_oauth.go
  • internal/controller/claw_codex_oauth_test.go
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Include Go license header from hack/boilerplate.go.txt template in all Go source files
Run golangci-lint via make lint and use make lint-fix for auto-fixing, with .golangci.yml configuration including lll and dupl linters enabled
Use make fmt (go fmt) and make vet (go vet) for code formatting and vetting before committing

Files:

  • internal/controller/claw_proxy.go
  • internal/controller/claw_proxy_test.go
  • api/v1alpha1/claw_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • internal/controller/claw_resource_controller.go
  • internal/controller/claw_codex_oauth.go
  • internal/controller/claw_codex_oauth_test.go
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • internal/controller/claw_proxy.go
  • docs/user-guide.md
  • internal/controller/claw_proxy_test.go
  • api/v1alpha1/claw_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • README.md
  • config/crd/bases/claw.sandbox.redhat.com_claws.yaml
  • internal/controller/claw_resource_controller.go
  • internal/controller/claw_codex_oauth.go
  • internal/assets/manifests/claw/configmap.yaml
  • internal/controller/claw_codex_oauth_test.go
**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*_test.go: Use require assertion from testify for fatal setup errors in tests, and assert for value comparisons
Structure tests with Test* function names, use t.Run() for subtests, t.Cleanup() for cleanup, and implement table-driven test patterns
Use waitFor(t, timeout, interval, condition, message) helper for async test assertions with 10s timeout and 250ms poll interval
Create separate test files per resource type (e.g., claw_configmap_test.go, claw_credentials_test.go)

Files:

  • internal/controller/claw_proxy_test.go
  • internal/controller/claw_codex_oauth_test.go
api/v1alpha1/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Modify API types in api/v1alpha1/ and run make manifests to regenerate CRD YAML in config/crd/bases/ and make generate to regenerate zz_generated.deepcopy.go

Files:

  • api/v1alpha1/claw_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
internal/controller/**/*_controller.go

📄 CodeRabbit inference engine (CLAUDE.md)

Apply RBAC authorization via // +kubebuilder:rbac:... markers on reconciler methods in the controller

Files:

  • internal/controller/claw_resource_controller.go
internal/assets/manifests/**/*.{yaml,yml}

📄 CodeRabbit inference engine (CLAUDE.md)

internal/assets/manifests/**/*.{yaml,yml}: Configure pod security with non-root user (uid 65532), restricted seccomp profile, and drop all Linux capabilities
Set readOnlyRootFilesystem: true on proxy and wait-for-proxy containers, but not on init-config or gateway containers which require writable paths for Node.js and AI tools

Files:

  • internal/assets/manifests/claw/configmap.yaml
🧠 Learnings (5)
📚 Learning: 2026-06-01T02:00:32.268Z
Learnt from: CR
Repo: codeready-toolchain/claw-operator PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-01T02:00:32.268Z
Learning: Use the MITM proxy to inject credentials transparently, with known providers getting auto-inferred defaults from the centralized `knownProviders` registry in `claw_providers.go`

Applied to files:

  • internal/controller/claw_proxy.go
  • docs/user-guide.md
📚 Learning: 2026-06-01T02:00:32.268Z
Learnt from: CR
Repo: codeready-toolchain/claw-operator PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-01T02:00:32.268Z
Learning: Applies to api/v1alpha1/**/*.go : Modify API types in `api/v1alpha1/` and run `make manifests` to regenerate CRD YAML in `config/crd/bases/` and `make generate` to regenerate zz_generated.deepcopy.go

Applied to files:

  • api/v1alpha1/zz_generated.deepcopy.go
  • README.md
📚 Learning: 2026-06-01T02:00:32.268Z
Learnt from: CR
Repo: codeready-toolchain/claw-operator PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-01T02:00:32.268Z
Learning: Manage Kubernetes resources via Kustomize with server-side apply in the unified `ClawResourceReconciler` controller managing all resources through two components: `claw/` and `claw-proxy/`

Applied to files:

  • internal/controller/claw_resource_controller.go
  • internal/controller/claw_codex_oauth.go
📚 Learning: 2026-05-27T15:29:16.197Z
Learnt from: alexeykazakov
Repo: codeready-toolchain/claw-operator PR: 149
File: internal/assets/manifests/claw/kustomization.yaml:19-19
Timestamp: 2026-05-27T15:29:16.197Z
Learning: In this repo’s claw Kustomize YAML manifests, when an image tag for ghcr.io (specifically ghcr.io/openclaw/openclaw) is being verified via `crane manifest` in an unauthenticated environment, a `not found` result can be caused by missing registry authentication (false positives). Do not flag the tag as missing based solely on that `crane manifest` output; require an authenticated verification step (e.g., GHCR login/token) or another independent check before concluding the tag is absent.

Applied to files:

  • internal/assets/manifests/claw/configmap.yaml
📚 Learning: 2026-06-01T02:00:32.268Z
Learnt from: CR
Repo: codeready-toolchain/claw-operator PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-06-01T02:00:32.268Z
Learning: Applies to **/*_test.go : Create separate test files per resource type (e.g., `claw_configmap_test.go`, `claw_credentials_test.go`)

Applied to files:

  • internal/controller/claw_codex_oauth_test.go
🔇 Additional comments (1)
internal/controller/claw_resource_controller.go (1)

1675-1677: ⚡ Quick win

Clarify Secret-rotation rollout: Codex OAuth auth.json is (or isn’t) covered by pod-template secret-version stamping

The operator already stamps pod-template annotations with Secret resourceVersions to trigger a rolling update (r.stampSecretVersionAnnotation(ctx, objects, instance)), and the secret-to-reconcile mapping includes instance.Spec.CodexOAuth.SecretRef.Name == secretName (lines 1675-1677 in internal/controller/claw_resource_controller.go). This directly undercuts the claim that secret rotation would leave auth-profiles.json stale until an unrelated rollout.

That said, the actual behavior depends on whether stampSecretVersionAnnotation includes the Codex OAuth Secret in the set of Secrets it stamps (needs the implementation in internal/controller/claw_proxy.go). If it does, Secret rotation will restart the gateway pod template and the init-config import will run again; if it doesn’t, the original concern still applies.

Comment on lines +134 to +161
function importCodexOAuthProfiles(config) {
if (!fs.existsSync(codexOAuthPath)) return;
const credential = codexOAuthCredentialFromAuthJson(fs.readFileSync(codexOAuthPath, "utf8"));
for (const agentId of configuredAgentIds(config)) {
const storePath = path.join(pvcDir, "agents", agentId, "agent", "auth-profiles.json");
let store = { version: 1, profiles: {} };
if (fs.existsSync(storePath)) {
try {
const existing = JSON.parse(fs.readFileSync(storePath, "utf8"));
if (existing && typeof existing === "object" && !Array.isArray(existing)) {
store = {
version: existing.version || 1,
profiles: existing.profiles && typeof existing.profiles === "object" && !Array.isArray(existing.profiles)
? existing.profiles
: {},
};
}
} catch {
console.warn(`[init-config] existing ${storePath} is invalid JSON; replacing it`);
}
}
store.version = 1;
store.profiles[codexOAuthProfileId] = credential;
fs.mkdirSync(path.dirname(storePath), { recursive: true });
fs.writeFileSync(storePath, JSON.stringify(store, null, 2), { mode: 0o600 });
fs.chmodSync(storePath, 0o600);
console.log(`[init-config] imported Codex OAuth profile for ${agentId}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Disabling Codex OAuth does not remove the persisted credential.

This path only upserts store.profiles[codexOAuthProfileId]. When spec.codexOAuth is removed, or when profileID changes, the previous ChatGPT refresh token stays under /home/node/.openclaw/agents/*/agent/auth-profiles.json indefinitely because nothing prunes operator-managed Codex profiles. That means turning the feature off does not actually remove the credential from the PVC.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assets/manifests/claw/configmap.yaml` around lines 134 - 161, The
importCodexOAuthProfiles function currently only upserts
store.profiles[codexOAuthProfileId] and never removes operator-managed Codex
entries, so disabling spec.codexOAuth or changing profileID leaves stale
credentials in each agent's auth-profiles.json; update importCodexOAuthProfiles
(and the logic that runs when codexOAuthPath is missing) to iterate
configuredAgentIds(config) and, for each agent storePath, remove the old
operator-managed profile key(s) (at minimum the previous codexOAuthProfileId and
the current codexOAuthProfileId when spec.codexOAuth is absent or profileID
changed), then write back the store (or delete the file if profiles becomes
empty) preserving file permissions (mode 0o600); use the existing symbols
codexOAuthProfileId, configuredAgentIds, and storePath to locate and prune
entries.

Comment on lines +698 to +707
t.Run("should include chatgpt.com with backend-api path restriction", func(t *testing.T) {
data, err := generateProxyConfig(nil, nil, nil)
require.NoError(t, err)

var cfg proxyConfig
require.NoError(t, json.Unmarshal(data, &cfg))
route := findRouteByDomain(t, cfg.Routes, "chatgpt.com")
assert.Equal(t, "none", route.Injector)
assert.Equal(t, []string{"/backend-api/"}, route.AllowedPaths)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update the hard-coded route-order test as part of this change.

Line 698 adds a new exact-match builtin route, but TestGenerateProxyConfig/should order exact matches before suffix matches still asserts the pre-change domain list. That test now fails because chatgpt.com sorts before clawhub.ai.

Minimal fix
 		expectedDomains := []string{
 			"api.example.com",
+			"chatgpt.com",
 			"clawhub.ai",
 			"codeload.github.com",
 			"github.com",
 			"openrouter.ai",
 			"raw.githubusercontent.com",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/claw_proxy_test.go` around lines 698 - 707, The test
"should order exact matches before suffix matches" in TestGenerateProxyConfig
expects a hard-coded domain order that was changed by adding a new exact-match
route ("chatgpt.com"); update the expected domain list in that test (the
assertion that compares generated routes from generateProxyConfig) to include
"chatgpt.com" among the exact-match entries (so it appears before suffix matches
like "clawhub.ai") and adjust the assertion accordingly so exact matches are
still asserted to come before suffix matches.

Comment thread README.md
Comment on lines +199 to +225
#### OpenAI Codex OAuth

After logging in with Codex CLI, import ChatGPT OAuth from `~/.codex/auth.json`:

```sh
oc create secret generic codex-oauth \
--from-file=auth.json=$HOME/.codex/auth.json \
-n $NS
```

```sh
oc apply -f - <<EOF
apiVersion: claw.sandbox.redhat.com/v1alpha1
kind: Claw
metadata:
name: instance
namespace: $NS
spec:
codexOAuth:
secretRef:
name: codex-oauth
key: auth.json
model: gpt-5.5
EOF
```

For known providers (`google`, `anthropic`, `openai`, `xai`), the operator infers `type` and `domain` automatically. Codex OAuth is configured separately with `spec.codexOAuth`. For other LLM providers, messaging channels, MCP servers, and more, see the [User Guide](docs/user-guide.md).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve existing credentials in this sample.

This section says Codex OAuth is configured separately, but the manifest only sets spec.codexOAuth. Applying it to an instance that already has spec.credentials removes those entries, so the documented “configure OpenAI separately” flow breaks on the next oc apply. The same caveat applies to the new Codex OAuth example in docs/user-guide.md.

Safer example
 spec:
+  credentials:
+    - name: openai
+      provider: openai
+      secretRef:
+        - name: openai-api-key
+          key: api-key
   codexOAuth:
     secretRef:
       name: codex-oauth
       key: auth.json
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#### OpenAI Codex OAuth
After logging in with Codex CLI, import ChatGPT OAuth from `~/.codex/auth.json`:
```sh
oc create secret generic codex-oauth \
--from-file=auth.json=$HOME/.codex/auth.json \
-n $NS
```
```sh
oc apply -f - <<EOF
apiVersion: claw.sandbox.redhat.com/v1alpha1
kind: Claw
metadata:
name: instance
namespace: $NS
spec:
codexOAuth:
secretRef:
name: codex-oauth
key: auth.json
model: gpt-5.5
EOF
```
For known providers (`google`, `anthropic`, `openai`, `xai`), the operator infers `type` and `domain` automatically. Codex OAuth is configured separately with `spec.codexOAuth`. For other LLM providers, messaging channels, MCP servers, and more, see the [User Guide](docs/user-guide.md).
spec:
credentials:
- name: openai
provider: openai
secretRef:
- name: openai-api-key
key: api-key
codexOAuth:
secretRef:
name: codex-oauth
key: auth.json
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 199 - 225, The example manifest only sets
spec.codexOAuth which will replace the resource's spec and drop any existing
spec.credentials; update the README example to show a safe approach that
preserves existing credentials—either include existing spec.credentials
alongside spec.codexOAuth in the sample Claw manifest (so the apply is additive)
or demonstrate using a merge/patch operation (e.g., oc/kubectl patch or a
strategic merge) to add spec.codexOAuth without overwriting spec.credentials;
reference the Claw resource and the spec.codexOAuth and spec.credentials fields
in the instructions so users know which keys must be preserved.

@alexeykazakov

Copy link
Copy Markdown
Contributor

Thank you for the PR!

However there is a concern with this approach. It keeps the real codex secret in the gateway. Here is a PR with an alternative approach: #184
In #184 no codex secrets are exposed to the gateway. However it addresses the Codex as an LLM provider issue only. Codex support as an agent harness (for coding and other stuff) is not covered in #184. There is a high level proposal doc for that feature though.

@sallyom

sallyom commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

closing in favor of #184 !

@sallyom sallyom closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation feature New feature or request test Work that adds, fixes, or maintains automated tests or coverage (unit, integration, e2e, flakiness)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants