Skip to content

Identity is an Ed25519 keypair

Part of funduq's mechanisms.

A provider's identity to any funduq it connects to is its Ed25519 keypair — not an account funduq issues. An agent is (public key, name); an LLM offering is the same pair; a name is deliberately not an identity and is not exclusive. A short fingerprint derived from the key supports human-friendly resolution, trust-on-first-use: two keys colliding on one fingerprint is an error, not a merge. funduq has a keypair of its own (FunduqIdentity, configured, never generated silently), so a provider can pin the funduq it means to serve and detect an imposter before producing anything worth stealing.

Three payload families on this side, each under its own domain tag so a captured signature for one purpose can never be replayed as another:

domain tag signed by authorizes
funduq-connect-provider connecting provider opening a link
funduq-connect-funduq funduq answering a link-open
funduq-kyok-call agent provider one KYOK completion call

(Three more belong to callers rather than providers — funduq-delegate, funduq-resolve and funduq-cancel — and are in responsibility chains. Six in all.)

Registering and deleting are not on that list, and used to be. Four families signed them — one per roster, one per verb — each re-proving with a self-chosen timestamp that the caller held a key. But the key was already proved, once, when the link opened: the handshake is a session in everything but name, and those four were re-proving what it established. They are operations on the open link now, and nothing signs them.

Two things went with them. The agent card was never in a registration's signed bytes, so a captured signature could re-register the same names with a different card — there is no detached signature left to splice one onto. And funduq-connect-provider no longer binds the names to be served: they were in there so a captured proof could not be replayed to serve a different agent, and a ticket issued to one key cannot be replayed at all.

The KYOK call keeps its own signature because it is a different channel — the agent provider calling in, not riding its own outbound link — and it is the one payload that hashes the request body into the signature, which is what a paid call deserves.

The KYOK call signs over a timestamp inside a freshness window. Link-open does not: a self-chosen timestamp is replayable for its whole window by anyone on the path, so opening a link answers a challenge the verifier chose — funduq mints a single-use nonce, the provider signs it together with its own nonce, the names it intends to serve, and the funduq key it means to connect to — the recipient is in the signed bytes, so a proof coaxed out by one funduq cannot be relayed to attach at another — and funduq's answering signature (over both nonces, under a distinct role tag so neither proof reflects as the other) is what the provider verifies against its pinned funduq key. In-process connections authenticate the same way, automatically — sharing a process is not a reason to skip identity.

Roster rules

Registration is a signed batch, and re-registering a subset withdraws the omitted names from live serving. Attaching — declaring which registered names a connection serves right now — requires prior registration and never implies it. Deletion is its own signed act and is refused while the name is in use. funduq holds one connection per role: a re-attach under the same key replaces the old connection; replicas are the provider's own concern behind its single connection.

Published as data

Every payload above is exported by the SDKs — the agent families by funduq-provider-sdk, the LLM families by its llm extra — as independent twins of funduq's implementation: neither SDK imports funduq nor funduq them (the LLM SDK does share the provider SDK's keypair class, because identity is identity). Each is pinned byte-for-byte in contract-vectors.json, with deterministic signatures under a published test key. CI fails if a payload family goes unpublished.

Design records

Why this is shaped the way it is, and what it was shaped like first: