Skip to content

fix(codex): exclude codex-app-server synthetic apiKey from secrets audit#69581

Merged
amknight merged 2 commits intoopenclaw:mainfrom
Sanjays2402:fix/codex-app-server-audit-false-positive
Apr 21, 2026
Merged

fix(codex): exclude codex-app-server synthetic apiKey from secrets audit#69581
amknight merged 2 commits intoopenclaw:mainfrom
Sanjays2402:fix/codex-app-server-audit-false-positive

Conversation

@Sanjays2402
Copy link
Copy Markdown
Contributor

Summary

  • Problem: The secrets audit flags Codex's synthetic apiKey: "codex-app-server" (defined in extensions/codex/provider.ts) as PLAINTEXT_FOUND, even though it's not a real secret — Codex's real authentication lives inside the app-server transport.
  • Why it matters: Every user who has configured the Codex harness sees a false-positive plaintext finding in openclaw secrets audit, eroding trust in the signal.
  • What changed: Declared codex-app-server as a plugin-owned non-secret marker in extensions/codex/openclaw.plugin.json, and extended the existing model-auth-markers unit tests to lock in the behavior. No code changes — just the manifest and a regression test.
  • What did NOT change: Audit logic, isNonSecretApiKeyMarker implementation, any other plugin's manifest. The fix flows through the same path already used by ollama-local, lmstudio-local, gcp-vertex-credentials, and minimax-oauth.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause

  • Root cause: The Codex extension was added without its synthetic codex-app-server apiKey being declared as a non-secret marker on the plugin manifest, while sibling plugins (Ollama, LMStudio, Anthropic-Vertex, Minimax) already do so.
  • Missing detection / guardrail: No explicit assertion that every bundled plugin which uses a synthetic apiKey value in models.json registers it through nonSecretAuthMarkers. (Out of scope for this PR, but could be a follow-up guardrail.)
  • Contributing context: The audit code path (src/secrets/audit.ts:412) already guards plaintext reporting with !isNonSecretApiKeyMarker(apiKey), which in turn calls listKnownNonSecretApiKeyMarkers() — a function that aggregates markers from the plugin manifest registry via loadPluginManifestRegistry({ cache: true }).plugins.flatMap(p => p.nonSecretAuthMarkers). Adding the marker to the Codex manifest is sufficient.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/model-auth-markers.test.ts
  • Scenario the test should lock in:
    1. isNonSecretApiKeyMarker("codex-app-server") returns true.
    2. listKnownNonSecretApiKeyMarkers() includes "codex-app-server" after the manifest registry is loaded.
  • Why this is the smallest reliable guardrail: the two assertions exercise both the fast-path (direct marker check) and the manifest-driven aggregation, which is exactly how the audit and the merge/auth-store flows consume it. Any future accidental removal of the marker from the Codex manifest — or a regression in the manifest registry loader that drops bundled plugin markers — fails this test.
  • Existing test that already covers this (if any): src/agents/model-auth-markers.test.ts already covers the four peer markers (ollama-local, lmstudio-local, gcp-vertex-credentials, minimax-oauth). This PR extends those same tests with the Codex case.

User-visible / Behavior Changes

  • openclaw secrets audit no longer reports PLAINTEXT_FOUND for Codex's synthetic providers.codex.apiKey value in models.json.
  • No other user-visible changes. No new configuration options. No default changes.

Diagram

N/A — no flow change, only an additional entry in an existing allow-list loaded at plugin-registry init time.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? Nocodex-app-server is a synthetic literal that has always been hardcoded in extensions/codex/provider.ts; this PR just declares it as a known non-secret marker. No tokens are read, stored, or transmitted differently.
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS 26.5 (Apple Silicon, also applies to Linux)
  • Runtime/container: local
  • Model/provider: Codex harness (extensions/codex)
  • Integration/channel: openclaw secrets audit CLI
  • Relevant config: models.json containing providers.codex.apiKey = "codex-app-server" (the default after Codex discovery)

Steps

  1. Configure Codex provider (e.g. install the Codex extension and run a Codex-managed model once so models.json persists the provider).
  2. Run openclaw secrets audit.
  3. Observe finding: code: PLAINTEXT_FOUND, jsonPath: providers.codex.apiKey.

Expected

  • No PLAINTEXT_FOUND entry for the Codex provider, because codex-app-server is a synthetic non-secret marker.

Actual (before this PR)

  • The audit reports the synthetic value as a plaintext leak.

After this PR

  • Audit no longer reports it, matching the existing behavior for ollama-local, lmstudio-local, gcp-vertex-credentials, and minimax-oauth.

Evidence

  • Failing test/log before + passing after
    • The new assertions in src/agents/model-auth-markers.test.ts fail on main (with arrayContaining([…, "codex-app-server", …]) missing) and pass with this PR applied.
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • Inspected src/secrets/audit.ts to confirm the plaintext guard already calls isNonSecretApiKeyMarker.
    • Inspected src/agents/model-auth-markers.ts to confirm listKnownNonSecretApiKeyMarkers() aggregates bundled plugin manifests.
    • Confirmed the Codex plugin manifest is loaded via loadPluginManifestRegistry (checked src/plugins/manifest-registry.ts).
    • Confirmed codex-app-server is used as the synthetic value in extensions/codex/provider.ts (lines 88, 89, 117).
    • Confirmed JSON syntax of the updated manifest (python3 -c "import json; json.load(...)").
    • Confirmed the new assertions are placed next to peer markers so future regressions are obvious.
  • Edge cases checked: the manifest registry cache (cache: true) is loaded at startup; no code path reads nonSecretAuthMarkers outside the registry aggregation, so no additional sites need updating.
  • What I did not verify: did not run the full pnpm test:unit locally (no pnpm install on this machine); CI will run the suite.

