Skip to content

Fix gateway daemon token drift after token rotation#28428

Closed
l0cka wants to merge 5 commits intoopenclaw:mainfrom
l0cka:fix/gateway-service-token-drift-17223
Closed

Fix gateway daemon token drift after token rotation#28428
l0cka wants to merge 5 commits intoopenclaw:mainfrom
l0cka:fix/gateway-service-token-drift-17223

Conversation

@l0cka
Copy link
Copy Markdown
Contributor

@l0cka l0cka commented Feb 27, 2026

Summary

  • stop embedding OPENCLAW_GATEWAY_TOKEN in generated daemon service environments and migrate legacy embedded-token units via audit/doctor repair
  • persist token-auth gateway token to config during daemon install/repair and reinstall from config-derived service env
  • make gateway-service local token resolution config-first under OPENCLAW_SERVICE_KIND=gateway
  • fix local restart drift checks to compare service token against gateway.auth.token (not env-injected token)
  • fix local tui and status probe auth precedence to prefer gateway.auth.token over stale shell/.env token overrides, preventing unauthorized token mismatch after token rotation
  • add/adjust tests and changelog for [Bug]: OPENCLAW_GATEWAY_TOKEN in systemd service file not updated on config change or update, causing device_token_mismatch #17223

Testing

  • pnpm -s vitest run src/daemon/service-env.test.ts src/daemon/service-audit.test.ts src/gateway/credentials.test.ts src/gateway/credential-precedence.parity.test.ts src/commands/doctor-gateway-services.test.ts src/commands/daemon-install-helpers.test.ts src/cli/daemon-cli/lifecycle-core.test.ts src/tui/gateway-chat.test.ts src/cli/daemon-cli/status.gather.test.ts
  • pnpm build
  • pnpm check

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime cli CLI command changes commands Command implementations size: M labels Feb 27, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Feb 27, 2026

Greptile Summary

This PR fixes gateway daemon token drift after token rotation by implementing a config-first token management strategy.

Key Changes

  • Removed OPENCLAW_GATEWAY_TOKEN from daemon service environments - tokens are no longer embedded in systemd/launchd service definitions
  • Gateway services now read tokens from gateway.auth.token config instead of embedded environment variables
  • Local credential resolution automatically uses config-first precedence when OPENCLAW_SERVICE_KIND=gateway
  • Install flow persists tokens to config during initial setup and when explicitly provided
  • Doctor repair flow migrates legacy embedded tokens to config before reinstalling services
  • Service audits now flag any embedded tokens as needing reinstallation
  • Token drift checks compare service tokens against config tokens (not environment-derived tokens)
  • TUI and status probes prefer config tokens over stale shell/env overrides

Implementation Quality

The implementation is comprehensive and well-tested with 23 files changed. All critical paths have test coverage including credential precedence parity tests, service audit tests, install flow tests, and doctor repair tests. The migration path for legacy systems is sound - when doctor repair detects an embedded token and config token is missing, it persists the environment token to config before reinstalling.

Impact

This eliminates a critical failure mode where gateway services would fail authentication after token rotation because they were using stale embedded tokens. Users can now rotate tokens via config without needing to reinstall daemon services.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is comprehensive, well-tested, and addresses a critical authentication failure mode. All changes are internally consistent - token parameter removal propagates correctly through all code paths, credential precedence logic is uniform, and test coverage validates both new behavior and migration paths. The PR includes proper backwards compatibility through doctor repair flow that migrates legacy embedded tokens to config before reinstallation. No security vulnerabilities introduced - the change actually improves security by centralizing token management in config rather than embedding in multiple service definitions.
  • No files require special attention

Last reviewed commit: 211d145

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: 211d145223

ℹ️ 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".

Comment thread src/commands/doctor-gateway-services.ts Outdated
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: f0491cb569

ℹ️ 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".

Comment thread src/cli/daemon-cli/install.ts Outdated
Comment thread src/commands/doctor-gateway-services.ts Outdated
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: 86665858ed

ℹ️ 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".

Comment thread src/commands/configure.daemon.ts Outdated
Comment thread src/commands/doctor-gateway-daemon-flow.ts Outdated
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: 01e5b948aa

ℹ️ 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".

};
try {
await writeConfigFile(nextCfg);
cfgForServiceInstall = nextCfg;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Propagate persisted token config back to doctor state

After persisting nextCfg, this branch only assigns it to cfgForServiceInstall, so the caller’s cfg remains stale. In doctorCommand, a later writeConfigFile(cfg) (triggered when any other doctor fix is pending) can rewrite openclaw.json without the just-persisted token, undoing the repair. For legacy embedded-token services, that can leave a tokenless unit plus missing gateway.auth.token, causing token-mode restart/auth failures.

Useful? React with 👍 / 👎.

},
};
try {
await writeConfigFile(nextCfg);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Block token persistence when doctor config is invalid

This repair path writes nextCfg directly without validating the current config snapshot first. Doctor explicitly runs in best-effort mode on invalid/parsing-failed configs, so cfg can be incomplete; accepting this repair can overwrite the user’s config with a minimal token-only structure and drop unrelated settings. Align this path with the install/configure flows by checking snapshot validity (or merging from snapshot.config) before writing.

Useful? React with 👍 / 👎.

@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 5, 2026
steipete added a commit that referenced this pull request Mar 7, 2026
Landed from contributor PR #28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
@steipete
Copy link
Copy Markdown
Contributor

steipete commented Mar 7, 2026

Landed on main after rebasing onto the current branch tip.

What changed while landing:

  • kept the tokenless gateway service-unit model from this PR
  • removed the remaining daemon install/configure/doctor/onboarding call sites that still tried to pass a plaintext token: into buildGatewayInstallPlan(...)
  • fixed the doctor repair path so env-backed tokens can be persisted before reinstall, while SecretRef-backed configs stay non-persisted
  • aligned daemon CLI + TUI drift checks with config-first local token precedence for gateway services
  • updated the install/doctor/service-audit/onboarding coverage to the tokenless-service expectation
  • ran pnpm lint, pnpm build, and pnpm test

Commits:

Thanks @l0cka.

@steipete steipete closed this Mar 7, 2026
vincentkoc pushed a commit to BryanTegomoh/openclaw-upstream that referenced this pull request Mar 8, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
ziomancer pushed a commit to ziomancer/openclaw that referenced this pull request Mar 8, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
openperf pushed a commit to openperf/moltbot that referenced this pull request Mar 8, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
mcaxtr pushed a commit to mcaxtr/openclaw that referenced this pull request Mar 8, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
GordonSH-oss pushed a commit to GordonSH-oss/openclaw that referenced this pull request Mar 9, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
(cherry picked from commit 265367d)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
(cherry picked from commit 265367d)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
(cherry picked from commit 265367d)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
(cherry picked from commit 265367d)
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Landed from contributor PR openclaw#28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes commands Command implementations gateway Gateway runtime size: XL stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants