Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
78 changes: 78 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ confirmation closes that invite. The inviter
should stay online briefly so existing members can learn about newly joined
devices through one-hop introductions. Use `entangle group list`,
`entangle group members <name>`, and `entangle group leave <name>` to inspect
or leave groups. A second Entangle server using the same data directory gets
a temporary ID while the first server is running. See
or leave groups. Human admins can run `entangle group remove <group> <member>`
to remove a member and rotate the key, `entangle group rekey <group>` to
rotate without changing membership, and `entangle group admin <group> <member>`
to hand off administration. A second Entangle server using the same data
directory gets a temporary ID while the first server is running. See
[docs/SETUP.md](docs/SETUP.md) for group setup, firewall, client configuration,
and a two-machine smoke test.

Expand All @@ -82,8 +85,9 @@ The standalone commands are `entangle serve` (default), `entangle node`, and
## Design and security

The crate boundaries, message flow, wire format, and security limitations are
documented in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Protocol version 4
uses group-bound Noise links; all devices must share a group to communicate.
documented in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Protocol version 5
uses epoch-bound, group-authenticated Noise links with signed membership
updates; all devices must share a group to communicate.

## License

Expand Down
34 changes: 33 additions & 1 deletion crates/entangle-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{fmt, path::Path};
pub mod sas;

/// Current version of the Entangle control protocol.
pub const PROTOCOL_VERSION: u32 = 4;
pub const PROTOCOL_VERSION: u32 = 5;

/// A process-unique particle identity rendered as 32 lowercase hexadecimal digits.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
Expand All @@ -20,10 +20,42 @@ pub struct Member {
pub particle_id: String,
pub name: String,
pub static_key: String,
pub sign_key: String,
pub added_by: String,
pub added_at: String,
}

/// A signed group membership and key update.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct GroupUpdate {
pub group_id: String,
pub epoch: u32,
pub key_hex: String,
pub admin: String,
pub admin_sign_key: String,
pub revoked: Vec<Revocation>,
pub kind: UpdateKind,
pub issued_by: String,
pub issued_at: String,
pub signature: String,
}

/// A member removed from a group, bound to the static key that was revoked.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Revocation {
pub particle_id: String,
pub static_key: String,
}

/// The operation represented by a signed group update.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum UpdateKind {
Remove { particle_id: String },
Rekey,
AdminHandoff { to: String },
}

impl ParticleId {
/// Creates a fresh identity using the OS random number generator; callers may persist it.
pub fn generate() -> Self {
Expand Down
Loading
Loading