Repository navigation
feat(identity): always back up keys in managed builds - #2398
Conversation
add the BUZZ_NSEC_BACKUP_CONSENT=managed native build input. when set, the uploader backs up every local key and ignores the saved backup choice, so keys created before backup was configured are backed up too. build.rs accepts only empty or managed, and managed requires the backup service and namespace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
a managed pass holds the shared consent lease across network requests, so first run saving automatic backup hit busy and reported interrupted. in managed builds, enabling backup while a pass holds the lease now succeeds without writing. adds a regression test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
…choice a malformed or incompatible choice.json stopped managed backup with a storage failure. nsec_backup_choice::admit now takes only the shared lease in managed builds and keeps the existing validation otherwise. adds coverage for missing, opted-out and malformed choices. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kalvin Chau <kalvin@block.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Automated source review by Star Lord via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security) and Groot (product flows) reviews.
No actionable correctness or security findings at head d1ff286ae7e9e612e59267bbb597298961f5864a against base c3c46c50352f13dd1b1b8a966de01e7a05f7b72e. The malformed-consent failure identified on the earlier revision is resolved in source: managed admission now acquires only the shared lease, and the named _consent binding retains it through the backup pass. Unmanaged consent validation and the account/key checks remain intact. The added admission test covers missing, false and malformed choices plus exclusion of concurrent choice writes.
Optional documentation cleanup: qualify the “Automatic backup consent hooks” section in docs/identity.md for managed builds, so its description of future automatic uploads agrees with the new policy.
Source-only review of the change, callers, lifecycle, test source and public PR description (no attachments). We did not run tests, builds or the app, or independently verify CI. Helper-level coverage does not establish a packaged managed build uploading an existing key; that remains unverified. This is a COMMENT review, not approval.
* origin/main: (52 commits) feat(agents): give plugin agent types the Buzz side of a turn (#2364) feat(plugins): pin buzz://plugin-install links to a path and commit (#2315) feat(plugins): tint currentColor SVG page icons like host icons (#2314) feat(notifications): add a soft notification sound (#1536) feat(agents): let agents propose a profile picture (#2267) fix(plugins): default reminders and workflows off for fresh installs (#2291) Show all reactors in compact, separate emoji capsules (#2179) fix(panels): remember page split widths per workspace (#2264) feat(search): browse open channels from a Channels tab in search (#2164) perf(relay): page combined replay filters after a reconnect (#2308) fix(composer): make native Mac text shortcuts work past link chips (#2390) perf(relay): read creator proofs for many channels per filter (#2312) fix(channels): let published leave and delete confirm through access loss (#2357) fix(media): save native context menu media downloads and hide loopback links on macOS (#2131) fix(links): say why a message preview is unavailable, and preview unjoined public channels (#2136) test(browser): serve emoji artwork in the reaction hit-area journey (#2138) test(browser): click a reply link only after its row settles (#2358) fix(agents): restore delegated workflow mentions (#2399) feat(identity): always back up keys in managed builds (#2398) test(threads): render before checking the reader across activity resizes (#2389) ... Signed-off-by: Gil Birman <gil@squareup.com> Co-authored-by: Claude <noreply@anthropic.com> # Conflicts: # src/plugins/author.test.mjs
Adds the native build input
BUZZ_NSEC_BACKUP_CONSENT=managed. A build compiled with it backs up every local key and ignores the saved backup choice.Why
Without the flag, the uploader runs only when
choice.jsonholdsautomatic: truefor the current key, service and namespace, and only first-run setup writes that file. A user who was signed in before backup was configured never goes through first run again, so their key stays atno_consent("Automatic backup is off for this key."), and nothing in the app can change that. For an organization's build, backup is policy, not a per-user choice.What
nsec_backup_config::managedvalidates the input. Unset or empty keeps explicit consent.managedrequires the backup service and namespace to be configured. Any other value fails the build.build.rsruns that validation alongside the existing service and namespace check.nsec_backup_choice::admitdecides whether a pass may run. In managed builds it takes only the choice file's shared lease and doesn't parse the saved choice, so a missing, opted-out or malformed choice can't stop backup. The lease still serializes passes against choice writes. Unmanaged builds keep the existing validation.nsec_backup.rsuses it as its consent gate. Every other precondition still applies: a Builderlab session, and the key bound to the signed-in account.nsec_backup_choice::set: in a managed build, turning automatic backup on while a pass holds the shared lease now succeeds without writing, because the running pass already backs the key up. Without this, first run'ssetBackupChoice(pubkey, true)(backup.ts:184) fails with busy and reports "interrupted" when a pass started bylocal_key_installedis still running.docs/identity.mddocuments the input.Unmanaged builds behave the same as before. No UI change.
Validation
nsec_backuplib tests pass (59), includingmanaged_consent_needs_configured_backup,a_managed_build_enables_backup_during_a_running_passanda_managed_build_admits_a_pass_whatever_choice_is_saved. The second test holds a pass at the upload request and checks that an unmanaged write still fails with busy while a managed one succeeds. I ran the built test binary directly because the local signed-run wrapper needs a signing identity.cargo clippy -p Buzz --lib --tests -- -D warningspasses unconfigured.cargo clippy -p Buzz --lib -- -D warningspasses with a managed staging configuration.cargo fmt --checkpasses.Not exercised: a packaged managed build uploading an existing key. The release pipeline sets the input in a separate change.
🤖 Generated with Claude Code