Skip to content

Federation Protocol

mzchat federation follows a Direct Participation model. Unlike Matrix or ActivityPub, where servers act as proxies for their users, mzchat clients connect directly to host servers while maintaining their home-server-rooted identity.

A user from Home Server (A) can join a guild on Remote Server (B) without Server B needing to maintain a permanent sync connection with Server A.

The join protocol is designed to be Optimistic & Fail-Open:

  1. Assertion: The Client calls JoinInvite on Server B, providing their $K_{id}$, a valid Device Certificate, and a Profile Hint (cached display name/avatar).
  2. Instant Validation: Server B verifies the cryptographic chain of trust. If the signature is valid, Server B immediately creates a local “Shadow Account” and grants access.
  3. Authoritative Sync: In the background, Server B enqueues a VerifyUser RPC to Server A.
  4. Finalization: Server A confirms the user’s authoritative metadata and provides a Push Delegation Token. Server B updates the shadow account with this data.

The “So What”: If Server A is offline, the user can still join and participate in Server B immediately. Only push notifications and authoritative profile refreshes are delayed.

Every user identity is cryptographically rooted in a single Home Server. This server is the authoritative source for the user’s root public key ($K_{id}$) and primary profile.

  • Active Server: The server the client is currently connected to for real-time interaction (primary UI context).
  • Homeserver: The permanent identity provider. Federated servers store the user’s homeserver URL to facilitate authoritative profile verification.

A defining pillar of mzchat is that the Client is Multi-Homed. It does not rely on the Home Server to proxy interactions with Remote Servers.

  • Direct Routing: Every resource (Guild, Channel, Message) is hosted by a specific server. The Client MUST route RPCs for that resource directly to the host server’s endpoint.
  • Transport Context: While the UI may have a global “Active Server” state, the underlying data layer derives the correct Transport per-request based on the resource’s origin server.

The “So What”: This prevents “routing leaks” where a client might accidentally send sensitive data or queries to the wrong server in a multi-server session. It also ensures that a failure on one server (including the Home Server) only affects resources hosted there.

Every federated user is represented on a remote server by a Shadow Account.

By default, remote servers maintain a local copy of the user’s profile metadata (display name, bio, avatar) which they periodically refresh from the Home Server via VerifyUser.

Users may choose to Unlink their profile on a specific federated server.

  • Synced: The remote server reflects the Home Server profile.
  • Unlinked: The user can set a unique display name/bio specifically for that server. The remote server stores this locally and stops automatic synchronization.

Regardless of sync status, the remote server maintains absolute control over local relationships: roles, channel access, and bans. A user’s reputation is tracked locally, though servers may choose to propagate ban notifications to the Home Server via PropagateBan.

Since the Client only maintains an active connection to the currently viewed server, notifications from other servers must be relayed.

  1. Event: A mention occurs on Remote Server B.
  2. Relay: Server B calls PushNotification on Home Server A using the Push Delegation Token obtained during onboarding.
  3. Delivery: Server A routes the notification to the user’s local UnifiedPush distributor.

Users can migrate their account to a new homeserver (Server B) from their old homeserver (Server A).

  1. Authentication: User logs into Server B using their identity key (K_id) via a signed device certificate.
  2. Proof of Migration: The login request includes a Migration Proof:
    • new_homeserver: The URL of Server B.
    • migration_timestamp: Current timestamp.
    • migration_signature: Signature of new_homeserver|timestamp signed by K_id.
  3. Server B Action:
    • Verifies the signature.
    • Updates the user’s homeserver field in its database to itself.
    • Sends an UpdateHomeServer RPC to the list of migration_targets (e.g., Server A) provided by the client.
  4. Server A Action (upon receiving UpdateHomeServer):
    • Verifies the signature (same payload).
    • Updates the user’s homeserver field in its database to Server B.
    • Future requests for this user may be redirected or proxied to Server B (implementation dependent).

This process ensures that the user’s identity moves with them, and old servers are notified to stop acting as the authoritative homeserver.

A homeserver acts as the authoritative source for the following user data:

  • User ID (id): The public key of the user’s identity key pair (Ed25519).
  • Public Key (public_key): Legacy field, now typically same as ID.
  • Device Certificates (device_certificates): List of authorized devices, their public keys (K_dev), and signatures.
  • Refresh Tokens (refresh_tokens): Long-lived tokens for session management.
  • Display Name (name): The user’s visible name.
  • Avatar:
    • avatar_url: URL to the user’s avatar image.
    • avatar_color: Fallback color for the avatar.
  • Bio (bio): User’s biography or status message.
  • Presence Preference (presence_preference): User’s desired online status (Online, Busy, Offline).
  • Homeserver (homeserver): The canonical URL of the user’s current homeserver.
  • Profile Sync Status (is_profile_synced): Whether the profile should be synced from the homeserver.
  • Guild Memberships (guild_members): Which guilds the user has joined.
  • Roles (user_guild_roles): Roles assigned to the user within each guild.
  • Permissions: Effective permissions derived from roles.
  • Join Date: When the user joined each guild.
  • Messages (messages): All messages sent by the user.
    • Content (Text, Media).
    • Timestamps (Created, Edited).
    • Pin status.
  • Reactions (reactions): Emojis added to messages by the user.
  • Typing Status: Ephemeral status (not stored permanently).
  • Push Distributors (push_distributors): URLs for push notification delivery (e.g., ntfy).
  • FCM Tokens (fcm_tokens): Firebase Cloud Messaging tokens for mobile push.
  • Guild Order (guild_order): User’s preferred ordering of guilds in the UI.
  • Files: Images, videos, and other media uploaded by the user. These are stored in the object store and referenced by file_id.
  • Federated Identity: If the user is from another server, their profile data is cached in users table but homeserver points to the remote URL.
  • Ban Records: If the user is banned, records are kept in banned_users and potentially propagated via ban_notifications.