For the complete documentation index, see llms.txt. This page is also available as Markdown.

Access management: roles and domains

Authority throughout the protocol is governed by one model. No contract implements its own owner and its own role checks. Every privileged function is gated through an access manager that holds the roles and the policies that decide who may call it. Deployment rights, upgrade rights, agent powers, the administrative roles that govern trust: all are roles in this model.

This page describes how the model works, how roles are scoped, how a token suite is wired to it, and who sits at the top of each hierarchy. What each role gates is listed in Actors and roles.

The model

The protocol uses OpenZeppelin's AccessManager. A managed contract asks one question before it executes a privileged function: may this caller call this function on me? The manager answers from two tables.

Table
Content

Functions to roles

For each managed contract and each privileged function, the role that may call it.

Roles to members

For each role, the accounts that hold it, and for each the delay that applies to their calls.

Consolidating authority this way has two virtues.

  • One place to audit. Who can do what, across a whole token suite, is read from one contract. There is no patchwork of per-contract owners.

  • Authority can be delegated precisely. A role can be held by a single key, a multisig, an institution's governance process or an automated system, without changing the contracts that check it. How a role is held is a policy decision outside the contract.

The managers

Authority is not concentrated in one manager for everything. Each Issuer has its own manager, and the network has one for the contracts every asset shares.

Manager
Governs
Root held by

The manager of a token suite, a TREXAccessManager

The Token, the TREXRegistry, the IdentityRegistryStorage and the ModularCompliance of one or several assets

The Issuer

The manager of the network

The TREXFactory, the TREXImplementationAuthority, the TrustedGatewayRegistry, the IdentityFactory, the ReputationRegistry, and the shared compliance modules and adapters

Network governance

The authority of a compliance module an Issuer deployed itself

The upgrade of that module

That Issuer

The roles of an Issuer's own manager have no reach over the network contracts, and the network's roles have no reach inside an Issuer's manager.

The network uses one manager, and not one holder. Its roles are different roles, held by different multisigs with their own members and thresholds: publishing versions, vetting gateways, administering the identity layer and setting reputation are separate powers in separate hands.

Roles are scoped to a domain

Several assets can share one manager. If roles were global to the manager, the minter of one asset could mint another. Roles are therefore scoped.

A domain is an issuer, or a fund: one team across every token in it. A role identifier is made of two parts, the domain and the role.

Part
Meaning

Domain, upper half of the identifier

Which group of assets the role applies to

Role number, lower half

Which role: OWNER, AGENT_MINTER, and so on

  • Two tokens in one domain share their agents. Granting AGENT_MINTER in a domain lets its holder mint every token of that domain.

  • Two domains are isolated. A role of one domain satisfies nothing in another, even in the same manager.

  • No role exists without a domain. A role identifier cannot be built for domain zero, so no unscoped role can be granted by omission.

  • An identifier can be read back. Tooling recovers the domain and the role from the identifier found in a grant event.

An Issuer can also define roles of its own in its domain, by name, next to the standard ones. They are mapped to functions and granted like any role.

The platform domain

Platform roles live in a reserved domain that no suite role can be built in: OWNER of the factory, VERSION_MANAGER, ASSET_DEPLOYER, INTEROP_MANAGER. Network governance holds OWNER, VERSION_MANAGER and INTEROP_MANAGER. It grants ASSET_DEPLOYER to the Issuers and tokenization providers that deploy suites. ASSET_DEPLOYER gates the deployment of a suite and the creation of the identity of a token, and nothing else: the references of the factory stay under OWNER.

The domain registry

The TREXAccessManager keeps a record of domains: createDomain(name) creates one, assign(domainId, target) records the domain of a token or of a storage, and domainOf, domainName and domainCount read it back.

This record is a directory. It is not what authorizes a call. Authorization is the role mapped to each function and the grants behind it. Commissioning keeps the two in step.

The hierarchy of a suite

An arrow means "grants and revokes". The roles below ADMIN_ROLE are each in a domain.

Administrator
Hands out
Typical holder

ADMIN_ROLE

OWNER, SUITE_ADMIN, AGENT_ADMIN. Maps functions to roles. Commissions suites.

The Issuer's governance

SUITE_ADMIN

The configuration roles of the suite

The Issuer's product or operations lead

AGENT_ADMIN

The agent roles, the keeper, the binding of storages

The Issuer's head of operations, or its transfer agent

