Skip to content

feat(desktop): register an agent that runs elsewhere — attest an existing public key and publish its owner policy #8012

Description

@samsymbia

Motivation

Buzz already treats a hand-launched agent as first-class at the protocol level: docs/remote-agents.md says a launcher that exports BUZZ_PRIVATE_KEY, BUZZ_RELAY_URL and BUZZ_AUTH_TAG and execs the harness "is a conforming launcher … today, with no code change". A systemd unit on a VPS, or a harness Buzz doesn't ship at all, qualifies.

What's missing is the owner's side. For an agent it did not create, the desktop cannot produce either of the two owner-signed things such an agent needs:

  • the NIP-OA attestation. The desktop mints one only inside the create-agent form, for a key the form generates (Keys::generate() in desktop/src-tauri/src/commands/agents.rs); there is no import. The CLI verifies tags but never mints them.
  • the kind:30177 policy. Without it, once an agent is attested, the mention picker hides it: getAgentMentionAdmission always admits a person but admits an agent only if a verified owner policy's respond_to includes the viewer. Adding an agent to a channel as bot goes through the same flow, so it can't be added either.

The form's "Where to run" choice can't express this case: it offers "This computer" and buzz-backend-* providers found on the owner's machine, all of which run the harness on the owner's behalf. An operator running the harness themselves — on a server, or a harness other than buzz-acp — has no door. Today the only way through is hand-computing the tag with compute_auth_tag, and hand-signing and publishing the kind:30177, which means handling the owner's nsec outside the keyring.

We hit this provisioning three agents as code (two headless buzz-acp agents under systemd, one agent running through another harness's Buzz channel plugin). Each showed as a person in the desktop, and once attested, could not be mentioned.

Proposed solution

A third "Where to run" option in the create-agent dialog: "Somewhere else — I run it myself".

  • It asks for the agent's public key (npub or hex) — not a keypair. An attestation is a signature over the public key, so the desktop never needs the agent's secret, and the operator's key never has to leave the host it runs on.
  • It skips the harness/runtime/provider fields, which aren't the desktop's to decide in this mode, and keeps name, respond_to / allowlist and optional persona.
  • On save, with the owner's keyring key, it computes the NIP-OA tag with empty conditions (as the form does today) and publishes the kind:30177 policy, using the existing build_agent_event shape. It omits system_prompt / model / provider, since the operator owns those.
  • It shows the BUZZ_AUTH_TAG value to install on the agent's host, single-quoted. Then, as it does for provider deploys, it can wait until the agent's latest kind:0 carries a valid tag — which is what the desktop itself uses to decide "agent".

These agents would then appear in My Agents with the existing "Not managed on this device" cloud marker, and their policy could be edited there like any other.

Permissions. We don't think this needs a relay-role gate, and it shouldn't be admin-only:

  • creating an agent isn't role-gated today;
  • on a closed relay, an owned agent is admitted through its owner's membership, the same delegation desktop-created agents use;
  • signing a tag over a key you don't control is inert — the relay records an owner only when the agent itself authenticates presenting the tag (needs its private key), the desktop reads ownership only from the agent-signed profile, and the directory accepts only policies from the owner that profile names.

A relay operator who wants to limit who may bring agents would be better served by a relay-side policy than a UI gate.

Alternatives considered

  • Importing a keypair into the form. Moves the agent's private key onto the owner's laptop, and the desktop would then consider itself the agent's manager. The public-key-only flow avoids both.
  • buzz agents draft-create. It needs BUZZ_AUTH_TAG already, so it can't bootstrap the first attestation. It's for an attested agent proposing a new agent (and see fix(desktop): buzz agents draft-create succeeds on relay but fails to trigger Desktop draft review form #3791).
  • A CLI subcommand to mint tags and policies. Works — it's what we use today — but it means pasting the owner's nsec somewhere other than the keyring. A desktop action keeps the key where it is.

Additional context

Related, and in practice encountered in this order when doing this by hand:

Duplicates: none found for registering an externally-run agent. Closest are agent snapshot import (#4197, #5458), which imports a definition rather than an externally-run key, and draft-create (#3791).

Tested against relay 40220d5 (v0.2.1).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions