pub struct ThresholdPolicy {
pub threshold: u8,
pub signers: Vec<String>,
pub policy_id: PolicyId,
pub scope: Option<Capability>,
pub ceremony_endpoint: Option<String>,
}Expand description
Policy for threshold signature operations (M-of-N).
This struct defines the parameters for FROST (Flexible Round-Optimized Schnorr Threshold) signature operations. FROST enables M-of-N threshold signing where at least M participants must cooperate to produce a valid signature, but no single participant can sign alone.
§Protocol Choice: FROST
FROST was chosen over alternatives for several reasons:
- Ed25519 native: Works with existing Ed25519 key infrastructure
- Round-optimized: Only 2 rounds for signing (vs 3+ for alternatives)
- Rust ecosystem:
frost-ed25519crate from ZcashFoundation is mature - Security: Proven secure under discrete log assumption
§Key Generation Approaches
Two approaches exist for generating threshold key shares:
-
Trusted Dealer: One party generates the key and distributes shares
- Simpler to implement
- Single point of failure during key generation
- Appropriate for org-controlled scenarios
-
Distributed Key Generation (DKG): Participants jointly generate key
- No single party ever sees the full key
- More complex, requires additional round-trips
- Better for trustless scenarios
§Integration with Auths
Threshold policies can be attached to high-value operations like:
sign-release: Release signing requires M-of-N approversrotate-keys: Key rotation requires multi-party approvalmanage-members: Adding admins requires quorum
§Example
let policy = ThresholdPolicy {
threshold: 2,
signers: vec![
"did:key:alice".to_string(),
"did:key:bob".to_string(),
"did:key:carol".to_string(),
],
policy_id: "release-signing-v1".to_string(),
scope: Some(Capability::sign_release()),
ceremony_endpoint: Some("wss://auths.example/ceremony".to_string()),
};
// 2-of-3: Any 2 of Alice, Bob, Carol can sign releases§Storage
Key shares are NOT stored in Git refs (they are secrets). Options:
- Platform keychain (macOS Keychain, Windows Credential Manager)
- Hardware security modules (HSMs)
- Secret managers (Vault, AWS Secrets Manager)
The policy itself (public info) is stored in Git at:
refs/auths/policies/threshold/<policy_id>
Fields§
§threshold: u8Minimum signers required (M in M-of-N)
signers: Vec<String>Total authorized signers (N in M-of-N) - DIDs of participants
policy_id: PolicyIdUnique identifier for this policy
scope: Option<Capability>Scope of operations this policy covers (optional)
ceremony_endpoint: Option<String>Ceremony coordination endpoint (e.g., WebSocket URL for signing rounds)
Implementations§
Trait Implementations§
Source§impl Clone for ThresholdPolicy
impl Clone for ThresholdPolicy
Source§fn clone(&self) -> ThresholdPolicy
fn clone(&self) -> ThresholdPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ThresholdPolicy
impl Debug for ThresholdPolicy
Source§impl<'de> Deserialize<'de> for ThresholdPolicy
impl<'de> Deserialize<'de> for ThresholdPolicy
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for ThresholdPolicy
Source§impl PartialEq for ThresholdPolicy
impl PartialEq for ThresholdPolicy
Source§fn eq(&self, other: &ThresholdPolicy) -> bool
fn eq(&self, other: &ThresholdPolicy) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for ThresholdPolicy
impl Serialize for ThresholdPolicy
impl StructuralPartialEq for ThresholdPolicy
Auto Trait Implementations§
impl Freeze for ThresholdPolicy
impl RefUnwindSafe for ThresholdPolicy
impl Send for ThresholdPolicy
impl Sync for ThresholdPolicy
impl Unpin for ThresholdPolicy
impl UnsafeUnpin for ThresholdPolicy
impl UnwindSafe for ThresholdPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.