Skip to main content

Federation

Nodes federate with each other over HTTPS with signed requests (protocol: FEDERATION.md). Users of one node join rooms, send DMs and add friends on other nodes; their home node vouches for them. Federation is on by default (TAVRN_FEDERATION_ENABLED).

Every node serves its discovery document at https://<TAVRN_DOMAIN>/.well-known/tavrn: domain, endpoints, node keys, policies and capabilities. Other nodes resolve a domain in the order well-known → SRV record → direct https://<domain>/api/v1. If the node runs on another host than its identity domain, the identity domain must proxy the well-known path or publish an SRV record: Identity domain and node host (delegation). The node also serves the document on its own host.

Outbound federation requests go only to public addresses (private and loopback addresses are refused unless TAVRN_FEDERATION_ALLOW_PRIVATE=true, meant for development and closed intranets).

The operator decides which nodes this node federates with and how much load other nodes may cause.

  • TAVRN_FEDERATION_BLOCKLIST: domains never federated with, including their subdomains. Node admins can also block a node in the Federation tab of the node administration. Node and room bans of a domain also cover its subdomains (a ban of evil.example refuses a.evil.example).
  • TAVRN_FEDERATION_ALLOWLIST: if set, the node federates only with these domains (a closed federation); the blocklist still wins.
  • Blocks and node bans of a domain stop the outgoing traffic too: queued notifications for it are dropped as undeliverable, and profiles, avatars and application documents are no longer fetched from it.
  • Incoming friend requests: at most 10 per hour from one node to one user, and at most 20 pending from one node per user; further requests are dropped.
  • Rate limits per remote domain and minute: TAVRN_FEDERATION_RATE_LOGINS, …_INBOX, …_API, …_CLAIMS, with shares per remote user (…_API_PER_USER; a quarter of the logins per account and per client address); quotas of remote users: TAVRN_FEDERATION_MAX_REMOTE_USERS, …_PER_DOMAIN.
  • Remote users with nothing left on this node are deleted after TAVRN_FEDERATION_REMOTE_USER_RETENTION_DAYS.
  • Bots: TAVRN_FEDERATION_REMOTE_BOTS (accept other nodes’ bots), TAVRN_APPS_FEDERATE (this node’s bots on other nodes).
  • TAVRN_FEDERATION_NOTIFY_BANS=true tells a banned remote user’s home node about the removal (never the reason).

Notifications for conversations on other nodes reach a user through the federation notify hint at the user’s home node (only DMs, group DMs, mentions and calls for remote conversations); the home node then sends web push where needed.

Nodes find each other through reference nodes (TAVRN_REFERENCE_NODES, several comma-separated are fine). The binary’s default is empty; .env.example sets tavrn.org, the official node and reference directory, which you may keep, replace or clear. Without a reference node a node neither announces itself nor pulls a node list; its Discover page then shows only the nodes that announce themselves to it. With TAVRN_DIRECTORY_LISTING=true (the default) a node announces itself to each of them at startup, every 6 hours and whenever a room is listed or unlisted. The reference node verifies the announce against the node’s own /.well-known/tavrn (it must be reachable over HTTPS with a valid certificate, and federation must be on), then lists the node and fetches its discoverable rooms from the node itself; every room comes with a listing the node signs, so no other node can forge it. A node not heard from for 48 hours drops out of the list. Nodes also pull the node lists of their reference nodes, so the Discover page of every node shows the whole directory.

  • To be listed: keep TAVRN_DIRECTORY_LISTING=true, make sure the reference node can reach your https://<domain>/.well-known/tavrn, and let room owners mark public rooms as listed. Only rooms marked that way appear; the node’s name and description come from TAVRN_NAME and TAVRN_DESCRIPTION.
  • Not to be listed: TAVRN_DIRECTORY_LISTING=false. The node still federates and its users can still use Discover; other nodes refuse to list it.
  • To run a reference node: there is nothing extra to switch on, every node accepts announces. Point other nodes’ TAVRN_REFERENCE_NODES at your domain. TAVRN_DIRECTORY_MAX_ROOMS (default 5000) caps the cached rooms of other nodes (at most 200 per node). Announces are limited to one per domain every 10 minutes.
  • Moderation: node admins remove a node or a single room from their directory with DELETE /api/v1/admin/directory/nodes/{domain} or DELETE /api/v1/admin/directory/rooms/{node}/{room_id} (undo with POST /api/v1/admin/directory/relist); delisted entries are neither shown nor passed on. Blocked domains (TAVRN_FEDERATION_BLOCKLIST, node bans of a domain) are never listed.
  • A listing node lists itself: its own entry (built from TAVRN_NAME, TAVRN_DESCRIPTION and its discovery document) and its listed rooms appear in its own directory, so a reference node shows up in the lists other nodes pull from it.
  • Reports: users report other nodes or their rooms from the Discover page (“Report”). Reports go to the admins of the user’s own node, never to the reported node, and never block anything on their own: the Federation tab of the node administration shows the count per node and the reports, and removes a node from the directory from there. Three different users reporting the same node within 7 days leave a notice in the audit log. Each user can send 10 reports a day; reports are kept 180 days.

A node checks the behavior of every node it federates with (not its code): shortly after the first contact, then daily, and on demand (FEDERATION.md §9). The checks use the reserved system account tavrn-conformance (created at the first start, no password, hidden from user lists; the username cannot be registered) and a throwaway room on the other node, and verify among other things that forged, replayed, expired or misaddressed tokens are refused, that the inbox refuses unsigned and tampered messages, that the MLS delivery service refuses stale, replayed and tampered commits, that plaintext is refused in encrypted channels, and that logins are rate-limited.

  • Hard failures (e.g. a forged signature is accepted) and spoofing seen in live traffic (a token for a user of another domain, a forged from, repeated tampered inbox messages) block the node automatically. A later check without hard failures lifts an automatic block. Warnings never block.
  • keys.consistent also fetches the other node’s discovery document from every address its domain resolves to (IPv4 and IPv6, several hosts): different keys on different addresses are a hard failure (a split view or an interception on one path). Roll out new signing keys to all hosts of a node at once.
  • TAVRN_FEDERATION_REQUIRE_CONFORMANCE=true (default false) additionally refuses federated logins and inbox messages of nodes that were not checked yet (503 federation.conformance_pending, the check starts at once) or failed.
  • The Federation tab of the node administration lists the known nodes with their result, failure and violation counts; it runs a check now, blocks and unblocks a node (all audited). The same over the API: GET /api/v1/admin/federation/peers, POST …/peers/{domain}/check, …/block, …/unblock.
  • From the command line: docker compose exec tavrn tavrn-node doctor --peer community.example (CLI commands).
  • Users see a warning above the rooms of a node that failed the check of their home node; rooms of a node their home node blocks are not shown at all.

This page is generated from tavrn-node/docs/HANDBOOK.md (AGPL-3.0-only) when the website is built; its links were adapted for this site.