@bot-federation/relay-core
v0.1.0
Published
Runtime-agnostic Bot Federation relay: invite handshake, blind envelope routing, capability enforcement, audit
Readme
@bot-federation/relay-core
The Bot Federation relay's trust logic, storage ports, and HTTP surface — with no dependency on a specific runtime or database.
npm i @bot-federation/relay-coreRunning a relay in ten lines
import { MemoryRelayStore, RelayService, createRelayApp } from '@bot-federation/relay-core';
const service = new RelayService({
store: new MemoryRelayStore(),
config: { registration: 'account_allowlist', accountAllowlist: ['acct_a', 'acct_b'] },
});
export default createRelayApp({ service }); // a Hono app: Workers, Node, Deno, Bunapps/relay in the repository binds this to Cloudflare Durable Objects. Tests and the browser demo bind it to MemoryRelayStore.
What the relay is
A blind, accountable postbox. It authenticates who is talking to it, enforces that an active federation grants the scope in use, rejects replays, meters abuse, and records metadata.
It cannot read a message body, read an intent statement, mint or widen a capability, forge a signature, or revive a revoked federation.
Bringing your own storage
Implement RelayStore. Four operations must be atomic with respect to concurrent callers, because a read-modify-write race in any of them is a security bug rather than a glitch:
| | |
|---|---|
| claimNonce | Replay rejection |
| bumpSeq | Ordering guarantee |
| consumeRate | Abuse control |
| incrementCapabilityUse | Capability budget |
Everything else is ordinary record storage. MemoryRelayStore is a readable reference implementation; the Durable Objects adapter in apps/relay shows how to shard it.
Configuration
| | |
|---|---|
| registration | open for local development, account_allowlist for anything public, closed to freeze |
| requirePasskeyForAccept | Default true. Require a user-verified passkey, not an owner key, to accept an invite |
| requireApprovalForElevatedSend | Default true. Require a relay-verifiable approval on every elevated send |
| requirePasskeyForElevated | Default true. That approval must be a passkey. Owner-key is not sufficient |
| webauthnRpId / webauthnOrigin | Relying party for passkey verification |
| defaultPlan | Tenancy hook. Plans and quotas attach to org_id; no billing logic lives here |
HEADLESS_RELAY_CONFIG turns all three flags off for the in-browser demo and tests. relayConfigFromEnv relaxes a flag only on the literal string 'false'. Do not copy the headless overlay onto a network-reachable relay.
All authorization lives in RelayService. The HTTP layer parses, enforces a size cap, and maps typed errors onto status codes — so a reviewer can read the trust surface in one file.
Apache-2.0