IRS_WRITER is held by registries only and stays under ADMIN_ROLE. No administrator of a domain can hand it out. Agents edit investor records through a registry, never in the storage directly, so a storage shared between two domains gives the agents of one nothing over the other.

Trust statement. The holder of ADMIN_ROLE on a manager can remap any function to any role and grant any role. It controls every suite that manager governs. It is the key an Issuer protects most.

Commissioning a suite

A deployed suite is not operable until its functions are mapped to roles: until then, every privileged function answers to the holder of ADMIN_ROLE only. This wiring is called commissioning.

What commissioning does

Maps each privileged function of the token, the registry, the compliance and the storage to its role, in the suite's domain

The tables listed in Actors and roles

Sets which role administers which

The hierarchy above

Grants AGENT to the token

So that a recovery can register the new wallet

Grants IRS_WRITER to the registry, and binds the registry to its storage

So that registrations can be written

Commissioning requires ADMIN_ROLE. It can be run again: it applies the same standard tables.

There are two ways to get a commissioned suite.

The factory deploys the manager
The Issuer supplies its manager

At deployment

The factory deploys a TREXAccessManager, creates a domain named after the token, assigns the token and its storage to it, and commissions the suite.

The factory deploys the suite against the Issuer's manager and writes nothing into it.

Afterward

The factory hands ADMIN_ROLE to the account the Issuer named and renounces its own.

The Issuer commissions the suite itself. Until it does, the suite is not operable.

Suits

An Issuer's first asset

An Issuer that already has a manager and adds an asset to it, in an existing domain or a new one

The factory keeps no authority over a suite it has deployed.

An Issuer that wants a manager of its own can obtain it from the access manager factory of the T-REX Network [[TBC: the access manager factory]], which deploys the network's reference TREXAccessManager code. An Issuer can also deploy a manager by other means, and then answers for its code. In both cases the manager is the Issuer's: who holds its root, how roles are split and to whom they are granted are the Issuer's decisions and its responsibility. The network has no say in them.

Several assets, one manager

An Issuer with several assets chooses how to group them.

Arrangement
Effect

Several tokens in one domain

One team operates them all. A role granted once applies to every token of the domain.

Several domains in one manager

Separate teams per fund or per product line, under one root.

One manager per token

Complete separation, including of the root.

Tokens can be moved from one domain to others later. The operation remaps their functions to the new domain's roles, grants the new roles and revokes the old ones in one step.

Delays and scheduled operations

A role can be granted with an execution delay. Its holder then does not call the function directly. It schedules the call, waits for the delay, and executes it. During the delay, the operation is visible on-chain and can be cancelled by the account that scheduled it, by the holder of the guardian role that the manager attaches to that role, or by the admin of the manager. This guardian role belongs to OpenZeppelin's AccessManager and has nothing to do with the Guardians of an identity.

This turns any sensitive function into a timelocked one by configuration, without a change to the contract: the pause can be immediate while a change of compliance module waits 48 hours.

One detail: a batch function is authorized by the role of its single operation. A holder whose role carries a delay uses the single operation, scheduled. The batch form requires immediate permission. batchRegisterIdentity is the exception: it has its own mapping and can be scheduled.

owner() and the manager

Every suite contract exposes owner(), for tooling that expects one. It returns the address of the manager, not of a person. The manager of a suite is not replaced: it is an upgradeable contract that is upgraded in place, and the identity of the token is managed by it.

The token's identity follows the same roles

The ONCHAINID of a token has one MANAGEMENT key: the manager of its suite. Whoever the Issuer authorizes in the manager acts on the token's identity through it. The token and its identity are governed by the same structure.

The identity layer

The IdentityFactory and the ReputationRegistry are governed through the manager of the network, with the same mechanism, by roles that are distinct from the platform roles.

Authority
Gates

Identity layer administration

The policy and the modules of each identity type, the trusted gateways and verifiers

A creation role per identity type

Deploying an identity of that type for another account

The beacon upgrader, with a delay

Upgrading the implementation of every identity

REPUTATION_MANAGER

Reputation scores and the claim-add threshold

An ONCHAINID itself is not governed by a manager. It is governed by its own keys. See Keys, purposes and signers.

Reading the configuration

Everything about who can do what is on-chain and readable.

Question
Read

Which role gates this function?

getTargetFunctionRole(contract, selector) on the manager

Does this account hold this role, and with what delay?

hasRole(roleId, account)

Who administers this role?

getRoleAdmin(roleId)

Which domain is this token in?

domainOf(token)

Who is the authority of this contract?

authority() on the contract

Last updated