Skip to content

Conversation

@weboko
Copy link
Contributor

@weboko weboko commented Oct 12, 2025

TBD, not for review yet

This is draft of a spec for WebRTC Signaling over Waku.

Implementation in logos-messaging/js-waku#2677

Copy link
Contributor

@fryorcraken fryorcraken left a comment

Choose a reason for hiding this comment

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

Very exciting.

It looks pretty much decentralized to me.

The spec is very verbose tho, and propose too many "options".

I'd KISS and describe the simplest option.

You can then have a "Future" section that lays out other potential designs

Comment on lines +75 to +77
The Waku WebRTC Signaling Protocol defines a method for two peers in a Waku network to establish a direct WebRTC peer-to-peer connection. It leverages Waku as a decentralized signaling channel (in place of a traditional centralized WebRTC signaling server) to exchange the necessary handshake messages (SDP offers/answers and ICE candidates) for setting up a WebRTC connection. This protocol is application-agnostic – it can be used to set up connections for any purpose (e.g. audio calls, video calls, real-time data exchange, collaborative applications) without being tied to a specific calling UI or workflow.

In this protocol, Waku is used only for signaling (control messages). Once the WebRTC connection is established, high-bandwidth or real-time data (media streams, data channel messages, etc.) flow directly between the peers over the WebRTC peer connection. This approach offloads traffic from the Waku network and allows low-latency, peer-to-peer communication, while Waku provides censorship-resistant and privacy-preserving rendezvous for initiating the connection.
Copy link
Contributor

Choose a reason for hiding this comment

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

feels redundant with the abstract


## Terminology

- **Peer / Participant**: A node or user participating in the protocol (each running a Waku client capable of WebRTC). In a given connection setup, one peer will act as the initiator (the one starting the WebRTC handshake) and the other as the responder (the one receiving a connection offer and answering it). These roles are per-session and not fixed; any peer may initiate a new connection to any other as long as both run the protocol.
Copy link
Contributor

Choose a reason for hiding this comment

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

Feels redundant, when you have a paragraph for initiator and responder just below.

- **Responder**: The peer that receives an offer and chooses whether to accept (answer) or refuse it (equivalent to “called party” in a call scenario).
- **Session**: A single WebRTC connection attempt (and, if accepted, the resulting WebRTC connection) between two peers. Each session is identified by a unique session ID generated by the initiator. All signaling messages related to that session carry this ID.
- **SDP**: Session Description Protocol, used in WebRTC to describe session capabilities (offers and answers).
- **ICE**: Interactive Connectivity Establishment, the mechanism for finding network paths between peers. Trickle ICE (as defined in RFC 8838) is used, meaning ICE candidates are exchanged incrementally as they are found, rather than all at once.
Copy link
Contributor

Choose a reason for hiding this comment

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

Link to RFC 8838

Signaling messages in this protocol are carried as Waku messages on a designated content topic. To facilitate targeted delivery and privacy, each peer **SHOULD** listen on a content topic specific to itself, and initiators **SHOULD** send signaling messages to the content topic associated with the intended responder. For example, an application **MAY** derive a peer-specific topic by incorporating the peer’s ID or a derivative of it. One simple scheme is:

