Skip to main content

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;