Skip to content

feat(client): local-key enterprise desktop and agent POC - #7663

Draft
baxen wants to merge 4 commits into
mainfrom
sketch/nip-fi-local-key-client
Draft

baxen wants to merge 4 commits into
mainfrom
sketch/nip-fi-local-key-client

Conversation

@baxen

@baxen baxen commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Desktop + agent POC (second pass)

This draft now implements a connected client POC against an assumed kgoose API, rather than only header plumbing and an effort inventory. Local Nostr signing remains unchanged; no remote custody implementation is imported.

Implemented

  • Work-account browser login → native assertion acquisition → community startup, with in-app reauthentication that preserves mounted drafts.
  • Bounded, no-redirect assertion exchange with exact-body NIP-98 proof, JWT metadata checks, per-key issuer/subject/audience pinning, single-flight renewal and retry cooldown.
  • Desktop WebSocket and background relay admission; HTTP query/GET/submit; media upload/download/proxies; huddle and agent TTS admission; expiry/logout leases and primary HTTP late-result cancellation.
  • Local-agent assertion broker with generation/key/relay-bound capabilities. Human JWT/session credentials are not handed to agents. Explicit agent-key publications acquire their own assertions.
  • ACP sockets + REST, CLI HTTP + one-shot WS, MCP credential forwarding and authenticated media. Agent sockets retain a fixed admission deadline and probe renewal authority.
  • Per-invocation Git second-header support for desktop project operations and buzz git; built-in dev-MCP routes Git through the renewing launcher.
  • Detached-provider launch supplies a scoped renewal credential through secret environment, assuming an adapter /agent-delegations endpoint.

Assumptions and scope

The new /v1/buzz/identity/assertions endpoint returns {assertion, nostr_pubkey, expires_at} following existing browser/code login. Detached agents additionally require /agent-delegations returning a revocable agent_credential. These are assumed API shapes, not existing kgoose implementation claims. The adapter must authorize agent enrollment/delegation; NIP-OA alone never substitutes for that policy.

Disabled by default. Configure BUZZ_BUILD_NIP_FI_ORIGINS, BUZZ_BUILD_LOGIN_API_URL, and BUZZ_BUILD_NIP_FI_ASSERTION_URL to run against the adapter. Mobile files retained from the first pass are still partial plumbing; this pass focuses desktop and agents.

Remaining POC limitations

  • No live Okta/adapter/enforcing relay, native packaged app, or remote provider deployment validated.
  • Huddles currently end at admission expiry and require rejoining; seamless audio renewal remains.
  • Native archive limit:0 live tails still need finite reconnect gap repair. Renderer and ACP have existing catch-up machinery.
  • Complete streaming/playback/late-result cache fencing and offline retention policy remain; logout is not a local-content wipe.
  • Custom/external harness shells need buzz git (built-in dev-MCP has the shim). Long Git transfers can expire mid-operation.
  • Detached credential policy, lifetime, revocation and support recovery require adapter agreement. Desktop logout alone does not revoke detached agents.

See docs/nip-fi-client-poc.md for runnable build settings, exact assumed request/response shapes, actual coverage and refinement work. The former sketch document is replaced, not an alternative implementation plan.

