Skip to content

fix: strip skill-injected env vars from ACP harness spawn env (#36280)#36316

Merged
vincentkoc merged 5 commits intoopenclaw:mainfrom
taw0002:fix/skill-apikey-leak-to-acp
Mar 6, 2026
Merged

fix: strip skill-injected env vars from ACP harness spawn env (#36280)#36316
vincentkoc merged 5 commits intoopenclaw:mainfrom
taw0002:fix/skill-apikey-leak-to-acp

Conversation

@taw0002
Copy link
Copy Markdown
Contributor

@taw0002 taw0002 commented Mar 5, 2026

Summary

Fixes #36280 — Skill apiKey entries leak as provider env vars (e.g., OPENAI_API_KEY) to ACP harness child processes, causing Codex CLI to silently use API billing instead of OAuth.

Root Cause

applySkillConfigEnvOverrides() sets skill API keys on process.env (e.g., OPENAI_API_KEY from openai-image-gen's primaryEnv) at the start of an agent run and only reverts them in the finally block after the run completes. During the run, resolveAcpClientSpawnEnv() spreads process.env into the child process env, so ACP harnesses like Codex CLI inherit the leaked keys.

Fix

  1. Track injected keys: Added a module-level activeSkillEnvKeys Set in env-overrides.ts that tracks which env vars are currently injected by skill overrides. The set is populated when keys are applied and cleared when the reverter runs.

  2. Strip on ACP spawn: Extended resolveAcpClientSpawnEnv() to accept an optional stripKeys set. The call site in createAcpClient() passes the active skill env keys so they're stripped from the child process environment.

  3. No config changes needed: The fix is automatic — no user configuration required.

Changed Files

  • src/agents/skills/env-overrides.ts — Added activeSkillEnvKeys tracking + getActiveSkillEnvKeys() export
  • src/acp/client.ts — Extended resolveAcpClientSpawnEnv() with stripKeys option; call site passes skill env keys
  • src/acp/client.test.ts — 2 new tests for stripKeys behavior
  • src/agents/skills/env-overrides.test.ts — New test file for getActiveSkillEnvKeys()

Testing

All existing tests pass. New tests verify:

  • Skill-injected keys are stripped from spawn env
  • Non-skill keys are preserved
  • Original baseEnv is not mutated

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: S labels Mar 5, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a60ac95d1d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 5, 2026

Greptile Summary

This PR fixes a credential-leak bug where skill-injected env vars (e.g., OPENAI_API_KEY set by applySkillConfigEnvOverrides) were leaking into ACP harness child processes. The fix is solid: a module-level Set tracks injected keys, and the spawn helper strips them before forking.

Key points:

  • The core logic is correct and safe — getActiveSkillEnvKeys() is called synchronously just before use, with no async gaps
  • The resolveAcpClientSpawnEnv function creates a new env object before deleting keys, so there's no mutation of the input
  • Test coverage includes new tests for stripKeys behavior and validation that the original baseEnv is not mutated
  • Minor linting issue: unused afterEach import should be removed

Confidence Score: 5/5

  • Safe to merge — the fix correctly prevents API key leakage to child processes with no breaking changes to existing functionality.
  • The fix is targeted, well-tested, and solves a real security issue. The core logic is sound: a Set tracks which keys are currently injected, and they're stripped before spawning child processes. The implementation correctly copies the env object before stripping keys, eliminating mutation risks. All tests pass, and new tests validate both the positive case (keys stripped) and negative cases (original env not mutated, non-target keys preserved). The only minor issue (unused import) is cosmetic and doesn't affect functionality.
  • No files require special attention. The unused afterEach import in env-overrides.test.ts should be removed as part of routine cleanup.

Last reviewed commit: a60ac95

@vincentkoc vincentkoc self-assigned this Mar 6, 2026
taw0002 and others added 4 commits March 6, 2026 15:15
Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280
@vincentkoc vincentkoc force-pushed the fix/skill-apikey-leak-to-acp branch from a60ac95 to 2894f9d Compare March 6, 2026 20:17
@vincentkoc
Copy link
Copy Markdown
Member

Rebased this branch onto current main and pushed the cleaned head back to the contributor branch.

The active diff is now just the ACP env-leak fix, targeted lifecycle coverage for skill-injected env keys, and the changelog entry with attribution. I also fixed the stale check failure in src/acp/client.ts by typing the temporary spawn env explicitly so the key stripping path passes TypeScript on current main.

Local verification on the rebased branch:

  • pnpm test -- src/acp/client.test.ts src/agents/skills.test.ts (45 passed)
  • pnpm tsgo still hits unrelated pre-existing Feishu type errors on current main, not this PR’s files

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2894f9da73

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@vincentkoc vincentkoc merged commit ae96a81 into openclaw:main Mar 6, 2026
28 of 29 checks passed
vincentkoc added a commit to BryanTegomoh/openclaw-fork that referenced this pull request Mar 8, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
Saitop pushed a commit to NomiciAI/openclaw that referenced this pull request Mar 8, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
…aw#36280) (openclaw#36316)

* fix: strip skill-injected env vars from ACP harness spawn env

Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY)
are set on process.env during agent runs and only reverted after the run
completes. ACP harnesses like Codex CLI inherit these vars, causing them
to silently use API billing instead of their own auth (e.g., OAuth).

The fix tracks which env vars are actively injected by skill overrides in
a module-level Set (activeSkillEnvKeys) and strips them in
resolveAcpClientSpawnEnv() before spawning ACP child processes.

Fixes openclaw#36280

* ACP: type spawn env for stripped keys

* Skills: cover active env key lifecycle

* Changelog: note ACP skill env isolation

* ACP: preserve shell marker after env stripping

---------

Co-authored-by: Vincent Koc <[email protected]>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
alexey-pelykh added a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Skill apiKey entries leak as OPENAI_API_KEY env var to ACP harness child processes (Codex CLI uses API billing instead of OAuth)

2 participants