Skip to content

Add inbound Matrix routing by hs_token (Phase 2) - #31

Closed
fmartingr wants to merge 1 commit into
feat/multiple-server-supportfrom
feat/multiple-server-support-phase-2
Closed

Add inbound Matrix routing by hs_token (Phase 2)#31
fmartingr wants to merge 1 commit into
feat/multiple-server-supportfrom
feat/multiple-server-support-phase-2

Conversation

@fmartingr

Copy link
Copy Markdown
Contributor

Summary

Phase 2 of multi-Matrix-server support (MM-64622): route inbound Matrix Application Service traffic to the correct server. Each managed homeserver has its own hs_token; the presented bearer token is matched against every server's token to resolve the serverID, and all lookups/persistence happen in that server's KV namespace.

Builds on Phase 1 (config/client registry, namespaced KV). Single-server installs behave exactly as before.

Changes

  • Auth middleware (server/api.go): match the presented Bearer token against every server's HSToken (constant-time, full scan), resolve serverID, and inject it into the request context. Keeps the global enable_sync check plus a per-server Enabled check; unknown/invalid token → 401.
  • Transaction dedup (server/matrix_webhook.go): key processedTransactions by (serverID, txnID) instead of txnID alone — Matrix txnIDs are only unique per homeserver, so colliding IDs across servers no longer dedupe against each other.
  • Event routing (server/matrix_webhook.go): thread serverID through processMatrixEvent; room-mapping and fallback room-state lookups use the resolved server's namespace and client from the registry.
  • Ghost-user detection: check the user-ID suffix against the resolved server's domain rather than the single global config.
  • Inbound persistence (server/sync_to_mattermost.go, server/bridge_utils.go): all matrix_user_, mattermost_user_, matrix_event_post_, matrix_reaction_ reads/writes are namespaced by serverID; post property stored as matrix_event_id_<serverDomain>.
  • /matrix server command (server/command/command.go): admin-only subcommands (list/add/remove/map) to register additional servers directly for local multi-server testing, since the System Console UI can't yet manage more than one server.
  • Local dev tooling: second Synapse/Element stack in docker-compose.yml (+ configs), and a docs/local-development.md guide.
  • Tests: two-server unit + integration tests covering namespace isolation, per-(serverID, txnID) dedup, unchanged single-server behavior, and unknown-token 401.

Acceptance criteria

  • Inbound events from server A never read/write server B's namespace.
  • Duplicate detection is per (serverID, txnID).
  • One-server installs behave exactly as before.

Route inbound Application Service traffic to the correct homeserver by
matching the presented hs_token against each server's HSToken, resolving
a serverID, and scoping all lookups to that server's KV namespace.

- api.go: MatrixAuthorizationRequired matches the bearer token against
  every server's hs_token (constant-time), injects the resolved serverID
  into the request context, and enforces the per-server Enabled flag on
  top of the global enable_sync switch.
- matrix_webhook.go: dedup transactions per (serverID, txnID); thread
  serverID through processMatrixEvent, room-mapping lookup, ghost-user
  detection, and Matrix-initiated DM handling.
- plugin.go/bridge_utils.go/sync_to_mattermost.go: construct inbound
  bridges scoped to the originating server; resolve the per-server domain
  for the matrix_event_id_<domain> post property.
- kvstore: add SetAtomicWithRetries for concurrency-safe upserts of the
  shared channel_mapping value across servers.

Also adds an admin-only /matrix server command group and backing registry
mutation API for local multi-server testing until the System Console UI
lands.
@fmartingr fmartingr closed this Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant