pub struct GroupMembership {
pub identity_info: BTreeMap<IdentityRef, IdentityInfo>,
pub identity_roles: BTreeMap<IdentityRef, GroupRole>,
}Expand description
Advanced identity and membership management for distributed groups.
GroupMembership handles the complex identity scenarios that arise in distributed,
encrypted group communication. It separates cryptographic identity (via
zoe_wire_protocol::VerifyingKey) from display identity (names, aliases).
§🎭 Identity Architecture
The system operates on a two-layer identity model:
§Layer 1: Cryptographic Identity (VerifyingKeys)
- Each participant has one or more
zoe_wire_protocol::VerifyingKeys - These keys are used for message signing and verification
- Keys are the fundamental unit of authentication and authorization
- A key represents a device, account, or cryptographic identity
§Layer 2: Display Identity (Aliases and Names)
- Each key can declare multiple
crate::IdentityTypevariants:- Main Identity: The primary identity for a key (often a real name)
- Aliases: Secondary identities for role-playing, privacy, or context
- Each identity can have associated
crate::IdentityInfowith display names - Identities are what users see and interact with in the UI
§🔄 Use Cases and Benefits
§Privacy and Pseudonymity
VerifyingKey(Alice_Device_1) ──┬─→ Main: "Alice Johnson"
├─→ Alias: "ProjectLead"
└─→ Alias: "AnonymousReviewer"Alice can participate in the same group with different personas:
- Official communications as “Alice Johnson”
- Project management as “ProjectLead”
- Anonymous feedback as “AnonymousReviewer”
§Multi-Device Identity
Real Person: Bob ──┬─→ VerifyingKey(Bob_Phone) ─→ Main: "Bob Smith"
└─→ VerifyingKey(Bob_Laptop) ─→ Main: "Bob Smith"Bob can use multiple devices with the same display identity.
§Role-Based Communication
VerifyingKey(Company_Bot) ──┬─→ Alias: "HR Bot"
├─→ Alias: "Security Alert System"
└─→ Alias: "Meeting Scheduler"Automated systems can present different faces for different functions.
§🔒 Security and Authorization
§Key-Based Authorization
- All permissions and role assignments are tied to
IdentityRefvariants - An
IdentityRef::Keydirectly authorizes the key holder - An
IdentityRef::Aliasauthorizes only if the key controls that alias - Use
GroupMembership::is_authorizedto check if a key can act as an identity
§Self-Sovereign Identity Declaration
- Only a key can declare identities for itself
- Other participants cannot assign aliases to someone else’s key
- Identity information is cryptographically signed by the declaring key
- Malicious identity claims are prevented by signature verification
§📊 Data Structure
§Identity Storage
GroupMembership::identity_info: Maps(VerifyingKey, IdentityType) → IdentityInfo- Stores display names and metadata for each declared identity
- Multiple identities per key are fully supported
§Role Assignments
GroupMembership::identity_roles: MapsIdentityRef → GroupRole- Roles can be assigned to specific identities, not just keys
- Enables fine-grained permission control per identity
§🔧 Core Operations
§Identity Discovery
GroupMembership::get_available_identities: Find all identities a key can useGroupMembership::get_display_name: Get human-readable name for an identityGroupMembership::has_identity_info: Check if identity has been declared
§Role Management
GroupMembership::get_role: Get the role assigned to a specific identityGroupMembership::get_effective_role: Get role when key acts as an alias- Roles default to
super::events::roles::GroupRole::Memberif not explicitly set
§💡 Usage Examples
§Setting Up Multiple Identities
use zoe_app_primitives::{GroupMembership, IdentityType, IdentityRef, IdentityInfo};
use zoe_wire_protocol::KeyPair;
use std::collections::HashMap;
let mut membership = GroupMembership::new();
let alice_key = KeyPair::generate(&mut rand::rngs::OsRng).public_key();
// Alice declares her main identity
let main_identity = IdentityInfo {
display_name: "Alice Johnson".to_string(),
metadata: vec![],
};
// Alice declares an alias for anonymous feedback
let anon_identity = IdentityInfo {
display_name: "Anonymous Reviewer".to_string(),
metadata: vec![],
};
// In practice, these would be set via GroupManagementEvent::SetIdentity
// Here we simulate the result of processing those events
membership.identity_info.insert(
IdentityRef::Key(alice_key.clone()),
main_identity,
);
membership.identity_info.insert(
IdentityRef::Alias { key: alice_key, alias: "anon".to_string() },
anon_identity,
);§Checking Authorization
// Check if Alice can act as her main identity (always true)
let main_ref = IdentityRef::Key(alice_key.clone());
assert!(membership.is_authorized(&alice_key, &main_ref));
// Check if Alice can act as her anonymous alias
let alias_ref = IdentityRef::Alias {
key: alice_key.clone(),
alias: "anon".to_string(),
};
assert!(membership.is_authorized(&alice_key, &alias_ref));
// Check if Alice can act as someone else's alias (false)
let other_key = KeyPair::generate(&mut rand::rngs::OsRng).public_key();
let other_alias = IdentityRef::Alias {
key: other_key,
alias: "not_alice".to_string(),
};
assert!(!membership.is_authorized(&alice_key, &other_alias));§Role-Based Access with Identities
// Assign admin role to Alice's main identity
let main_ref = IdentityRef::Key(alice_key.clone());
membership.identity_roles.insert(main_ref.clone(), GroupRole::Admin);
// Assign member role to Alice's anonymous alias
let alias_ref = IdentityRef::Alias {
key: alice_key,
alias: "anon".to_string(),
};
membership.identity_roles.insert(alias_ref.clone(), GroupRole::Member);
// Check effective roles
assert_eq!(
membership.get_role(&main_ref),
Some(GroupRole::Admin)
);
assert_eq!(
membership.get_role(&alias_ref),
Some(GroupRole::Member)
);§🌐 Integration with Group Events
Identity management integrates with the event system through:
super::events::GroupActivityEvent::SetIdentity: Declares new identitiessuper::events::GroupActivityEvent::AssignRole: Assigns roles to identities- Event processing updates the membership state automatically
- All identity changes are part of the signed, encrypted event history
This ensures that identity management is:
- Auditable: Full history of identity changes
- Consistent: Same view across all group members
- Secure: Cryptographically signed and verified
Fields§
§identity_info: BTreeMap<IdentityRef, IdentityInfo>Identity information for keys and their aliases: (key_bytes, identity_type) -> identity_info Keys are ML-DSA verifying keys encoded as bytes for serialization compatibility
identity_roles: BTreeMap<IdentityRef, GroupRole>Role assignments for identities (both keys and aliases)
Implementations§
Source§impl GroupMembership
impl GroupMembership
Check if a verifying key is authorized to act as a specific identity
Sourcepub fn get_available_identities(
&self,
_key: &VerifyingKey,
) -> HashSet<IdentityRef>
pub fn get_available_identities( &self, _key: &VerifyingKey, ) -> HashSet<IdentityRef>
Get all identities that a verifying key can act as
Sourcepub fn get_role(&self, identity_ref: &IdentityRef) -> Option<GroupRole>
pub fn get_role(&self, identity_ref: &IdentityRef) -> Option<GroupRole>
Get the role for a specific identity
Sourcepub fn get_effective_role(
&self,
_key: &VerifyingKey,
_acting_as_alias: &Option<String>,
) -> Option<GroupRole>
pub fn get_effective_role( &self, _key: &VerifyingKey, _acting_as_alias: &Option<String>, ) -> Option<GroupRole>
Get effective role when a key acts as a specific identity
Sourcepub fn get_display_name(
&self,
key: &VerifyingKey,
identity_type: &IdentityType,
) -> String
pub fn get_display_name( &self, key: &VerifyingKey, identity_type: &IdentityType, ) -> String
Get display name for an identity
Sourcepub fn has_identity_info(
&self,
_key: &VerifyingKey,
_identity_type: &IdentityType,
) -> bool
pub fn has_identity_info( &self, _key: &VerifyingKey, _identity_type: &IdentityType, ) -> bool
Check if an identity has been declared by a key
Trait Implementations§
Source§impl Clone for GroupMembership
impl Clone for GroupMembership
Source§fn clone(&self) -> GroupMembership
fn clone(&self) -> GroupMembership
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more