Skip to Content
DevelopersRolesPermission model

The permission model

This page explains how the Roles Modifier stores permissions. The model has three levels: targets, functions, and conditions.

You can build most permissions in the Zodiac App , with policy action templates and per-parameter toggles. The app and the SDK write the same model. Read this page to understand what they write.

Clearance: the access level for a target

For each target address, a role has one clearance level:

ClearanceMeaning
NoneThe role cannot call the target. This is the default.
TargetThe role can call every function of the target.
FunctionThe role can call only the listed functions of the target.

The four configuration verbs

The owner of the Roles Modifier configures a role with four functions:

FunctionEffect
allowTarget(roleKey, target, options)Set clearance Target. The role can call every function of the target.
scopeTarget(roleKey, target)Set clearance Function. The role can call the target only through functions that you allow next.
allowFunction(roleKey, target, selector, options)Allow one function with all parameter values (a wildcard).
scopeFunction(roleKey, target, selector, conditions, options)Allow one function only when the condition tree passes.

revokeTarget and revokeFunction remove the access again.

You rarely call these functions yourself. Your constellation (through push) and the Zodiac App compute and apply them for you. The verbs still appear in events, in the subgraph, and in the app, so learn their names.

Execution options

allowTarget, allowFunction, and scopeFunction take an options value. It controls two extra rights:

ValueEther transfer (send)Delegate call
None (0)NoNo
Send (1)YesNo
DelegateCall (2)NoYes
Both (3)YesYes

A delegate call runs foreign code with the full power of the Safe. It can drain all assets and change the owners. Only allow delegate calls to contracts that you have verified, and never to upgradeable contracts.

Members and role keys

assignRoles(module, roleKeys, memberOf) adds or removes members. One address can hold many roles. When a member executes, it names the role key to use.

A role key is a bytes32 value. The SDK encodes a label of up to 32 characters (a-z, 0-9, _) into the key. Example: manager becomes 0x6d616e6167657200000000000000000000000000000000000000000000000000.

setDefaultRole(module, roleKey) sets the role that applies when the member calls the generic execTransactionFromModule instead of execTransactionWithRole. This makes the Roles Modifier a drop-in target for modules that only know the IAvatar interface.

Wildcard with care

A wildcarded target (allowTarget) accepts every call, with every parameter, forever — until you revoke it. Prefer scopeTarget plus explicit functions. Use conditions for functions that move value.

approve on a token is as powerful as transfer. If you allow approve without a condition on the spender, the member can grant the token to any address.

Next steps

Last updated on