Review Conversations

  • I will reply to or resolve every bot review conversation I address in this PR.
  • I will leave unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: a future plugin reuses the string codex-app-server in a non-Codex context and ends up whitelisted.
    • Mitigation: the string is intentionally Codex-branded and lives in the Codex plugin manifest. The registry aggregates from origin === "bundled" plugins only, so third-party plugins cannot injection-whitelist additional markers.

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511
@Sanjays2402 Sanjays2402 requested a review from a team as a code owner April 21, 2026 03:46
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 21, 2026

Greptile Summary

This PR fixes a false-positive PLAINTEXT_FOUND audit finding for the Codex extension's synthetic "codex-app-server" apiKey by adding it to nonSecretAuthMarkers in the Codex plugin manifest — the same mechanism already used by Ollama, LMStudio, Anthropic-Vertex, and Minimax. The marker value matches exactly what extensions/codex/provider.ts hardcodes at lines 88, 89, and 117, and two new unit test assertions in model-auth-markers.test.ts lock in both the direct-check path and the manifest-registry aggregation path.

Confidence Score: 5/5

Safe to merge — purely additive manifest entry and regression test, no logic changes.

The change follows the exact same pattern as four sibling plugins, the marker string is verified to match the hardcoded literal in provider.ts, no audit logic was modified, and both the direct-check and manifest-aggregation code paths are covered by the new test assertions.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(codex): exclude codex-app-server syn..." | Re-trigger Greptile

@Sanjays2402
Copy link
Copy Markdown
Contributor Author

The three red checks look unrelated to the change in this PR:

  • check-additional-runtime-topology-gateway reports dist-runtime file growth 5692 exceeded max 200 and byte growth 48MB exceeded 2MB. This diff is +3 lines across extensions/codex/openclaw.plugin.json and src/agents/model-auth-markers.test.ts — no runtime code or bundling is touched, so that growth shouldn't come from this change. My best guess is a first-time fork baseline issue where the watch/rebuild gate has no cached before build to compare against.
  • check-additional is the rollup of the shard above, so it reports the same failure.
  • GPT-5.4 / Opus 4.6 parity gate exited with only an UNKNOWN STEP and a Node.js 20 deprecation warning — no test step logged a failure, looks like a runner infra hiccup.

Happy to rebase or push a trivial commit to retrigger — just did the latter. Let me know if there's anything I should adjust in the PR itself.

@amknight
Copy link
Copy Markdown
Member

LGTM, merging 👍

@amknight amknight merged commit 081da17 into openclaw:main Apr 21, 2026
89 of 92 checks passed
zhongmairen pushed a commit to agencyos-cn/openclaw-bad that referenced this pull request Apr 21, 2026
* 'main' of https://github.com/openclaw/openclaw:
  fix(agents): enforce subagent envelope inheritance on ACP child sessions [AI-assisted] (openclaw#69383)
  fix(tui): arm streaming watchdog on every delta, not only visible ones (openclaw#69338)
  fix(codex): exclude codex-app-server synthetic apiKey from secrets audit (openclaw#69581)
steipete pushed a commit that referenced this pull request Apr 21, 2026
…dit (#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes #69511

* ci: retrigger checks (no-op)

(cherry picked from commit 081da17)
gdibble pushed a commit to gdibble/openclaw that referenced this pull request Apr 21, 2026
…dit (openclaw#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511

* ci: retrigger checks (no-op)
zhonghe0615 pushed a commit to zhonghe0615/openclaw that referenced this pull request Apr 27, 2026
…dit (openclaw#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511

* ci: retrigger checks (no-op)
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…dit (openclaw#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511

* ci: retrigger checks (no-op)
zhonghe0615 pushed a commit to zhonghe0615/openclaw that referenced this pull request May 7, 2026
…dit (openclaw#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511

* ci: retrigger checks (no-op)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…dit (openclaw#69581)

* fix(codex): exclude codex-app-server synthetic apiKey from secrets audit

The Codex extension uses the literal string "codex-app-server" as a
hardcoded placeholder apiKey in provider.ts, since the real
authentication is managed by the app-server transport itself.

The secrets audit currently reports this as a real plaintext leak
(PLAINTEXT_FOUND), producing a false positive for any user who has
configured the Codex harness.

Declare it as a plugin-owned non-secret marker in the Codex plugin
manifest, so it flows through the standard
`listKnownNonSecretApiKeyMarkers()` path alongside `ollama-local`,
`lmstudio-local`, `gcp-vertex-credentials`, and `minimax-oauth`.

Also extends the existing `model auth markers` unit tests to lock
in the behavior.

Fixes openclaw#69511

* ci: retrigger checks (no-op)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: secrets audit PLAINTEXT_FOUND for synthetic codex-app-server apiKey in models.json

2 participants