miden_standards/account/access/mod.rs
1use alloc::vec;
2
3use miden_protocol::account::{AccountComponent, AccountId, RoleSymbol};
4
5pub mod authority;
6pub mod ownable2step;
7pub mod pausable;
8pub mod rbac;
9
10/// Access control configuration for account components.
11///
12/// Each variant expands into the set of [`AccountComponent`]s that implement that access
13/// control choice **plus** the matching [`Authority`] component. The [`Authority`] is
14/// auto-yielded so callers don't need to remember to install it separately and so that the
15/// authority discriminator stays in sync with the chosen access mode.
16///
17/// - [`AccessControl::AuthControlled`] yields just [`Authority::AuthControlled`].
18/// - [`AccessControl::Ownable2Step`] yields [`Ownable2Step`] + [`Authority::OwnerControlled`].
19/// - [`AccessControl::Rbac`] yields [`Ownable2Step`] + [`RoleBasedAccessControl`] + an
20/// [`Authority`]. The `authority_role` field selects which authority kind is installed:
21/// - `None` → [`Authority::OwnerControlled`] (the top-level owner gates `set_*` operations).
22/// - `Some(role)` → [`Authority::RbacControlled { role }`] (any holder of `role` gates `set_*`
23/// operations).
24///
25/// Pass to
26/// [`AccountBuilder::with_components`][miden_protocol::account::AccountBuilder::with_components]
27/// to install the access control components on the account:
28///
29/// ```no_run
30/// use miden_protocol::account::AccountBuilder;
31/// use miden_standards::account::access::AccessControl;
32/// # let owner: miden_protocol::account::AccountId = unimplemented!();
33/// # let init_seed = [0u8; 32];
34/// AccountBuilder::new(init_seed)
35/// .with_components(AccessControl::Rbac { owner, authority_role: None });
36/// ```
37///
38/// For accounts that don't use the [`AccessControl`] convenience but want to install the
39/// [`Authority`] component directly, the [`Authority`] enum can be passed via
40/// [`AccountBuilder::with_component`][miden_protocol::account::AccountBuilder::with_component].
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub enum AccessControl {
43 /// No external access control component is installed; access decisions are gated solely
44 /// by the account's auth component.
45 AuthControlled,
46 /// Two-step ownership transfer with the provided initial owner. Authority for `set_*`
47 /// operations is fixed to the registered owner.
48 Ownable2Step { owner: AccountId },
49 /// Role-based access control. Includes [`Ownable2Step`] internally; the provided `owner`
50 /// becomes the top-level RBAC authority (the account's owner).
51 ///
52 /// `authority_role` controls which authority is installed alongside RBAC:
53 /// - `None` (default) → [`Authority::OwnerControlled`]: the top-level `owner` is the sole
54 /// authority for `set_*` operations (`set_mint_policy`, `set_burn_policy`, metadata setters).
55 /// RBAC roles can still be granted/revoked but they do not directly gate the
56 /// authority-protected procedures.
57 /// - `Some(role)` → [`Authority::RbacControlled { role }`]: any account holding `role` becomes
58 /// a valid authority for `set_*` operations. Role membership is managed through the standard
59 /// RBAC API on the [`RoleBasedAccessControl`] component.
60 Rbac {
61 owner: AccountId,
62 authority_role: Option<RoleSymbol>,
63 },
64}
65
66impl IntoIterator for AccessControl {
67 type Item = AccountComponent;
68 type IntoIter = alloc::vec::IntoIter<AccountComponent>;
69
70 /// Yields the [`AccountComponent`]s implementing this access control configuration, in the
71 /// order they must be installed on the account. The matching [`Authority`] component is
72 /// always included.
73 fn into_iter(self) -> Self::IntoIter {
74 match self {
75 AccessControl::AuthControlled => vec![Authority::AuthControlled.into()].into_iter(),
76 AccessControl::Ownable2Step { owner } => {
77 vec![Ownable2Step::new(owner).into(), Authority::OwnerControlled.into()].into_iter()
78 },
79 AccessControl::Rbac { owner, authority_role: None } => vec![
80 Ownable2Step::new(owner).into(),
81 RoleBasedAccessControl::empty().into(),
82 Authority::OwnerControlled.into(),
83 ]
84 .into_iter(),
85 AccessControl::Rbac { owner, authority_role: Some(role) } => vec![
86 Ownable2Step::new(owner).into(),
87 RoleBasedAccessControl::empty().into(),
88 Authority::RbacControlled { role }.into(),
89 ]
90 .into_iter(),
91 }
92 }
93}
94
95pub use authority::{Authority, AuthorityError};
96pub use ownable2step::{Ownable2Step, Ownable2StepError};
97pub use pausable::{Pausable, PausableManager, PausableStorage};
98pub use rbac::RoleBasedAccessControl;