mirror of
https://github.com/logos-messaging/chat_proto.git
synced 2026-01-03 05:23:08 +00:00
make inbox protocol part of core
This commit is contained in:
parent
270b97210a
commit
16dbe448f5
@ -3,6 +3,21 @@ syntax = "proto3";
|
||||
package umbra.base;
|
||||
|
||||
import "proto/umbra/encryption.proto";
|
||||
import "proto/umbra/invite.proto";
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Protocol Frames
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
message InboxV1Frame {
|
||||
string recipient = 1;
|
||||
// string conversation_type = 2;
|
||||
oneof frame_type {
|
||||
invite.InvitePrivateV1 invite_private_v1 = 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SDS Payloads
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package umbra.convos.inbox;
|
||||
|
||||
import "proto/umbra/conversations/private_v1.proto";
|
||||
|
||||
|
||||
// Specification: [TODO]
|
||||
|
||||
message InboxV1Frame {
|
||||
string recipient = 1;
|
||||
// string conversation_type = 2;
|
||||
oneof frame_type {
|
||||
convos.private_v1.ConversationInvite_PrivateV1 invite_private_v1 = 10;
|
||||
}
|
||||
}
|
||||
7
proto/umbra/invite.proto
Normal file
7
proto/umbra/invite.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package umbra.invite;
|
||||
|
||||
message InvitePrivateV1 {
|
||||
string participants = 1;
|
||||
}
|
||||
@ -28,9 +28,9 @@ fn main() {
|
||||
&[
|
||||
"proto/umbra/base.proto",
|
||||
"proto/umbra/common_frames.proto",
|
||||
"proto/umbra/encryption.proto",
|
||||
"proto/umbra/conversations/inbox_v1.proto",
|
||||
"proto/umbra/conversations/private_v1.proto",
|
||||
"proto/umbra/encryption.proto",
|
||||
"proto/umbra/invite.proto",
|
||||
],
|
||||
// set proto_path
|
||||
&[get_proto_dir().to_str().unwrap()],
|
||||
|
||||
@ -6,11 +6,8 @@ use prost::Message;
|
||||
pub use types::umbra::*;
|
||||
|
||||
use crate::{
|
||||
base::{EncryptedBytes, UmbraEnvelopeV1},
|
||||
convos::{
|
||||
inbox::{InboxV1Frame, inbox_v1_frame},
|
||||
private_v1::{PrivateV1Frame, private_v1_frame},
|
||||
},
|
||||
base::{EncryptedBytes, InboxV1Frame, UmbraEnvelopeV1, inbox_v1_frame},
|
||||
convos::private_v1::{PrivateV1Frame, private_v1_frame},
|
||||
};
|
||||
|
||||
impl PrivateV1Frame {
|
||||
|
||||
112
specs/conversations.md
Normal file
112
specs/conversations.md
Normal file
@ -0,0 +1,112 @@
|
||||
---
|
||||
title: CONVERSATIONS
|
||||
name: Conversation based communications
|
||||
category: Standards Track
|
||||
status: raw
|
||||
tags: chat
|
||||
editor: Jazz Alyxzander<jazz@status.im>
|
||||
contributors:
|
||||
---
|
||||
## Abstract
|
||||
|
||||
This specification outlines the base message structure for the Conversations protocol.
|
||||
|
||||
## Background / Rationale / Motivation
|
||||
|
||||
Modern communication systems require a reliable and flexible way to establish and manage conversations between participants.
|
||||
While simple message-passing protocols exist, they lack the ability to manage state across a stream of messages.
|
||||
|
||||
The Conversations Protocol addresses this gap by providing a clear and standardized way for participants to initiate, conversations in decentralized environments.
|
||||
|
||||
|
||||
|
||||
## Theory / Semantics
|
||||
|
||||
[TODO: remove this link, by sumamrizing and embedding in the spec so its standalone]
|
||||
This is a lightweight framework for defining Conversation micro-protocols.
|
||||
The high level Conversations approach outlined [here](https://forum.vac.dev/t/chatsdk-conversations/509).
|
||||
The intention is to provide the minimal building blocks for a wide range of micro-protocols, while allowing ConversationTypes to remain as flexible as possible.
|
||||
|
||||
|
||||
### Conversations
|
||||
A conversation is responsible for defining its encryption, encoding, and message types which are necessary for operation.
|
||||
|
||||
A ConversationType MUST define which content topics are valid places to receive messages.
|
||||
A ConversationType MUST define which encryption scheme is used
|
||||
A ConversationType MUST define which Frames are valid.
|
||||
- Clients MUST be able to decode frames deterministically.
|
||||
|
||||
A ConversationType SHOULD define membership requirements and limitations.
|
||||
|
||||
Every Conversation instance MUST have a conversation_id.
|
||||
|
||||
|
||||
**Decoding**
|
||||
Clients determine how to decode a byte sequence by the `conversation_id`.
|
||||
|
||||
[TODO: Should we add more guidance later? e,g /<convo_type>/<version>/<ident>]
|
||||
`conversation_id's` must be uniquely identify which encryption state to. As there may be many ConversationTypes defined, specifications should be mindful of conflicts.
|
||||
|
||||
Clients only accepts envelopes with known `conversation_id's`. All others can be discarded as there is insufficient information to properly decrypt/decode the messages.
|
||||
|
||||
|
||||
**Framing**
|
||||
To maintain a deterministic decoding tree, all frames on the wire MUST be wrapped with a `UmbraEnvelope`.
|
||||
This provides a common type for all frames.
|
||||
|
||||
Underneath UmbraEnvelope, ConversationTypes are free to wrap frames as desired, however it is recommended to use `EncryptedFrame` to ensure clients can decode messages regardless of software version.
|
||||
|
||||
|
||||
**Conversation Hinting**
|
||||
[TODO: Needs lots of work]
|
||||
Conversation identifiers (conversation_id) have the potential to leak sensitive metadata if exposed in cleartext. Frames sharing the same conversation_id could allow observers to infer social graph relationships, user activity patterns, or conversation linkage, depending on how conversation_id values are used by the specific ConversationType.
|
||||
|
||||
To mitigate this risk and provide a safer default for Conversation implementors, conversation_id values SHOULD be obscured in a way that prevents observers from linking frames belonging to the same conversation.
|
||||
|
||||
[TODO: Ratcheting Private Identifiers]
|
||||
|
||||
|
||||
|
||||
### Default Inbox
|
||||
To provide a baseline for interaction, clients need a method to receive initial frames/invites. To achieve this all clients MUST implement a default Inbox with `inbox_address = HASH(client_address)`. [TODO: Define hash here, or embed as part of the Inbox spec]
|
||||
|
||||
See [Inbox](./inbox.md) for more information.
|
||||
|
||||
|
||||
## Wire Format Specification / Syntax
|
||||
|
||||
The wire format is specified using protocol buffers v3.
|
||||
|
||||
```mermaid
|
||||
|
||||
message UmbraEnvelopeV1 {
|
||||
|
||||
string conversation_hint = 1;
|
||||
uint32 salt = 2;
|
||||
|
||||
EncryptedBytes encrypted_bytes = 10;
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Implementation Suggestions (optional)
|
||||
An optional *implementation suggestions* section may provide suggestions on how to approach implementation details, and,
|
||||
if available, point to existing implementations for reference.
|
||||
|
||||
|
||||
## (Further Optional Sections)
|
||||
|
||||
|
||||
## Security/Privacy Considerations
|
||||
[TODO: cover Conversation_id -> Message Types ]
|
||||
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
A list of references.
|
||||
@ -1,145 +0,0 @@
|
||||
---
|
||||
title: BASE
|
||||
name: Base type framework for the Umbra Protocol
|
||||
category: Standards Track
|
||||
status: raw
|
||||
tags: chat
|
||||
editor: Jazz Alyxzander<jazz@status.im>
|
||||
contributors:
|
||||
---
|
||||
## Abstract
|
||||
|
||||
This specification outlines the base message structure for the ChatSDK protocol.
|
||||
|
||||
## Background / Rationale / Motivation
|
||||
When a client detects a new encrypted message it must determine how to decrypt it.
|
||||
It is desired that clients can determine if they are the intended recipient without inferring this from successful decryption. This leads to lost messages with no indication of a problem, such as an out of date client.
|
||||
|
||||
One of the most difficult problems in decentralized messaging is managing breaking changes between independent clients. As clients are not always running the latest version they cannot always successfully parse new message types.
|
||||
|
||||
|
||||
## Theory / Semantics
|
||||
|
||||
|
||||
The generic structure of the protocol types follows the Conversations approach outlined [here](https://forum.vac.dev/t/chatsdk-conversations/509).
|
||||
The intention is to provide consistent data encapsulation for a wide range of micro-protocols.
|
||||
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A((On Receive)) --> E(Envelope)
|
||||
|
||||
E --> EB(EncryptedBytes)
|
||||
|
||||
EB -->|decrypt based on Envelope.Hint| CH{ConversationId?}
|
||||
|
||||
CH --> PF
|
||||
CH --> GF
|
||||
PF(PrivateV1Frame) --> CO(Content)
|
||||
PF --> Example:Reset
|
||||
GF(GroupV1Frame) --> CO(Content)
|
||||
GF --> Example:KeyRotation
|
||||
|
||||
```
|
||||
|
||||
|
||||
### UmbraEnvelope
|
||||
|
||||
The root of the parsing tree is the 'envelope'.
|
||||
Its primary role is to aid with payload discovery, which provides a hint as to whether this payload is of interest to the client.
|
||||
|
||||
One approach to do this privately is to include the conversation_id in a wrapping payload which is asymmetrically encrypted using the recipients public_key. This is undesirable for a few reasons:
|
||||
- Decryption Inefficiency: The message contents are already encrypted, which results in clients having to decrypt twice.
|
||||
- Encryption Failure Ambiguity: Clients cannot detect payload errors. This is because decryption faults are indistinguishable from messages intended for another client.
|
||||
- Poor Scaling: Requiring messages be encrypted per client, conflicts with more efficient payload generation techniques like conversation based addressing.
|
||||
|
||||
Another way is to provide a conversation hint in cleartext, however obscured to stop casual observers from attributing messages to conversations.
|
||||
- Hash(Conversation_id + Salt)
|
||||
- Hash stops casual observers from associating messages to a conversation
|
||||
- Salt produces a different output for
|
||||
|
||||
[TODO: Define Conversation hint]
|
||||
[TODO: Highlight privacy impacts]
|
||||
|
||||
The data contained here is public and has privacy implications, careful consideration is required.
|
||||
|
||||
|
||||
|
||||
### EncryptedBytes
|
||||
|
||||
The EncryptedBytes message is a self-describing wrapper for all encrypted payloads. As the protocol grows it will include potentially different encryption mechanisms. This message type makes no assumptions about the encryption used an allows new conversation types to use the same messaging framework.
|
||||
|
||||
|
||||
[TODO: Why isn't this defined within the conversation frames like SDS?]
|
||||
|
||||
|
||||
|
||||
## Wire Format Specification / Syntax
|
||||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,
|
||||
“NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
|
||||
|
||||
This section SHOULD not contain explanations of semantics and focus on concisely defining the wire format.
|
||||
Implementations SHOULD adhere to these exact formats to interoperate with other implementations.
|
||||
It is fine, if parts of the previous section that touch on the wire format are repeated.
|
||||
The purpose of this section is having a concise definition of what an implementation sends and accepts.
|
||||
Parts that are not specified here are considered implementation details.
|
||||
Implementors are free to decide on how to implement these details.
|
||||
|
||||
|
||||
The wire format is specified using protocol buffers v3.
|
||||
|
||||
```mermaid
|
||||
|
||||
message UmbraEnvelopeV1 {
|
||||
|
||||
string conversation_hint = 1;
|
||||
uint32 nonce = 2;
|
||||
|
||||
EncryptedBytes encrypted_bytes = 100;
|
||||
}
|
||||
|
||||
message EncryptedBytes {
|
||||
|
||||
oneof encryption {
|
||||
bytes encrypted_bytes=1;
|
||||
Plaintext plaintext = 2;
|
||||
Ecies ecies = 3;
|
||||
}
|
||||
|
||||
|
||||
message Ecies {
|
||||
bytes encrypted_bytes=1;
|
||||
bytes ephemeral_pubkey = 2;
|
||||
bytes tag = 3;
|
||||
|
||||
}
|
||||
|
||||
message Plaintext {
|
||||
bytes payload=1;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Implementation Suggestions (optional)
|
||||
An optional *implementation suggestions* section may provide suggestions on how to approach implementation details, and,
|
||||
if available, point to existing implementations for reference.
|
||||
|
||||
|
||||
## (Further Optional Sections)
|
||||
|
||||
|
||||
## Security/Privacy Considerations
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
A list of references.
|
||||
120
specs/inbox.md
Normal file
120
specs/inbox.md
Normal file
@ -0,0 +1,120 @@
|
||||
---
|
||||
title: INBOX
|
||||
name: Inbound messages
|
||||
category: Standards Track
|
||||
status: raw
|
||||
tags: chat
|
||||
editor: Jazz Alyxzander<jazz@status.im>
|
||||
contributors:
|
||||
---
|
||||
## Abstract
|
||||
|
||||
|
||||
## Background / Rationale / Motivation
|
||||
|
||||
|
||||
|
||||
## Theory / Semantics
|
||||
|
||||
Inboxes are inbound only conversation types, which allow a client to recieve messages from contacts.
|
||||
An inbox does not have a defined set of participants, and is used to receive messages when there does not exist and established channel between contacts.
|
||||
All messages to an inbox MUST be encrypted. [TODO: Reason]
|
||||
|
||||
### Accepted types
|
||||
Inboxes SHOULD attempt to handle all envelopes sent with the conversation_id `/inbox/v1/<inbox_address>`.
|
||||
|
||||
### Default Inbox
|
||||
|
||||
[Differentiate between Inbox the place you recieve and the Protocol -- Is htere a difference]
|
||||
An inbox is the default conversation type.
|
||||
It is a catch-all for all messages which
|
||||
|
||||
|
||||
|
||||
[TODO: is domain separation needed here or should we save some bytes?]
|
||||
|
||||
|
||||
**Encryption**
|
||||
|
||||
All Frames sent to the INBOX must be encrypted.
|
||||
|
||||
Frames CAN be encrypted
|
||||
|
||||
**Content Topic**
|
||||
|
||||
// TODO: Inbox Topics will be defined in ContactBundles, allowing for dynamic topic usage
|
||||
|
||||
All clients must listen for messages posted with the content topic `/inbox/<inbox_address>`
|
||||
|
||||
### Invites
|
||||
Conversations are required to define their own Invites, which contain the required information to bootstrap new participants.
|
||||
|
||||
|
||||
[TODO: InviteV1]
|
||||
|
||||
### EncryptedBytes
|
||||
|
||||
The EncryptedBytes message is a self-describing wrapper for all encrypted payloads. As the protocol grows it will include potentially different encryption mechanisms. This message type makes no assumptions about the encryption used an allows new conversation types to use the same messaging framework.
|
||||
|
||||
|
||||
[TODO: Why isn't this defined within the conversation frames like SDS?]
|
||||
|
||||
|
||||
|
||||
### Invites
|
||||
|
||||
Individual Conversations are responsible for defining a payload which will be used to initialize remote participants.
|
||||
|
||||
#### Invite Encryption
|
||||
|
||||
Invite
|
||||
|
||||
|
||||
|
||||
|
||||
## Wire Format Specification / Syntax
|
||||
The wire format is specified using protocol buffers v3.
|
||||
|
||||
```mermaid
|
||||
|
||||
message EncryptedBytes {
|
||||
|
||||
oneof encryption {
|
||||
bytes encrypted_bytes=1;
|
||||
Plaintext plaintext = 2;
|
||||
Ecies ecies = 3;
|
||||
}
|
||||
|
||||
|
||||
message Ecies {
|
||||
bytes encrypted_bytes=1;
|
||||
bytes ephemeral_pubkey = 2;
|
||||
bytes tag = 3;
|
||||
|
||||
}
|
||||
|
||||
message Plaintext {
|
||||
bytes payload=1;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Implementation Suggestions (optional)
|
||||
An optional *implementation suggestions* section may provide suggestions on how to approach implementation details, and,
|
||||
if available, point to existing implementations for reference.
|
||||
|
||||
|
||||
## (Further Optional Sections)
|
||||
|
||||
|
||||
## Security/Privacy Considerations
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
A list of references.
|
||||
Loading…
x
Reference in New Issue
Block a user