04 Auth
4.4 AccessRules & AuthZone
The nuances of what type of badge to use as an
AccessRule condition makes interesting auth model design for your dApp. However, the granularity of Scrypto’s auth framework goes further. In this section, we'll be exploring the use of access rules to tie badges as conditions for auth. We already saw a simplistic use of AccessRule back in Chapter 4.2 - Resource Auth - Revisiting Resource Behavior where we required single specific badge before a resource action can be performed. But access rules can be more flexible than simply requiring single badges. We can define an AccessRule which require two badges that may be held in two different account, unlocking the possibility of multi-factor control. This means it's possible that we can set up an AccessRule which require approval of two different people, each holding their own respective badges, before a permissioned action can be granted. We'll talk about the different conditions we can use to structure our AccessRule and explore how access rules are enforced.//Defining AccessRules
As explained briefly in Chapter 4: Introduction to Auth, access rules are used to define conditions of access by determining what badge(s) need to be present before a method or resource behavior can be performed. There are more than one way to construct an
AccessRule, a simple and straightforward way is by simply calling the rule!() macro. Within the rule!() macro, we can start defining our AccessRule.let access_rules: AccessRule = rule!(require(some_badge));This is a simple
However, we can take a step further from that by exploring other conditions we can use with
AccessRule which states that a singular some_badge is required for something. We haven’t yet applied this AccessRule to anything yet, but defining the conditions the access rules can enforce. However, we can take a step further from that by exploring other conditions we can use with
AccessRules.//Configuring AccessRules
Below, you’ll se a table that summarizes the rule conditions an
AccessRule may have:Condition
Description
require(single resource)
TRUE if the specified resource is present
require_any_of(list of resource)
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
TRUE always
deny_all
FALSE always
In many of our previous examples, we’ve mainly passed in the
ResourceAddress of the badge, but we can also pass in a NonFungibleGlobalId as well. If you’re using either a require_any_of, require_all_of, or require_n_of, you may also pass in a list of resources by using a vector:let access_rules = rule!(require_any_of( vec![ admin_badge.resource_address(), moderator_badge.resource_address() ] ));//Combining logical operators for your AccessRule
You may also consider adding multiple rules with combined logical operators such as
&& and ||, and nested () to add complexity in your use case.let access_rules = rule!( require(admin_badge.resource_address()) && require_amount(dec!(2), moderator_badge.resource_address()));With this
AccessRule condition, not only does an admin_badge need to be present in the transaction before a permissioned action can be performed, but also two moderator_badge also need to be present as well! In other words, so long as the badges are distributed to multiple accounts, this means the Radix Engine supports multi-sig transactions - requiring the transaction to be signed by multiple people to approve.//Enforcing AccessRules in the AuthZone
We’ve now covered different ways we can structure access rules and how badges are tied to conditions we define. But how do access rules work in practice? In the Chapter 4.3: Badges & Proofs section, we mentioned that we use badges as a form of auth in Scrypto, but in fact, we don’t actually send the badges directly to be validated. Instead, we send a proof of the badge to be validated.
On Radix, transaction are created with transaction manifests. We learned a bit about this in Chapter 1 where we gave a primer on Scrypto, but more on transactions will also be covered in Chapter 5: Introduction to Transactions on Radix with the Transaction Manifest. Within this transaction manifest will be describing the list of interactions intended by the caller such as calling component methods, withdrawing from account, or depositing to another account. Part of these interactions will be describing the resources and proofs required for the interaction as well as the movement of those resources and proofs.
When it comes to proofs, proofs are automatically sent to the AuthZone, a dedicated places where proofs are placed and used by the Radix Engine to validate against any access rules imposed. When the validations against access rules are satisfied, the Radix Engine can understand the roles assumed between any proofs sent and can allow access based on the boundaries allowed by the roles.
This context will be helpful to keep in mind as we delve in the next sections how we can apply these same auth concepts in the context of components as there are two approaches to component auths to be aware about.
On Radix, transaction are created with transaction manifests. We learned a bit about this in Chapter 1 where we gave a primer on Scrypto, but more on transactions will also be covered in Chapter 5: Introduction to Transactions on Radix with the Transaction Manifest. Within this transaction manifest will be describing the list of interactions intended by the caller such as calling component methods, withdrawing from account, or depositing to another account. Part of these interactions will be describing the resources and proofs required for the interaction as well as the movement of those resources and proofs.
When it comes to proofs, proofs are automatically sent to the AuthZone, a dedicated places where proofs are placed and used by the Radix Engine to validate against any access rules imposed. When the validations against access rules are satisfied, the Radix Engine can understand the roles assumed between any proofs sent and can allow access based on the boundaries allowed by the roles.
This context will be helpful to keep in mind as we delve in the next sections how we can apply these same auth concepts in the context of components as there are two approaches to component auths to be aware about.