Setting Access Rules

The previous section covers how auth is generally set up on your component. Although, when we approached the constructor section, we needed to map Roles with an AccessRule. We briefly mentioned that AccessRule allows us to specify the required badges a role needs to have to access a permissioned method. The AccessRule effectively enforces a boolean condition based on the presence of a badge. More specifically, these are Proofs of the badge(s).

Let’s review the snippet example we had in the previous section:

// -- snip --
.instantiate()
.prepare_to_globalize(
    OwnerRole::Fixed(
        rule!(require(owner_badge.resource_address())
    )
))
.roles(
    roles!(
        super_admin => rule!(require_amount(dec!(2), super_admin_badge.resource_address()));
        admin => rule!(require(admin_manager.resource_address()));
    )
)
.globalize();

Notice that the AccessRule for the OWNER (and likewise the admin) is different from the super admin. For the OWNER, we only required a Proof of the owner_badge, but for the super admin, we not only required the Proof of the super_admin_badge, but we want a quantity of two Proofs. There are many AccessRule requirement from which we can specify:

Rule Description

require(single resource)

TRUE if the specified resource is present

require_any_of(list of resources)

TRUE if any resource in the list is present

require_all_of(list of resources)

TRUE if every resource in the list is present

require_n_of(n, list_of_resources)

TRUE if at least n resources in the list are present

require_amount(quantity, single resource)

TRUE if the specified resource is present in at least the given quantity

allow_all or AccessRule::AllowAll

TRUE always

deny_all or AccessRule::DenyAll

FALSE always

The resources (or resource lists) may either be specified statically (giving exact resource addresses) or may be references to variables in the component.

Multiple rules may be combined with logical operators && and ||, and nested within (). There is no logical "not" operator.

Examples

Here is an examples for defining complex rules. We are setting access rules for accessing methods on a component. To be able to call the ban_member method, the caller must present a proof that they either own an admin badge or a moderator badge. To call the destroy method the caller must present a proof of the admin badge AND of two moderator badges.

#[blueprint]
mod rad_flix{
    enable_method_auth! {
        roles {
            auth1 => updatable_by: [];
            auth2 => updatable_by: [];
        },
        methods {
            ban_member => restrict_to: [admin, moderator]
            destroy => restrict_to: [admin, moderator]
        }

        // -- snip --

    pub fn instantiate() -> (Global<RadFlix>, Bucket, Bucket) {
        // Create the access badges
        let admin_badge: Bucket = ResourceBuilder::new_fungible(OwnerRole::None)
            .initial_supply(1);
        let moderator_badges: Bucket = ResourceBuilder::new_fungible(OwnerRole::None)
            .initial_supply(4);

        let admin_badge_address = admin_badge.resource_address();
        let moderator_badge_address = moderator_badges.resource_address();

        // Instantiate the component
        let component = Self {}
            .instantiate()
            .prepare_to_globalize(OwnerRole::None)
            .roles(
                roles!(
                    auth1 => rule!(require_any_of(vec![admin_badge_address, moderator_badge_address]));
                    auth2 => rule!(require(admin_badge_address) && require_amount(dec!(2), moderator_badge_address));
                )
            .globalize();

        (component, admin_badge, moderator_badges)
}

You can find more specific examples for setting rules on the methods rules or resource action rules pages.