> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/governance-and-infrastructure/access-management-roles-and-domains.md).

# 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](/start-here/actors-and-roles.md).

## 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. |

```mermaid
flowchart LR
    C["Caller"] -->|"calls a privileged function"| K["Managed contract"]
    K -->|"may this caller call this function?"| AM["AccessManager"]
    AM --> F["Function to role"]
    AM --> R["Role to members"]
    AM -->|"yes, no, or after a delay"| K
```

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

```mermaid
flowchart TB
    AD["ADMIN_ROLE<br/>root of the manager"]
    AD --> OW["OWNER"]
    AD --> SA["SUITE_ADMIN"]
    AD --> AA["AGENT_ADMIN"]
    AD --> IW["IRS_WRITER<br/>held by registries"]
    SA --> TM["TOKEN_MANAGER"]
    SA --> IM["IDENTITY_MANAGER"]
    SA --> CM["COMPLIANCE_MANAGER"]
    AA --> AG["AGENT and the<br/>seven agent roles"]
    AA --> IB["IRS_BINDER"]
    AA --> VK["VALIDATION_KEEPER"]
```

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](/identity-onchainid/keys-purposes-and-signers.md).

## 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                              |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.t-rex.network/governance-and-infrastructure/access-management-roles-and-domains.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
