Share the tokens, not the API key Block's Buzz makes multi-agent workspaces legible by scoping identity rather than permission flags, but the missing primitive is delegating bounded AI capacity without sharing API keys. freeq, an IRC server with cryptographic keys, solves this with a BUDGET command that lets operators set spending limits per channel and agents report signed spend against that budget, enabling consented, bounded, attributable, and revocable capacity loans. Share the tokens, not the API key ¶ share-the-tokens-not-the-api-key 2026-07-26 Block's Buzz https://github.com/block/buzz made the multi-agent workspace legible this month: humans and agents in the same room, every message and workflow step a signed event in one log, and agents holding their own keys rather than borrowing a human's. Its README puts the principle better than most specs do: "Scoped by identity, not by permission flags — the same way you'd scope a teammate." Which surfaces the next question. When five agents wake up to work, whose model allowance are they spending? People and teams increasingly pay for AI capacity that goes unused for long stretches: subscription allowances, prepaid credits, an organisational budget, a box running local inference. Meanwhile somebody else, or somebody else's agent, needs capacity right now and has none. Providers generally don't make that capacity safely delegable, and handing over your account credential is usually both prohibited and reckless. So the missing primitive isn't another shared API key. It's the ability to delegate a bounded amount of capacity to a person or an agent you choose, and keep attribution, revocation, and control while they use it. freeq is unusually well-shaped for that problem. The first post in this series https://freeq.at/blog/what-is-freeq/ explains the foundation: it's an IRC server that speaks the protocol a 1999 client speaks, except every participant holds a cryptographic key. This post is about what those keys become useful for once agents start consuming resources on somebody else's behalf. If protocol machinery is not your idea of a good time, the same substrate is rendered at FreeqWorld https://world.freeq.at/ as a multiplayer town: rooms are live channels, people and agents keep their DID-derived characters, and federation appears as travel between independently operated towns. What a loan of capacity would require ¶ what-a-loan-of-capacity-would-require Hand someone your credential and you've given them whatever authority that key carries, for as long as it stays valid, with no cryptographically attributable record of which jobs were theirs, and no way to withdraw it except rotation that breaks everything else using the same key. That isn't lending. It's making them you. A real loan needs the authority to spend to be its own object: consented to by the party whose capacity is being lent, bounded by an amount and a period,- attached to an identity rather than a secret, attributable per job, to the instruction that authorised it, revocable without collateral damage,- and narrowing rather than widening as it's passed along. That is a delegation problem, not a billing problem. The pieces freeq already had ¶ the-pieces-freeq-already-had An operator sets a budget in a channel and names who funds it. The sponsor defaults to whoever issues the command: BUDGET research amount=500;unit=credits;period=day;warn=0.8;hard=true Agents working there report what their work cost, signed, against that budget: @+freeq.at/sig=ed25519:kid:9f2c…:BASE64 SPEND research :amount=3;unit=credits;desc=claude-sonnet-4:1.2k-tokens;task=01JQ… That is the protocol shape a loan needs: a named sponsor, someone else's attributed work, and a limit that follows the delegation chain. At the start of this work freeq enforced that limit only over reported spend. It did not mediate or debit the underlying model capacity. Joining those two systems is what changed while I was writing this post. Around it, the identity rails are real: Who the human is. Accounts are AT Protocol DIDs. You authenticate by signing a server challenge with the key in your DID document, so the server holds no password and didn't issue your identity. Who the agent is. An agent has its own keypair, and its creator signs a FreeqBotDelegation/v1 certificate over the agent's DID and public key. Four rejection paths are tested: tampered signature, DID mismatch, missing signature, creator never registered. That proves one thing precisely, namely that this key was authorised by that key, and nothing about who holds the key now or what software is running. What was said. Every client registers an ed25519 key with MSGSIG and signs each message. The server verifies and relays the signature unchanged rather than re-signing, and keys are stored append-only by did, kid so a signature stays verifiable after the sender rotates or disconnects. What can be passed on. Spend aggregates across the delegation chain instead of resetting at each new identity, and a child inherits its parent's limit rather than falling through to the channel default. Capabilities narrow on delegation: a child gets the intersection with its parent's set, so an agent can't confer authority it doesn't hold. That last one was a bug until this week. The spawn path recorded whatever was requested, so an agent holding nothing could create a helper recorded as holding anything. The seam where it stopped ¶ the-seam-where-it-stopped Testing the joins between those systems is where the interesting findings were, and the sharpest one is a two-line observation: The budget system is metered and unmediated. The model path is mediated and unmetered. That was the state when I started writing this. freeq put itself between a caller and a paid model in exactly one place, its diagnostic interface, where the server holds the provider key and callers are authenticated by session bearer to DID, so nobody is handed the credential. That path recorded no spend and checked no budget. Meanwhile the budget system counted carefully, over numbers agents reported about calls freeq never saw. The one paid resource freeq controlled was the one it didn't count. Once stated that plainly, the separation was impossible to justify. So the two halves are now joined. The join, now that it exists ¶ the-join-now-that-it-exists POST /api/v1/model/chat/completions is an OpenAI-compatible call made by the server , charged to a channel budget: Authorization: Bearer