Skip to content

fix(connection): startup connects with a weaker token when the legacy device key is still present - #1512

Open
SebTardif wants to merge 1 commit into
openclaw:mainfrom
SebTardif:fix/f080-prefer-legacy-device-token
Open

SebTardif wants to merge 1 commit into
openclaw:mainfrom
SebTardif:fix/f080-prefer-legacy-device-token

Conversation

@SebTardif

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes: the next launch connects with a shared or bootstrap token when the per-gateway identity file is missing and the legacy device key for that same gateway URL is still on disk.

User Impact

User impact: a paired gateway keeps its device token across that startup instead of dropping back to the weaker token.

Why This Change Was Made

Startup now copies the legacy identity into the per-gateway directory and resolves it again before it accepts a shared or bootstrap token. If that copy fails, a device token read from the legacy directory is still used. A credential that is already a device token is left alone.

Evidence

Terminal output from the patched tree at 1327a863, calling LegacyStartupDeviceToken.Prefer through the connection test host. The legacy file is a real device-key-ed25519.json written by DeviceIdentity.StoreDeviceTokenForRole.

Passed!  - Failed: 0, Passed: 5, Skipped: 0, Total: 5
Prefer_CopiesLegacyIdentity_AndUsesDeviceTokenInsteadOfShared
  copied: true
  operator source: identity.DeviceToken
  operator token: paired-tok
  node source: identity.NodeDeviceToken
Prefer_CopyFailure_StillUsesLegacyDeviceTokenOverShared
  copied: false
  source: identity.DeviceToken

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs or instructions
  • Tests or validation
  • Security hardening
  • Chore or infrastructure

Scope

  • Tray or WinUI UX
  • Windows node capability
  • Local MCP or winnode
  • Gateway, connection, or pairing
  • Setup or onboarding
  • Permissions, privacy, or security
  • Tests, CI, or docs

Required proof pools

  • none: no installer, WSL gateway, or WinUI window is required. The choice is a file copy plus credential resolution.

Validation

  • dotnet test ./tests/OpenClaw.Connection.Tests/OpenClaw.Connection.Tests.csproj --filter LegacyStartupDeviceTokenTests on 1327a863: Passed 5, Failed 0.
  • dotnet build src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj -p:Platform=x64 succeeded. One existing Win2D warning. ./build.ps1 was not run.

Real Behavior Proof

  • Behavior or issue addressed: Startup used the shared token when the per-gateway identity file was missing, even though the legacy device key for that URL was still present.
  • Real environment tested: Windows, this worktree, commit 1327a863.
  • Exact steps or command run after this patch: dotnet test ./tests/OpenClaw.Connection.Tests/OpenClaw.Connection.Tests.csproj --filter LegacyStartupDeviceTokenTests
  • Evidence after fix: The copy path stored paired-tok as identity.DeviceToken and node-tok as identity.NodeDeviceToken. The blocked-directory path still returned identity.DeviceToken and did not create the per-gateway file.
  • Observed result after fix: The weaker shared token was not selected when the legacy device key matched the gateway URL.
  • Screenshot or artifact links verified? No
  • Not verified or blocked: The tray process was not launched, so the startup log line was not captured from a running app.
  • What was not tested: A full tray launch against a live gateway.

Security Impact

  • New permissions or capabilities? No
  • Secrets or tokens handling changed? Yes
  • New or changed network calls? No
  • Command or tool execution surface changed? No
  • Data access scope changed? No
  • If any answer is Yes, explain the risk and mitigation: The device token is preferred and copied into the existing per-gateway identity directory. The legacy file is not deleted. Tokens are not logged.

Compatibility and Migration

  • Backward compatible? Yes
  • Config or environment changes? No
  • Migration needed? No

Review Conversations

  • I replied to or resolved every bot review conversation addressed by this PR.
  • I left unresolved only conversations that still need maintainer judgment.

…oken

When the per-gateway identity file is missing, startup used the shared
or bootstrap token and never copied the legacy device key for that URL.
Copy the legacy identity and resolve it again before accepting the weaker token.

- Add LegacyStartupDeviceToken.Prefer for operator and node startup
- If the copy fails, still use a device token read from the legacy directory
- Do not copy or replace a credential that is already a device token

Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
@clawsweeper

clawsweeper Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 24, 2026
@clawsweeper

clawsweeper Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed September 24, 2026, 2:17 PM ET / 18:17 UTC.

ClawSweeper review

What this changes

The branch adds a startup credential helper that copies a legacy device identity into the active gateway directory and prefers its device token over a shared or bootstrap token.

Merge readiness

⛔ Blocked before merge - 10 items remain

The startup downgrade is still present on current main, so this PR addresses a real gap. The patch needs repair before merge: its copy-failure fallback does not reach the connection manager, and copying a corrupt legacy identity can block a previously usable shared-token connection.

