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:
| Clearance | Meaning |
|---|---|
None | The role cannot call the target. This is the default. |
Target | The role can call every function of the target. |
Function | The 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:
| Function | Effect |
|---|---|
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:
| Value | Ether transfer (send) | Delegate call |
|---|---|---|
None (0) | No | No |
Send (1) | Yes | No |
DelegateCall (2) | No | Yes |
Both (3) | Yes | Yes |
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
- Limit parameters: Conditions
- Set spending limits: Allowances
- Apply and execute: Quickstart