```text
/waku-webrtc/1/<peer-id>/proto
Copy link
Contributor

Choose a reason for hiding this comment

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

Not great for privacy to expose the peer id.

Also, maybe better to not even re-use the peer id, and instead possibly just use a new identifier? Does it have to be the peer id?


Where `<peer-id>` is a representation of the target peer’s Waku/libp2p peer ID (e.g. a base58 or base32 encoding). Using such a scheme, each peer subscribes (or registers a filter) to their own topic (containing their ID) and will receive only signaling messages directed to them. The initiator can publish an Offer to the responder’s topic, and the responder’s Answer (or Reject) can be published to the initiator’s topic.

**Privacy considerations:** Directly using a unique identifier (like a full peer ID) in the content topic can potentially allow observers to correlate messages with a specific user, since Waku relay or filter nodes will see the content topic of messages. To mitigate this, implementations **MAY** employ strategies such as hashing the peer ID or using bucketed topics (e.g. using a prefix of a hash of the peer ID) so that multiple peers share the same content topic, increasing anonymity. Another approach is to simply use a single, shared content topic for all WebRTC signaling (as was done in the Waku Phone prototype), embedding addressing info inside the message payload. A unified topic maximizes anonymity (all peers’ signals look alike) at the cost of efficiency (all clients receive all offers and must filter them). The choice of content topic strategy should balance privacy, scalability, and simplicity for the given application. In any case, encryption (discussed below) is critical so that only the intended recipient can read the signaling content, regardless of topic structure.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. I'd suggest to start with a fix content topic at this point in time. We can extend to scale later.


Establishing a WebRTC connection involves exchanging sensitive information such as network addresses (ICE candidates can reveal IP addresses) and capabilities. Using Waku as the signaling transport provides a decentralized channel, but security measures must be taken:

- **Encryption:** All signaling messages **SHOULD** be encrypted so that only the intended peer can read them. Waku payload encryption (Message Version 1) supports both asymmetric (per-recipient public key) and symmetric encryption. For example, if peer A knows peer B’s Waku public key (identity key), A can encrypt the `OFFER` for B using asymmetric encryption (so only B can decrypt). B’s response can be encrypted to A’s public key. If exchanging public keys is not feasible, a shared symmetric key can be agreed upon (through a pre-shared secret or a Diffie-Hellman exchange via some other secure channel) and then used to encrypt/decrypt all messages for that session (or even for all sessions between A and B). Without encryption, an attacker observing Waku network traffic could glean who is trying to connect to whom (from content topics or meta-data) and read the SDP which could leak IP addresses or fingerprints. Thus, encryption is a **MUST** for privacy in most use cases.
Copy link
Contributor

Choose a reason for hiding this comment

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

You already mentioned encryption earlier, avoid redundancy and just mention it in this section.

Establishing a WebRTC connection involves exchanging sensitive information such as network addresses (ICE candidates can reveal IP addresses) and capabilities. Using Waku as the signaling transport provides a decentralized channel, but security measures must be taken:

- **Encryption:** All signaling messages **SHOULD** be encrypted so that only the intended peer can read them. Waku payload encryption (Message Version 1) supports both asymmetric (per-recipient public key) and symmetric encryption. For example, if peer A knows peer B’s Waku public key (identity key), A can encrypt the `OFFER` for B using asymmetric encryption (so only B can decrypt). B’s response can be encrypted to A’s public key. If exchanging public keys is not feasible, a shared symmetric key can be agreed upon (through a pre-shared secret or a Diffie-Hellman exchange via some other secure channel) and then used to encrypt/decrypt all messages for that session (or even for all sessions between A and B). Without encryption, an attacker observing Waku network traffic could glean who is trying to connect to whom (from content topics or meta-data) and read the SDP which could leak IP addresses or fingerprints. Thus, encryption is a **MUST** for privacy in most use cases.
- **Authentication:** The protocol as specified does not include an explicit authentication or verification step of the peers’ identity beyond knowing the peer ID/public key. If a Waku message is encrypted to a peer’s key, that provides assurance it came from someone with the corresponding private key (since only they could craft a message you can decrypt). However, peers should still be mindful of potential impersonation. Applications that require stronger identity verification may layer additional authentication (e.g., a challenge/response or signing the SDP).
Copy link
Contributor

Choose a reason for hiding this comment

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

is the peer id used for authentication at all? I do not see any signature being included.


- **Encryption:** All signaling messages **SHOULD** be encrypted so that only the intended peer can read them. Waku payload encryption (Message Version 1) supports both asymmetric (per-recipient public key) and symmetric encryption. For example, if peer A knows peer B’s Waku public key (identity key), A can encrypt the `OFFER` for B using asymmetric encryption (so only B can decrypt). B’s response can be encrypted to A’s public key. If exchanging public keys is not feasible, a shared symmetric key can be agreed upon (through a pre-shared secret or a Diffie-Hellman exchange via some other secure channel) and then used to encrypt/decrypt all messages for that session (or even for all sessions between A and B). Without encryption, an attacker observing Waku network traffic could glean who is trying to connect to whom (from content topics or meta-data) and read the SDP which could leak IP addresses or fingerprints. Thus, encryption is a **MUST** for privacy in most use cases.
- **Authentication:** The protocol as specified does not include an explicit authentication or verification step of the peers’ identity beyond knowing the peer ID/public key. If a Waku message is encrypted to a peer’s key, that provides assurance it came from someone with the corresponding private key (since only they could craft a message you can decrypt). However, peers should still be mindful of potential impersonation. Applications that require stronger identity verification may layer additional authentication (e.g., a challenge/response or signing the SDP).
- **Denial-of-Service (DoS):** Because this protocol is open (anyone can send an `OFFER` to a peer’s topic if they know the peer ID), there is potential for spam or DoS by flooding offers. Implementers should also consider local policies: e.g., rate-limit incoming offers, require some form of introduction or pre-shared contact to accept offers, etc. An implementation might mitigate this by screening offers (for example, only allow incoming from known peers or use a reputation system).
Copy link
Contributor

Choose a reason for hiding this comment

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

Just don't use the peer id.

- **Encryption:** All signaling messages **SHOULD** be encrypted so that only the intended peer can read them. Waku payload encryption (Message Version 1) supports both asymmetric (per-recipient public key) and symmetric encryption. For example, if peer A knows peer B’s Waku public key (identity key), A can encrypt the `OFFER` for B using asymmetric encryption (so only B can decrypt). B’s response can be encrypted to A’s public key. If exchanging public keys is not feasible, a shared symmetric key can be agreed upon (through a pre-shared secret or a Diffie-Hellman exchange via some other secure channel) and then used to encrypt/decrypt all messages for that session (or even for all sessions between A and B). Without encryption, an attacker observing Waku network traffic could glean who is trying to connect to whom (from content topics or meta-data) and read the SDP which could leak IP addresses or fingerprints. Thus, encryption is a **MUST** for privacy in most use cases.
- **Authentication:** The protocol as specified does not include an explicit authentication or verification step of the peers’ identity beyond knowing the peer ID/public key. If a Waku message is encrypted to a peer’s key, that provides assurance it came from someone with the corresponding private key (since only they could craft a message you can decrypt). However, peers should still be mindful of potential impersonation. Applications that require stronger identity verification may layer additional authentication (e.g., a challenge/response or signing the SDP).
- **Denial-of-Service (DoS):** Because this protocol is open (anyone can send an `OFFER` to a peer’s topic if they know the peer ID), there is potential for spam or DoS by flooding offers. Implementers should also consider local policies: e.g., rate-limit incoming offers, require some form of introduction or pre-shared contact to accept offers, etc. An implementation might mitigate this by screening offers (for example, only allow incoming from known peers or use a reputation system).
- **Privacy of Content Topics:** If using peer-specific content topics (as recommended for efficiency), note that the content topic itself reveals a link to a peer’s ID. A third-party node can see that someone is sending messages to `/waku-webrtc/1/<peer-id>/proto`. This could be used to infer that `<peer-id>` is active or being contacted. It can also link the initiator and responder if the timing of messages on their respective topics is observed. To reduce this metadata leakage, implementations can use the techniques mentioned (topic hashing/bucketing or a shared topic for all signals). Additionally, Waku’s Relay protocol (gossip) provides some recipient anonymity by not revealing to intermediate nodes exactly which peer is the recipient, whereas Filter/Store protocols require telling a server the topics of interest (hence revealing the peer’s content topic subscription). Using a generic content topic for all WebRTC signaling (and filtering at the client level by peer IDs inside the message) maximizes anonymity but at a performance cost.
Copy link
Contributor

Choose a reason for hiding this comment

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

just propose a unique content topic.

- **Authentication:** The protocol as specified does not include an explicit authentication or verification step of the peers’ identity beyond knowing the peer ID/public key. If a Waku message is encrypted to a peer’s key, that provides assurance it came from someone with the corresponding private key (since only they could craft a message you can decrypt). However, peers should still be mindful of potential impersonation. Applications that require stronger identity verification may layer additional authentication (e.g., a challenge/response or signing the SDP).
- **Denial-of-Service (DoS):** Because this protocol is open (anyone can send an `OFFER` to a peer’s topic if they know the peer ID), there is potential for spam or DoS by flooding offers. Implementers should also consider local policies: e.g., rate-limit incoming offers, require some form of introduction or pre-shared contact to accept offers, etc. An implementation might mitigate this by screening offers (for example, only allow incoming from known peers or use a reputation system).
- **Privacy of Content Topics:** If using peer-specific content topics (as recommended for efficiency), note that the content topic itself reveals a link to a peer’s ID. A third-party node can see that someone is sending messages to `/waku-webrtc/1/<peer-id>/proto`. This could be used to infer that `<peer-id>` is active or being contacted. It can also link the initiator and responder if the timing of messages on their respective topics is observed. To reduce this metadata leakage, implementations can use the techniques mentioned (topic hashing/bucketing or a shared topic for all signals). Additionally, Waku’s Relay protocol (gossip) provides some recipient anonymity by not revealing to intermediate nodes exactly which peer is the recipient, whereas Filter/Store protocols require telling a server the topics of interest (hence revealing the peer’s content topic subscription). Using a generic content topic for all WebRTC signaling (and filtering at the client level by peer IDs inside the message) maximizes anonymity but at a performance cost.
- **Ephemeral Signaling:** Signaling messages typically have short usefulness (only during call setup). It’s recommended to mark them as ephemeral (non-persistent) so that Waku nodes do not store them beyond a short time. This reduces the risk of someone later retrieving historical call attempts via the Store protocol. It also means if a peer was offline during a call attempt, they might never see the offer (which is acceptable, akin to a “missed call”). If an application did want a “missed connection” notification, it could deliberately not mark the message ephemeral; but this should be weighed against privacy. In most cases, real-time connections should be ephemeral.
Copy link
Contributor

Choose a reason for hiding this comment

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

This reduces the risk of someone later retrieving historical call attempts via the Store protoco

How can they do that if it's encrypted?

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.

3 participants