Priority: P1
Reviewed head: 1327a863088ffe64ebf9424f916d2e363dd56454

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) Focused tests support the helper, but two startup-path defects and missing final-connection proof leave the patch below merge readiness.
Proof confidence 🦪 silver shellfish (2/6) Needs real behavior proof before merge: Authority-chain proof required: the PR's Windows test host exercises the new helper with real identity files, but the tray-to-Gateway connection manager is not exercised; its final credential choice after copy failure remains unobserved. A redacted running-app trace should show the successful-copy, failed-copy, and corrupt-file upgrade outcomes before final Gateway I/O; redact tokens, private paths, and endpoints. The new persistent-copy behavior also lacks verified running-app upgrade compatibility. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦪 silver shellfish (2/6) Security review found an item that needs attention.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: Authority-chain proof required: the PR's Windows test host exercises the new helper with real identity files, but the tray-to-Gateway connection manager is not exercised; its final credential choice after copy failure remains unobserved. A redacted running-app trace should show the successful-copy, failed-copy, and corrupt-file upgrade outcomes before final Gateway I/O; redact tokens, private paths, and endpoints. The new persistent-copy behavior also lacks verified running-app upgrade compatibility. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 8 items Introduced fallback: On copy failure, the new helper returns a credential resolved from the legacy directory.
Final credential owner: After the tray's preflight choice, ConnectAsync resolves the operator credential again from the per-gateway identity directory; it does not receive the selected legacy credential.
Introduced persistent copy: The helper copies an existing legacy file before resolving or validating its credential.
Findings 2 actionable findings [P1] Carry the legacy device credential into the final connection
[P1] Validate the legacy identity before copying it into active state
Security Needs attention Credential choice is not bound to final authentication: A failed copy can produce a legacy device-token choice in the tray while the connection manager independently selects a shared or bootstrap credential for the final connection.

How this fits together

The tray reads the active gateway record and stored identity before starting a connection. The connection manager resolves credentials again from the per-gateway directory before contacting the Gateway.

flowchart LR
A[Active gateway record] --> B[Startup credential check]
C[Legacy identity file] --> B
B --> D[Per-gateway identity file]
D --> E[Connection manager resolves credential]
E --> F[Gateway connection]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: Authority-chain proof required: the PR's Windows test host exercises the new helper with real identity files, but the tray-to-Gateway connection manager is not exercised; its final credential choice after copy failure remains unobserved. A redacted running-app trace should show the successful-copy, failed-copy, and corrupt-file upgrade outcomes before final Gateway I/O; redact tokens, private paths, and endpoints. The new persistent-copy behavior also lacks verified running-app upgrade compatibility. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Carry the legacy device credential into the final connection (P1) - When the copy fails, this returns a device token from the legacy directory, but TryConnectGatewayIfCredentialAvailable calls ConnectAsync(record.Id), whose manager resolves again only from the per-gateway directory. With a shared token present, the final connection can still use that token, so the new failed-copy path does not deliver its claimed protection.
  • Validate the legacy identity before copying it into active state (P1) - This copies any existing legacy file before checking whether it can be read. If that file is corrupt while the active gateway has a valid shared token, the prior startup accepted the shared token; after this copy, credential resolution reports a corrupt persisted identity and startup blocks the connection. Keep the working setup available without persisting an invalid identity.
  • Resolve security concern: Credential choice is not bound to final authentication - A failed copy can produce a legacy device-token choice in the tray while the connection manager independently selects a shared or bootstrap credential for the final connection.
  • Resolve merge risk (P1) - The changed credential path lacks final-connection proof that a failed identity copy cannot send a shared or bootstrap token when a valid legacy device token exists.
  • Resolve merge risk (P1) - Upgrade behavior for existing legacy identity files is unproven in a running tray, including corrupt files and preservation of an already usable shared-token setup.
  • Complete next step (P2) - Repair both startup-path findings, run required Windows validation, and add redacted current-head tray-to-Gateway proof for normal copy, copy failure, and corrupt-file upgrade. Updating the PR body should trigger re-review; otherwise ask a maintainer to comment @clawsweeper re-review.
  • Improve patch quality - Repair the final credential handoff and the corrupt-file copy path with focused regression coverage.
  • Improve patch quality - Provide redacted current-head tray-to-Gateway observations for successful copy, failed copy, and an existing corrupt legacy file.
  • Improve patch quality - Report the repository-required build and shared/tray tests plus the applicable connection validation results.

Findings

  • [P1] Carry the legacy device credential into the final connection — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:53-55
  • [P1] Validate the legacy identity before copying it into active state — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:43-47
  • [medium] Credential choice is not bound to final authentication — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:53
Agent review details

Security

Needs attention: The changed token choice is security sensitive because the claimed device-token fallback can be lost before the final Gateway authentication.

Review metrics

Metric Value Why it matters
Changed lines production +117/-52, tests +180/-2 The new helper and test coverage are focused, but the persistent credential behavior needs end-to-end validation.

Merge-risk options

