feat(canopy): add unregister command and stop resurrecting device keys#653
Open
passcod wants to merge 2 commits into
Open
feat(canopy): add unregister command and stop resurrecting device keys#653passcod wants to merge 2 commits into
passcod wants to merge 2 commits into
Conversation
canopy register now refuses when a registration already exists, telling the operator to run canopy unregister first, and always mints a fresh device key rather than reusing a leftover one — so a re-enrolment presents only the new identity and can't conflict with the server record it's claiming. canopy unregister erases every trace of an enrolment: the encrypted registration, the legacy Tamanu device-key.pem/server-id files, the cached tags, and (when postgres is reachable) the legacy deviceKey/metaServerId rows in local_system_facts. Confirmation prompt with a -y/--yes bypass. The legacy deviceKey/metaServerId DB rows are no longer *read*: server_info resolves identity from the registration then the standard files only, removing the footgun where alertd copied a stale deviceKey back onto disk. The rows are still deleted by unregister. Cached tags now live alongside the registration (%ProgramData%\bestool / /etc/bestool); the legacy C:\Tamanu / /etc/tamanu location is read as a fallback until the next online refresh. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The daemon reads the device key and server id once at startup and caches them for its lifetime, so enrolling or unenrolling only takes effect on restart. register and unregister now ask a running daemon to restart via the existing /restart control (best-effort: a daemon that isn't running is fine, it reads the registration afresh on its next start). Only wired up when the daemon is built into the binary. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e0b3bd6 to
3c6bca7
Compare
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.
🤖 Resetting and re-enrolling a canopy server kept hitting a conflict because a leftover device key was being reused across every enrolment. This makes a fresh enrolment use only the new identity, adds a way to wipe every trace of an old one, and removes the DB-backed resurrection path that quietly brought old keys back.
canopy registercanopy unregisterfirst, rather than silently reusing whatever identity is on disk.canopy unregister(new)Erases every place a canopy enrolment is stored:
%ProgramData%\bestool//etc/bestool, or a--configdir);device-key.pem,server-id);deviceKey/metaServerIdrows inlocal_system_facts, gated on the database being reachable — skipped with a warning otherwise.Prompts for confirmation, listing every target, with a
-y/--yesbypass. Elevates up front to remove root/admin-owned files, matchingregister.Stop reading the legacy DB rows
server_infono longer readsdeviceKey/metaServerIdfromlocal_system_facts; identity now resolves from the registration, then the standard file, and nothing else. This removes the footgun where the daemon copied a staledeviceKeyfrom the DB back onto disk, re-establishing an old identity even after the files were deleted. The rows are still deleted byunregister.Move cached tags alongside the registration
Tags now cache next to the registration instead of in
C:\Tamanu//etc/tamanu. The legacy location is read as a fallback so a host that hasn't refreshed since the move keeps its cached tags until the next online fetch rewrites them.Restart the daemon on an identity change
The daemon reads the device key and server id once at startup and caches them for its lifetime, so enrolling or unenrolling only takes effect once it restarts.
registerandunregisternow ask a running daemon to restart via the existing/restartcontrol endpoint, so it picks up the new identity (or drops the removed one) without a manual restart. Best-effort: a daemon that isn't running is fine — it reads the registration afresh on its next start. Only wired up when the daemon is built into the binary.Notes
get_or_create_server_idtests with file-based equivalents (no database needed now) and removed thewrite_device_key_filetests along with the function; added coverage forregistration::delete_inand the tags legacy-fallback.