feat(client): deregister the machine from the platform on uninstall - #1782
Merged
Conversation
Ported from openframe-oss-tenant PR #2207 (branch hotfix/client-uninstall-deregister) as the client moved to this repo, plus a final retry pass: credentials are loaded up front and held in memory, and if the in-flow deregistration never got through, one last attempt round runs at the end of the uninstall, after the wipe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The GCP load balancer rejects body-less HTTP/1.1 POSTs with 411 Length Required before they reach the backend, so deregistration never succeeded. Send a deletedAt timestamp body; the backend ignores it today but the request now carries Content-Length and goes through. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
danylo-babenko-flamingo
approved these changes
Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Client side of 86ahw2uxm — Remote and local uninstall with agent self-deletion: on uninstall, the client reports itself to the platform so the backend can run its deletion logic (mark the machine deleted, revoke the agent's OAuth client, tool cleanup). Covers every uninstall path — local
openframe-client uninstall, dashboard-triggered (via the client-uninstall listener PR), and the 410 tenant-gone flow — because the callback runs inside the shared uninstall flow.Port of flamingo-stack/openframe-oss-tenant#2207 — the client moved to this repo, so the PR moves with it (the tenant PR is closed as superseded).
New on top of the port — a final retry pass:
DeregistrationServiceconstruction and held in memory, so they survive the wipe.reportedflag tracks whether the platform accepted (2xx) or terminally dismissed (401/403/404/410) the call.retry_if_unreported()runs one more bounded attempt round at the very end of the uninstall — after the wipe, right before the process exits (on Windows: before the binary-cleanup script is launched). A transient outage during the first pass no longer permanently loses the deregistration; the tools-uninstall + directory-wipe duration acts as natural spacing between the two windows.Proposed backend contract (⚠️ needs agreement — @backend)
POST {gateway}/clients/api/agents/uninstallwithX-Machine-Id+X-Client-Secretheaders (mirrors how/reinstallauthenticates the machine). Expected semantics:2xx→ machine deregistered (endpoint must be idempotent: already-deleted →204, never an error)401/403/410→ platform already forgot this machine → client proceeds404→ endpoint not deployed yet → client proceeds (this PR can merge before the backend ships)Behavior
Service::install()invokes the previous binary'suninstallwhen installing over an existing installation; it setsOPENFRAME_REINSTALL=1and the uninstall skips deregistration — upgrades never delete the device. Env var rather than a CLI flag so older binaries (which the installer may invoke) ignore it instead of failing on an unknown argument.agent_config.json, falling back to the persisted machine-info store (registry / plist //etc/openframe) if the config is missing or corrupt.Testing
OPENFRAME_VERSION=0.1.0 cargo checkclean on host andx86_64-pc-windows-gnu.OPENFRAME_VERSION=0.1.0 cargo test -- --skip test_ensure_admin: 131 passed, 0 failed (includes the terminal-vs-transient status classification tests).🤖 Generated with Claude Code