Maintainer options:

  1. Repair credential handoff and copy validation (recommended)
    Make the final connection use the intended device credential or fail before sending a weaker one, and prevent a corrupt legacy file from changing a working shared-token setup.
  2. Pause the branch
    Hold the PR if final-connection and upgrade behavior cannot be demonstrated safely on this branch.

Technical review

Best possible solution:

Keep credential selection and final connection resolution consistent, validate a legacy identity before persisting it, and show the upgrade and failed-copy outcomes through the running tray-to-Gateway path.

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

Yes, from source: with an active matching gateway, a missing per-gateway identity, a legacy device token, and a failed copy, startup selects the legacy token but the manager resolves from the empty per-gateway directory. A corrupt legacy file plus a usable shared token exposes the separate upgrade failure.

Is this the best way to solve the issue?

No. The helper corrects the successful-copy case, but its selected fallback is discarded before final connection and it copies identity bytes before validating them.

Full review comments:

  • [P1] Carry the legacy device credential into the final connection — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:53-55
    When the copy fails, this returns a device token from the legacy directory, but TryConnectGatewayIfCredentialAvailable calls ConnectAsync(record.Id), whose manager resolves again only from the per-gateway directory. With a shared token present, the final connection can still use that token, so the new failed-copy path does not deliver its claimed protection.
    Confidence: 0.98
  • [P1] Validate the legacy identity before copying it into active state — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:43-47
    This copies any existing legacy file before checking whether it can be read. If that file is corrupt while the active gateway has a valid shared token, the prior startup accepted the shared token; after this copy, credential resolution reports a corrupt persisted identity and startup blocks the connection. Keep the working setup available without persisting an invalid identity.
    Confidence: 0.96

Overall correctness: patch is incorrect
Overall confidence: 0.96

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 273b0182745a.

Labels

Label changes:

  • add P1: The patch changes startup authentication and can either retain a token downgrade or stop an existing connection.
  • add merge-risk: 🚨 compatibility: Copying an invalid legacy file can turn a previously usable shared-token startup into a persistent identity-load failure.
  • add merge-risk: 🚨 auth-provider: The tray's chosen device credential is not passed to the manager that performs final Gateway authentication.
  • add merge-risk: 🚨 availability: A newly copied corrupt identity can prevent startup connection and later reconnects.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦪 silver shellfish.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Authority-chain proof required: the PR's Windows test host exercises the new helper with real identity files, but the tray-to-Gateway connection manager is not exercised; its final credential choice after copy failure remains unobserved. A redacted running-app trace should show the successful-copy, failed-copy, and corrupt-file upgrade outcomes before final Gateway I/O; redact tokens, private paths, and endpoints. The new persistent-copy behavior also lacks verified running-app upgrade compatibility. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P1: The patch changes startup authentication and can either retain a token downgrade or stop an existing connection.
  • merge-risk: 🚨 compatibility: Copying an invalid legacy file can turn a previously usable shared-token startup into a persistent identity-load failure.
  • merge-risk: 🚨 auth-provider: The tray's chosen device credential is not passed to the manager that performs final Gateway authentication.
  • merge-risk: 🚨 availability: A newly copied corrupt identity can prevent startup connection and later reconnects.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Authority-chain proof required: the PR's Windows test host exercises the new helper with real identity files, but the tray-to-Gateway connection manager is not exercised; its final credential choice after copy failure remains unobserved. A redacted running-app trace should show the successful-copy, failed-copy, and corrupt-file upgrade outcomes before final Gateway I/O; redact tokens, private paths, and endpoints. The new persistent-copy behavior also lacks verified running-app upgrade compatibility. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

Security concerns:

  • [medium] Credential choice is not bound to final authentication — src/OpenClaw.Connection/LegacyStartupDeviceToken.cs:53
    A failed copy can produce a legacy device-token choice in the tray while the connection manager independently selects a shared or bootstrap credential for the final connection.
    Confidence: 0.98

What I checked:

Likely related people:

  • Barbara Kudiess: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Scott Hanselman: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@karkarl

karkarl commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Global triage: HOLD_FOR_AUTHOR. Take confidence 5%; recommendation confidence 99%; effort medium; risk high.

Two credential-precedence failures block this exact head:

  1. On copy failure, LegacyStartupDeviceToken selects the legacy device credential and identity path, but App discards both and connects by record ID. The manager can then resolve from the empty per-gateway directory and fall back to a weaker shared or bootstrap token.
  2. The legacy identity is copied before parsing or cryptographic validation. A corrupt legacy file can become active per-gateway state and permanently break startup that previously worked with a valid shared token.

Please make the final connection owner choose credential plus matching identity directory atomically, validate legacy identity before persistence, and cover operator, node-only, copy-failure, and corrupt-file paths end to end.

Required pools are windows-wsl-gateway-e2e and windows-clean-installer-upgrade, not none. Exact-head CI passed ordinary hosted suites, but the three red E2E shards also fail on the exact base before the changed behavior; CI Gate is derivative and real migration proof remains missing.

This branch has not been deployed

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

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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.

2 participants