Verification

  • 473 CLI unit tests passed.
  • Spawned CLI → fake adapter → protected HTTP and WebSocket fixture passed; verifies both headers, exact-body possession proofs, key equality, token absence from frames, revocation refusal, and Git URL-scoped second header.
  • 12 shared client tests passed, including real adapter exchange, no redirect forwarding, metadata rejection, per-key tokens, stale login fences, and immutable socket expiry.
  • 104 ACP relay tests passed.
  • 100 dev-MCP tests passed.
  • 3 native identity tests passed, including real /query headers and logout during an in-flight result.
  • 2 Playwright enterprise/OSS startup tests passed (E2E mock bridge, Chromium).
  • Focused Rust/desktop clippy, desktop TypeScript, format/diff and file-size gates passed during implementation. Final focused clippy checks passed. All normal pre-push hooks passed, including Rust tests, desktop JS tests, Tauri clippy/tests, mobile checks, TypeScript, formatting/lint and file-size checks.
  • Full just ci failed in test-unit: acp::tests::idle_resets_on_stdout_activity failed its elapsed-time assertion (933 passed, 1 failed, 1 ignored in that run). The other 13 Rust groups passed; later CI stages did not run. No baseline establishes causality.
  • The first push was blocked by the normal branch-skew hook. origin/main was merged cleanly with sign-off (aa5845f36). On the merged tree, the isolated idle_resets_on_stdout_activity test and CLI HTTP/WS/Git acceptance passed. The full just ci rerun failed on keepalive_resets_idle_past_deadline (elapsed 100.734417ms; 940 passed, 1 failed, 1 ignored in that ACP run). The other 13 Rust groups passed; later CI stages did not run. Full CI is not green; timing sensitivity is suspected, not proven unrelated. The subsequent pre-push run exposed a shared-target collision: the CLI executable was replaced by a zero-byte sidecar stub, alongside the two ACP wall-clock fixture failures. Fix commit b90b14253 runs the CLI through its own test executable and drives the actual ACP reader with in-memory input/virtual time. The three focused idle-reset tests, CLI HTTP/WS/Git fixture, and clippy passed. Published successfully at b90b142538c50bc8953e8dd35e0aa8249efc0bfd; every normal pre-push hook passed, with no bypass. A full just ci pass after the fixture fixes is not yet established; the successful pre-push run is not equivalent to the full build gate.

Signed-off-by: Bradley Axen <baxen@squareup.com>
@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is a9dd4d3bd771b47f0efb4e7f6f7329a5921372b5...b90b142538c50bc8953e8dd35e0aa8249efc0bfd.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review b90b142538c50bc8953e8dd35e0aa8249efc0bfd to authorize a new review.
Any previous review applies only to its recorded range.

…mission

Signed-off-by: Bradley Axen <baxen@squareup.com>
@baxen baxen changed the title feat(client): sketch NIP-FI integration with local signing feat(client): local-key enterprise desktop and agent POC Sep 15, 2026
…ey-client

* origin/main:
  Fix desktop onboarding regressions (#7659)
  Deduplicate thread context by ACP session delivery (#7620)
  feat(mobile): hard-block under-18 users on the store age signal (#4665)

Signed-off-by: Bradley Axen <baxen@squareup.com>
Signed-off-by: Bradley Axen <baxen@squareup.com>
bradseiler added a commit that referenced this pull request Sep 16, 2026
## Summary
This is a behavior-preserving refactor that gives the desktop relay HTTP
bridge one helper for authenticated request construction. It moves the
repeated `Authorization`, JSON content type, optional `x-auth-tag`,
body, and timeout setup into `build_authenticated_relay_request`.

The helper uses the final URL, auth header, and body bytes passed by the
caller. It does not sign, reserialize, normalize, send, parse, classify
errors, choose a client, or handle rate limits.

Excluded paths: media, WebSocket, Git, agents, mobile, and NIP-FI. The
query send helper only routes through the new request builder so the
timeout and `x-auth-tag` behavior are covered by the same seam.

### Related issue
None found. This prepares for the enterprise identity follow-up to be
smaller than #7663.

### Testing
- `cargo fmt --manifest-path desktop/src-tauri/Cargo.toml --check`
passed at `356676a2f70f6bdf80cfdcb9084f1f7548359ecb`.
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml
relay::tests::authenticated -- --nocapture` passed at
`356676a2f70f6bdf80cfdcb9084f1f7548359ecb`.
- `just desktop-tauri-check` passed at
`356676a2f70f6bdf80cfdcb9084f1f7548359ecb`.
- `just desktop-tauri-test` passed at
`356676a2f70f6bdf80cfdcb9084f1f7548359ecb`.
- `just desktop-tauri-clippy` passed at
`356676a2f70f6bdf80cfdcb9084f1f7548359ecb`.

Generated with Codex

Signed-off-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>
Co-authored-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant