Skip to main content

Roles & Permissions

The contract-level role model: the bytes32 roles defined in the contracts, what they authorise, and the production safety rules around the most powerful ones.

note

This is the contract-level RBAC reference. For the operational, product-side view of who can do what in the app, see the user guide Roles & permissions.

How roles work​

Access control is role-based. Each role is a bytes32 constant named ROLE_<UPPER_SNAKE> — a keccak256 hash of asset.tokenization.standard.role.<PascalName>, generated from a /// @custom:hash role <PascalName> annotation (see Hash code generation) — defined in constants/roles.sol. The one exception is DEFAULT_ADMIN_ROLE = 0x00, which keeps its OpenZeppelin-compatible value. Roles are seeded at deployment through the Rbac[] array the Factory accepts, and managed afterwards with the standard grantRole / revokeRole / renounceRole functions:

struct Rbac {
bytes32 role;
address[] members;
} // IResolverProxy.Rbac

DEFAULT_ADMIN_ROLE — handle with care​

DEFAULT_ADMIN_ROLE (0x00) sits at the top of the role tree and can grant or revoke every other role. Critically, it also authorises high-impact, instant Diamond operations on the proxy — updateResolver, updateConfig, and updateConfigVersion — which take effect in a single transaction with no on-chain timelock and no user exit window.

Admin must be a multisig

Because those operations are instant and irreversible, DEFAULT_ADMIN_ROLE must be held by a multisig or governance contract in production — never an externally-owned account (EOA). The multisig's own approval workflow is what supplies the delay, review, and accountability that the contracts deliberately do not impose on-chain.

Operational roles​

Day-to-day actions are gated by purpose-specific roles. The main ones, grouped by responsibility:

AreaRoles (ROLE_*)Authorises
Issuance / supplyAgent, Issuer, CapMint, burn, forced transfers; issuance; supply-cap management.
Compliance & identityKyc, KycManager, InternalKycManager, SsiManager, ControlList, ControlListManagerKYC status, allow/deny lists, self-sovereign identity configuration.
Asset protectionFreezeManager, Locker, Pauser, PauseManager, DeactivateFreeze/unfreeze, lock tokens, pause/unpause, deactivate the token.
ClearingClearing, ClearingValidatorClearing and settlement operations and their validation.
Corporate actionsCorporateAction, CorporateActionForceCancel, Snapshot, AdjustmentBalance, AmortizationDividends, voting, coupons, snapshots, balance adjustments (and the high-risk force-cancel).
Bond economicsMaturityManager, MaturityRedeemer, InterestRateManager, KpiManager, NominalValue, ProceedRecipientManagerMaturity, redemption, interest / KPI rates, nominal value, proceeds.
LoansLoanManager, LoansPortfolioManagerLoan and loans-portfolio operations.
Documents & controlDocumenter, Controller, ProtectedPartitions (+ Participant), CustomDataManager, WildCard, CreateConfiguration, TrexOwnerDocuments, controller transfers, protected partitions, custom data, configuration creation, ERC-3643 ownership.

The exact constants (ROLE_AGENT, ROLE_KYC_MANAGER, …) and their generated hashes live in constants/roles.sol and are surfaced in the generated scripts/domain/atsRoles.generated.ts.

High-risk: corporate-action force-cancel​

A subset of corporate-action operations have force-cancel variants that bypass the normal date guards. These can leave a token in an inconsistent state and are not reversible. The role that authorises them (ROLE_CORPORATE_ACTION_FORCE_CANCEL) must be granted only to a multisig, never an EOA. See Scheduled tasks & force-cancel for the full risk model.

Best practices​

  • ✅ Hold DEFAULT_ADMIN_ROLE (and any force-cancel role) in a multisig/governance contract.
  • ✅ Grant the minimum roles each operator needs; prefer narrow operational roles over admin.
  • ✅ Record role grants/revocations in your governance log.
  • ❌ Never assign admin or force-cancel roles to an EOA in production or pre-production.