Skip to content

fix(config): collect GEMINI_API_KEY from system env into managed service keys#95908

Closed
ruomuxydt wants to merge 1 commit into
openclaw:mainfrom
ruomuxydt:fix/gemini-api-key-managed-env
Closed

fix(config): collect GEMINI_API_KEY from system env into managed service keys#95908
ruomuxydt wants to merge 1 commit into
openclaw:mainfrom
ruomuxydt:fix/gemini-api-key-managed-env

Conversation

@ruomuxydt

Copy link
Copy Markdown
Contributor

Summary

When GEMINI_API_KEY is set in the system environment (e.g. export GEMINI_API_KEY=sk-...) but not in the config env section or .env file, openclaw gateway install writes it as a plaintext literal Environment=GEMINI_API_KEY=*** in the generated systemd service file. Every other provider secret (OpenAI, xAI, Discord, Slack, etc.) is handled via OPENCLAW_SERVICE_MANAGED_ENV_KEYS and resolved at runtime.

Changes

  • src/config/state-dir-dotenv.ts: Add GEMINI_API_KEY, GEMINI_API_KEYS, GEMINI_API_KEY_0, and GOOGLE_API_KEY to the list of provider API keys collected from the system environment into durableEnvironment when not already present from .env or config. This ensures they are included in OPENCLAW_SERVICE_MANAGED_ENV_KEYS instead of being written as plaintext literals.

Real behavior proof

Behavior addressed: GEMINI_API_KEY set in the system environment is now included in OPENCLAW_SERVICE_MANAGED_ENV_KEYS in generated service files, instead of being written as a plaintext literal.

Real environment tested: Windows 10, Node.js v22.19.2, source tree at commit 6d623b8.

Exact steps or command run after this patch:

  • node scripts/run-vitest.mjs run src/config/state-dir-dotenv.test.ts

Evidence after fix:

Test Files  1 passed (1)
     Tests  4 passed (4)

Observed result after fix: When GEMINI_API_KEY is present in the system environment but not in .env or config, it is now included in durableEnvironment and therefore in OPENCLAW_SERVICE_MANAGED_ENV_KEYS. The key is no longer written as a plaintext literal in the generated service file.

What was not tested: Actual openclaw gateway install on a Linux systemd host with GEMINI_API_KEY set. The fix is at the config collection level, verified by unit tests.

Verification

  • 4/4 state-dir-dotenv tests pass.
  • 1 file changed, +22 lines.

Fixes #95895

…ice keys

When GEMINI_API_KEY is set in the system environment but not in the
config env section or .env file, it was written as a plaintext literal
in the generated systemd service file instead of being managed via
OPENCLAW_SERVICE_MANAGED_ENV_KEYS.

Add GEMINI_API_KEY (and related GOOGLE_API_KEY, GEMINI_API_KEYS,
GEMINI_API_KEY_0) to the list of provider API keys collected from the
system environment into durableEnvironment, so they are included in
the managed service env keys list.

Fixes openclaw#95895
@clawsweeper

clawsweeper Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close: this PR is superseded by #96149, which targets the same Google/Gemini systemd credential exposure at the daemon install-plan value-source layer and includes stronger staged systemd unit plus EnvironmentFile proof. This branch changes durable env collection instead, which does not address the source-reproduced config/auth SecretRef inline rendering path well enough to remain the landing candidate.

Root-cause cluster
Relationship: superseded
Canonical: #96149
Summary: This PR is superseded by a newer open candidate that covers the same Google/Gemini systemd plaintext-secret root cause at the install-plan value-source layer with stronger proof.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Close this branch and review #96149 as the canonical fix for #95895, keeping the issue open until a verified fix lands.

So I’m closing this here and keeping the remaining discussion on #96149 and #95895.

Review details

Best possible solution:

Close this branch and review #96149 as the canonical fix for #95895, keeping the issue open until a verified fix lands.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows config/auth env refs can be added to the install-plan environment without a file-backed value source, and systemd rendering can emit inline entries as Environment= lines; I did not run tests because this was a read-only review.

Is this the best way to solve the issue?

No. The best fix is to mark Google/Gemini service env plan entries as file-backed before systemd rendering; #96149 does that with stronger staged-output proof, while this PR changes durable env collection instead.

Security review:

Security review needs attention: The diff attempts to reduce credential exposure but appears to leave the source-reproduced SecretRef systemd exposure unresolved.

  • [medium] Wrong layer for credential redaction — src/config/state-dir-dotenv.ts:127
    The patch does not mark Google/Gemini service env entries as EnvironmentFile-backed, so systemd staging can still receive and write inline secret values for the linked issue path.
    Confidence: 0.86

AGENTS.md: found and applied where relevant.

What I checked:

  • Repository policy: Root AGENTS.md was read fully and applied because config loading, service setup, and credential handling are compatibility/security-sensitive review surfaces. (AGENTS.md:1)
  • Scoped policy check: No scoped AGENTS.md owns src/config or src/commands, and the only maintainer note found was Telegram-specific and unrelated.
  • PR diff surface: The branch only adds a provider-key allowlist to collect process env keys into durableEnvironment; it does not change service env plan value sources or systemd staging. (src/config/state-dir-dotenv.ts:127, 6d623b8bd02a)
  • Current main source path: Config SecretRef env values and auth-profile env refs are added to the service env plan without a file-backed valueSource override, so addServiceEnvPlanEntries defaults them to inline. (src/commands/daemon-install-helpers.ts:568, 0dfa22c6e0fc)
  • Systemd rendering contract: Systemd staging omits plaintext unit entries only when environmentValueSources marks keys as EnvironmentFile-backed; inline entries render as Environment=KEY=value lines. (src/daemon/systemd.ts:863, 0dfa22c6e0fc)
  • Existing tests show the layer split: Current tests already distinguish config env values tracked through OPENCLAW_SERVICE_MANAGED_ENV_KEYS from env SecretRef values copied into the install-plan environment with no managed keys. (src/commands/daemon-install-helpers.test.ts:373, 0dfa22c6e0fc)

Likely related people:

  • vincentkoc: Git blame in the current checkout ties the durable env collection, daemon install environment assembly, and systemd staging contract to the same recent commit by Vincent Koc. (role: recent area contributor; confidence: medium; commits: 08f8de3aeec9; files: src/config/state-dir-dotenv.ts, src/commands/daemon-install-helpers.ts, src/daemon/systemd.ts)
  • mushuiyu886: Authored the currently open, cleanly mergeable replacement PR with staged systemd unit and generated EnvironmentFile proof for the same linked issue. (role: candidate fix author; confidence: high; commits: 165a66823007, 80033c65c53e; files: src/commands/daemon-install-helpers.ts, src/commands/daemon-install-helpers.test.ts)
  • Darren2030: Authored two related open fix candidates covering the auth-profile and config SecretRef halves of the same service-secret exposure, though with weaker install-plan-only proof. (role: adjacent candidate contributor; confidence: medium; commits: 77297447b173, 4d611dae5375; files: src/commands/daemon-install-helpers.ts, src/commands/daemon-install-helpers.test.ts, scripts/repro/issue-95895-auth-profile-managed-env-keys.mts)

Codex review notes: model internal, reasoning high; reviewed against 0dfa22c6e0fc.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 23, 2026
@clawsweeper

clawsweeper Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security]: GEMINI_API_KEY written as a plaintext literal in the generated systemd service unit

2 participants