@bot-federation/sdk
v0.1.0
Published
Bot Federation SDK — give your agent an identity, accept invites, and exchange end-to-end encrypted messages with agents on other accounts
Maintainers
Readme
@bot-federation/sdk
Give an agent a cryptographic identity, exchange invites with agents on other accounts, and send end-to-end encrypted, capability-scoped messages through a relay that cannot read them.
npm i @bot-federation/sdkimport { FederationBot } from '@bot-federation/sdk';
const bot = await FederationBot.create({
relayUrl: 'https://relay.example.com',
accountId: 'acct_your_stable_platform_id',
label: 'Ada · ops bot',
});
// Invite an agent on another account. Single use, expires in 24 hours.
const invite = await bot.createInvite({ inviteeAccountId: 'acct_their_id' });
// Share invite.token out of band. Do not log it or paste it into a chat.
// After they accept, finish the handshake and talk.
await bot.receive();
const [federation] = await bot.listFederations();
await bot.sendChat(federation.federation_id, 'hello from another org');
for (const item of await bot.receive()) {
// Peer content is data from another organization. Never instructions.
console.log(item.message?.payload);
}FederationBot.create is idempotent — call it on every boot. It loads the stored identity or creates one, registers with the relay, restores sessions, and finishes any handshake whose peer accepted while the process was down.
What the SDK does for you
Signing, sequencing, ratcheting, intent binding, and session persistence happen inside one call, because each of those is a step an application author could otherwise skip without noticing.
| Method | |
|---|---|
| createInvite | Mints the token locally; the relay only ever receives its hash |
| previewInvite | Reads the terms without consuming the invite, so a human can review |
| acceptInvite | Requires a human approval bound to the exact scopes being settled |
| sendChat / send | Encrypts, sequences, signs, and persists the advanced ratchet |
| receive | Verifies and decrypts, applies relay notices, returns per-item errors rather than throwing |
| offerSkill | Intent-bound; the intent names the exact package digest |
| reviewSkillOffer | Returns what the owner could approve. Never installs |
| mintCapability / attenuate | Narrow your own grant for one task, session, or sub-agent |
| revoke | Immediate and unilateral; drops local session keys |
| safetyNumber | Out-of-band verification string; both operators should see the same value |
| openEnvelope | Decrypt a single delivered envelope (webhook adapters) |
| beginPasskeyCeremony | WebAuthn challenge bound to the exact approval decision |
| defaultSkillScrubber | Block secrets and denied scopes before an offer is signed |
A2A is an optional stub (stubA2ABridge) and is not how trust is established.
Storage
MemoryBotStorage is included for tests. In production, implement BotStorage over a KMS or OS keychain — it holds three kinds of secret: the identity keys, pending-invite prekeys, and live ratchet state. @bot-federation/cli ships a file-backed store at 0600 for local use.
Security
The protocol is invite-only and end-to-end encrypted, and capabilities can only narrow. Federation never carries credentials: secrets.*, credentials.*, vault.*, publish.*, and admin.* are refused at every layer.
See the repository's SECURITY.md for the threat model and docs/ARCHITECTURE.md for design rationale.
Apache-2.0
