Fix atomic device-key token clearing - #889
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 29, 2026, 4:31 PM ET / 20:31 UTC. Summary Reproducibility: yes. for the source-level path: current main rewrites the identity file non-atomically, and invalid/torn JSON causes LoadExisting() to generate a new keypair. I did not run a live crash or power-loss harness in this read-only review. Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this narrow atomic-writer fix after maintainer security/storage review, then let the linked canonical issue close when the PR merges. Do we have a high-confidence way to reproduce the issue? Yes for the source-level path: current main rewrites the identity file non-atomically, and invalid/torn JSON causes LoadExisting() to generate a new keypair. I did not run a live crash or power-loss harness in this read-only review. Is this the best way to solve the issue? Yes: the PR uses the existing atomic device-key write pattern and keeps the cleanup path best-effort. The remaining decision is maintainer acceptance of the sensitive storage contract, not a narrower code fix. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 87dc3dc79d7c. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
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. How this review workflow works
|
ClearStoredTokens in DeviceIdentityStore used File.WriteAllBytes to rewrite device-key-ed25519.json. A crash/power-loss mid-write could leave a torn file, causing LoadExisting to silently regenerate a new keypair and rotate the device identity. Fix: Add DeviceIdentity.TryClearAllDeviceTokens that strips all token fields using raw JSON filtering and writes atomically via temp-file + File.Move (same pattern as AtomicWriteKeyFile). ClearStoredTokens now delegates to it. Also add AtomicWriteKeyFileRaw for the ConnectionPage rollback-restore path that previously used File.WriteAllText directly. Fixes openclaw#888 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Guard TryClearAllDeviceTokens before enumerating JSON object properties so valid-but-non-object JSON remains a best-effort no-op instead of throwing through ClearStoredTokens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep DeviceIdentityStore.ClearStoredTokens as a best-effort operation by logging unexpected failures from the shared atomic token-clear helper instead of allowing them to escape connection cleanup flows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cc46e12 to
e6171f2
Compare
Adding screenshot proof from the manual smoke test. The smoke test used an isolated
So the stored device token was cleared while the device identity and Ed25519 keypair were preserved. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |

Summary
DeviceIdentityStore.ClearStoredTokensthrough a shared atomic token-clear helper instead of rewritingdevice-key-ed25519.jsonwithFile.WriteAllBytesDeviceToken,DeviceTokenScopes,NodeDeviceToken, andNodeDeviceTokenScopesConnectionPagerollback-restore pathFixes #888
Validation
./build.ps1dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restoredotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restoreOpenClaw.Connection.TestsDeviceIdentityStoretestsManual smoke
OPENCLAW_TRAY_DATA_DIRDeviceId,PublicKeyBase64, andPrivateKeyBase64stayed unchanged while token fields were clearedReal behavior proof
Manual smoke run against this branch using an isolated
OPENCLAW_TRAY_DATA_DIR.Proof screenshot shows:
deviceIdSame=TruepublicKeySame=TrueprivateKeySame=TruebeforeHadDeviceToken=TrueafterHasDeviceToken=FalseThis verifies token clearing removed the stored device token while preserving the device identity/keypair.