Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions proposals/4519-rtc-transports-registry.md

@turt2live turt2live Jul 28, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Transports endpoint: client
  • Transports endpoint: server

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is effectively implemented by Synapse via MatrixRTC.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

When ran in widget mode, Element Call cannot yet use the /transports endpoint because the widget API doesn't expose access to it. This is covered by #4515.

Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# MSC4519: MatrixRTC Transports Registry

[MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143) describes the framework for
Real-Time Communication (RTC) applications to operate over Matrix. The MSC also allows for alternate

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really 'alternate': it needs a transport to work at all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…which does somewhat conflict with the registry msc's requirement that only optional functionality be in registries… I suppose it's optional in that you don't have to implement all of them, even if you have to implement one?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"alternate" is in contrast to the specified transport itself, if any. We don't currently have that, so this might be confusing.

transports to be made available for accessing media streams of RTC application members. See MSC4143
for definitions and more information.

[MSC4518](https://github.com/matrix-org/matrix-spec-proposals/pull/4518) describes a process to
support interoperability of non-core Matrix components. The MSC supports a variety of data types
being stored within a registry, keyed by a string identifier, including chunks of specification.
See MSC4518 for more details on what registries are and how they intend to operate.

This proposal creates a new registry to hold RTC transports and their specifications, encouraging
interoperability without requiring those transports to enter the core Matrix specification. Transports
suitable for the core specification can still land there, though they'll also need placing in the
registry.

The primary motivation for a registry is to allow transports such as [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195)
to land with relative stability, but without placing a dependency on LiveKit into the core spec.
Comment on lines +18 to +19

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec has some optional modules, this sentence along with the potential issue of there not being many RTC transports makes this feel like overkill to have this be a registry?

@Johennes Johennes Aug 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think we need to improve the motivation a little. The concrete advantages of the registry I can currently think of are:

  • Releasing transports is not dependent on the spec release cycle
    This proposal doesn't currently clarify whether the registry will be released together with the spec or not though. See also https://github.com/matrix-org/matrix-spec-proposals/pull/4519/changes#r3813858452.
  • Transports can more easily be removed from the registry than from the main spec
    Homeservers declare support for entire spec versions. Even if a feature is removed, servers often retain their implementations to be able to declare support for older spec versions. This came up as a concern when discussing the integration of the LiveKit transport with the Synapse team.

Having said that, I acknowledge the concern that we may not have a lot of transports, however. The transports the VoIP team at Element can foresee right now are:

  • LiveKit (MSC4195)
    This is the only one we have today.
  • A cascading SFU transport where users connect to their local SFU only and SFUs federate
    @fkwp has made some explorations on this. It'll require a dedicated SFU implementation. If proven worthwhile, this would be an alternative (if not a full replacement) for the LiveKit transport. Currently, it seems likely that we'll work on this after Matrix 2.0.
  • A full-mesh transport where members connect to each other directly as in legacy VoIP
    This would be an alternative for small calls without LiveKit. Currently, it does not seem overly likely that we'll work on this in the near future unless somebody sponsors it.

It's difficult to predict what transports other people might come up with though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transports can more easily be removed from the registry than from the main spec
Homeservers declare support for entire spec versions.

I don't buy this. If we add a capability for them then just rip it out and mark it as unsupported via the capability.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erikjohnston is the main proponent for not putting LiveKit into the spec, so I'd appreciate talking points from him that can be included in this MSC.



## Proposal

A new "MatrixRTC Transports" registry is created with the following information:

* A transport `type`. MUST be an [Opaque Identifier](https://spec.matrix.org/v1.19/appendices/#opaque-identifiers).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this proposal says, "Types not in the registry are not permitted," but I hope that the spec could eventually make room for unregistered, proprietary transports which might not be suitable for making public. This seems easiest to manage if we recommend the Common Namespaced Identifier Grammar.

Previously we were recommending CNIG without the namespacing requirements so that we could still have an un-namespaced livekit as in this MSC, but I & others on the Element VoIP team would be interested in your judgement on whether it would be preferable to keep the namespacing requirement, if we say type uses CNIG.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly supporting proprietary transports doesn't really fit the Guiding Principles in my opinion. We can support namespacing, but I would still probably keep the limitation that only registered types can be used, at least until Matrix itself has a transport type that's part of the core specification.

Without a core transport type in the spec we run the risk of only having proprietary transports, which defeats the purpose of this registry.

A later MSC can remove the condition easily enough without it being a breaking change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(leaving open for further opinions, but mentally considering resolved for now)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would using m.livekit really be that bad?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m.livekit is fine in isolation, but opening up the registry to have unregistered custom types I feel would be a mistake.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should switch to m.livekit because we already use the namespacing elsewhere in MatrixRTC (e.g. m.per_member) and we would probably want to allow extensibility at some point.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#4195 has switch to m.livekit now.

* Stability (`stable` or `unstable`).
* A link to the specification for that transport, per MSC4143.

`stable` transports are added/changed/removed through normal MSCs. `unstable` transports are automatically

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit I'm somewhat struggling with what the MSC really achieves since clients could implement an open MSC today, so this feels like just a way to bypass the review process, but then isn't that process there for a reason?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the idea that registries exist outside of the spec, we need to define the process by which the registry is updated/used. This includes defining how unstable types are reflected in the proposed endpoint and how experimental implementations are worked on. Without automatic registration, we'd need 2 MSCs before implementations could start using a new transport: one to define the transport (already required) and another to add that to the registry.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well my point is that if there was no registry, you could just create the MSC and then start using it unstable-prefixed as we do now?

added when a new proposal is opened which introduce a transport. They MUST have a `type` of `msc0000.{stable_type}`
Comment thread
turt2live marked this conversation as resolved.
Outdated
and implementations MUST use the "Unstable Prefix" identifiers from the proposal rather than any
stable identifiers. For example, MSC4195's `livekit` type would have an unstable registration of
`msc4195.livekit`, using unstable identifiers. Later, if accepted, `livekit` can be registered as a
Comment thread
turt2live marked this conversation as resolved.
Outdated
stable `type` with stable identifiers in its specification.

Twelve months after the FCP acceptance of the MSC the unstable type is automatically removed from the
registry. Early removal is possible if the public federation has adopted the stable type sooner than
expected - a normal spec PR with normal review requirements is used to propose that removal.

**Note**: The automation above is process automation. Someone will still need to actually open the
spec PR which adds/removes/changes a transport's registration.

This structure allows for registry changes to be as easy as modifying the specification itself. As
a worked example:

* MSC4195 gets opened, introducing the `livekit` type.
* The author opens a spec PR to register the `msc4195.livekit` unstable type, using the MSC URL as
the specification reference (specifically the "Unstable Prefix" section/components).
Comment on lines +52 to +53

@Johennes Johennes Aug 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unstable transport is registered manually via a spec PR here but further up it says

[...] unstable transports are automatically added when a new proposal is opened which introduce a transport.

Having the registry change automatically as MSCs are opened worries me a little. I also wonder if we actually need to register unstable types in the registry at all? It feels like while something is not stable, it shouldn't land in the registry just like normal MSCs don't land in the spec either without being accepted?

That would also avoid the clean-up step 12 months after the transport became stable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registries are outside of the spec, so they need their own mechanisms to track unstable prefixes.

* MSC4195 goes through normal review, and is eventually proposed for FCP (merge).
* MSC4195 succeeds at FCP and becomes accepted.
* A contributor opens a spec PR to register the `livekit` stable type. They also write a new section
on the registry's page with MSC4195's contents. That new section's anchor becomes the spec URL.

**Note**: If the MSC is detailed enough, a link to the rendered Markdown in the spec proposals repo
is probably suitable too.
Comment on lines +59 to +60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linking by SHA would be ok but linking by branch name (which is normally done for the [Rendered] links) would allow for further changes to the registry-spec without new MSCs. I think for stable transports, I'd prefer the registry to just contain the required spec text – just like the normal spec.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following the concern here, sorry - linking to a branch name to get live updates is the desired behaviour.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is that the registry itself should be stable. It shouldn't change unexpectedly without a release. Anything that aims to enter the registry requires an MSC. While the MSC is unstable / unmerged, the MSC alone is sufficient to coordinate any early implementations. We don't need to track unstable transports in the registry – just like we don't track unstable features in the Matrix spec itself.

* Upon that spec PR being merged, MSC4195 also becomes merged (per MSC process).
* A year later, a contributor removes the `msc4195.livekit` unstable type through a spec PR.

Mentioned in this proposal's introduction, this process does not prohibit a transport from entering
the core spec. Instead of the spec PR for MSC4195 (for example) being an added section on the registry's
page, it would be somewhere within the core spec. The registry would then link to that versioned
section. Transports which intend to enter the core spec MUST declare that in their proposals - the
default assumption is that transports will not enter the core spec.

### Transport discovery

Some RTC transports might require server-side infrastructure such as SFUs and TURN servers. Clients
need a mechanism to discover the availability of such infrastructure and any potentially required
connection details. To enable this, a new authenticated, rate limited, and guest accessible endpoint
Comment thread
turt2live marked this conversation as resolved.
Comment thread
turt2live marked this conversation as resolved.
is added to the Client-Server API (core spec):

```json5
// GET /_matrix/client/v1/rtc/transports
// 200 OK
{
"rtc_transports": [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rename this to just transports for parity with the m.rtc.member events from #4143.

{
"type": "{transport_type}",
... // Further transport-specific properties (if required)
}
]
}
```

`rtc_transports` is required and MUST be an array of objects with at least a registered `type`. Types
Comment thread
turt2live marked this conversation as resolved.
not in the registry are not permitted. Additional properties/schema are as per the specification for
the `type`.

### Exception: MSC4195

Because MSC4195 has been used to test the unstable implementation of MSC4143 and has no unstable
prefixes itself, `livekit` is registered as an unstable type instead of `msc4195.livekit`. When
MSC4195 becomes accepted, its type is to be upgraded to `stable` with relevant changes to the spec
link. No implementation changes would be required outside what they'd need to do to support MSC4143
becoming stable itself.
Comment on lines +98 to +104

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this rather move into #4195? Otherwise both MSCs mutually depend on each other?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This MSC is better positioned to state the namespacing requirements. Stating them in this way doesn't create a dependency on MSC4195 - it's just saying "if/when MSC4195 enters the registry, it uses this type".



## Potential issues

See MSC4518 for potential issues with registries.

Transports are not expected to be proposed often, so the regular MSC process should support the
registry well. Most transports would have tried to enter the core specification anyway, which
would generate MSCs. Per MSC4518, the team which reviews additions/changes/removals to the registry
can change at any time through another MSC.


## Alternatives

See MSC4518 for alternatives to registries. In the case of MSC4195 (LiveKit Transport), the alternative
is effectively putting the dependency into the core spec for all implementations.

`.well-known` was considered for the transport discovery endpoint, but as a traditionally unauthenticated
endpoint it doesn't fit infrastructure requirements for some transports. Well-Known URLs are often not
served by the homeserver (which would have transport information), but rather a different web server,
making populating the resource much harder. Authentication further allows for user-specific transports.


## Security considerations

Individual transports are expected to have their own security considerations. The presence of a
registry does not carry inherent security challenges, per MSC4518.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue that they very much do since they offer a way for protocol to become spec with little or no review.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The review requirements are the same as any other MSC, so I'm not sure that holds true. It's also not a Security Consideration, but would rather be a Potential Issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a transport is added to the registry as soon as an MSC is created for it, doesn't that mean it's fair game to start using it as soon as you've created an MSC, regardless of whether anyone has looked at the MSC?



## Unstable prefix

Registries do not have an effective unstable prefix. To assist in editorial ease however, this
proposal's registry can be implemented as an added section in the [appendices](https://spec.matrix.org/v1.19/appendices/).
Comment thread
turt2live marked this conversation as resolved.
Later, when either more proposals use registries or the infrastructure is easier to use, the section
would be moved out.

The `GET /_matrix/client/v1/rtc/transports` endpoint should be accessed as `GET /_matrix/client/unstable/org.matrix.msc4143/rtc/transports`
while this proposal is considered unstable. Note that the namespace is from MSC4143 - this is to
reflect the endpoint being lifted out of that proposal and into this one.


## Dependencies

This proposal depends on MSC4518 (Registries).

This proposal SHOULD NOT be accepted without MSC4143 (MatrixRTC) being accepted
concurrently. Note that MSC4143 also depends on this proposal.
Loading