Skip to main content

common/mount/
principal.rs

1//! # Principals
2//!
3//! Principals represent identities (public keys) with permissions on a bucket.
4//!
5//! Each principal has:
6//! - An **identity** (Ed25519 public key)
7//! - A **role** defining their access level ([`PrincipalRole`])
8//!
9//! ## Trust Model
10//!
11//! There is no cryptographic enforcement of roles. Role-based access control
12//! is enforced by clients validating bucket updates against the prior state.
13//! Only add principals you trust.
14//!
15//! ## Shares
16//!
17//! Principals may have an associated [`SecretShare`](crate::crypto::SecretShare)
18//! allowing them to decrypt bucket content. The share is stored separately in
19//! [`Share`](super::Share), not in the [`Principal`] struct itself.
20
21use serde::{Deserialize, Serialize};
22
23use crate::crypto::PublicKey;
24
25/// The role of a principal on a bucket.
26///
27/// Roles determine what operations a principal can perform and when they
28/// receive encryption access.
29#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
30pub enum PrincipalRole {
31    /// Full read/write access to the bucket.
32    ///
33    /// Owners:
34    /// - Always have an encrypted [`SecretShare`](crate::crypto::SecretShare)
35    /// - Can modify bucket contents (add, remove, move files)
36    /// - Can add/remove other principals
37    /// - Can publish the bucket to grant mirror access
38    Owner,
39
40    /// Read-only access after publication.
41    ///
42    /// Mirrors:
43    /// - Can sync bucket data (encrypted blobs) at any time
44    /// - Cannot decrypt content until the bucket is published
45    /// - Once published, read the plaintext secret from the manifest
46    /// - Cannot modify bucket contents
47    /// - Useful for CDN/gateway nodes that serve published content
48    Mirror,
49}
50
51impl std::fmt::Display for PrincipalRole {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        match self {
54            PrincipalRole::Owner => write!(f, "Owner"),
55            PrincipalRole::Mirror => write!(f, "Mirror"),
56        }
57    }
58}
59
60/// A principal identity on a bucket.
61///
62/// The principal struct contains the identity and role, but not the encryption
63/// share. Shares are stored separately in [`Share`](super::Share) to allow
64/// mirrors to exist without shares until publication.
65#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
66pub struct Principal {
67    /// The principal's access level.
68    pub role: PrincipalRole,
69    /// The principal's Ed25519 public key.
70    pub identity: PublicKey,
71}