# Run system setup

You create your initial Ripple Custody environment setup with the `genesis` API operation.

The input request body contains two sections:

- `rootDomainSetup`: A standard new domain creation payload.
- `cryptoSetup`: The cryptographic algorithms Ripple Custody will use.


For an example request body and detailed descriptions of each section, see [Run the setup operation](#run-the-setup-operation) on this page.

You can only run this process once. The system is equipped with an anti-rewind mechanism that blocks any attempt to rerun the `genesis` operation.

After system setup, any further updates fall under the normal system update process of intents and the governance workflow. Therefore, it is important to consider what you want to include in your initial system setup.

For more information on how to design a Ripple Custody environment that meets your governance needs, see [Design your governance model](/products/custody/v1.26/get-started/design).

## Prerequisites

Before you run system setup, you need:

- The URL of your Ripple Custody API instance, which you can obtain from your Ripple liaison.
- The public keys of users you want to create.
For more information on user key generation, see [Generate a key pair and share the public key](/products/custody/v1.26/api/get-started/register#generate-a-key-pair-and-share-the-public-key).


## Run the setup operation

It is mandatory to define at least a primary (or root) domain, one user, and one policy during system setup, but you can also set up more.

To set up your system, call the [Genesis](/products/custody/v1.26/api/reference/openapi/genesis) API operation with a request body similar to the example below. You do not any authentication information, since the system has no active users at this stage.

### Request body example


```json Example genesis request body
{
    "rootDomainSetup": {
        "id": "e7eb7b63-d63b-4c30-9cca-d3b1ea7e46ad",
        "alias": "Root domain",
        "lock": "Unlocked",
        "governingStrategy": "CoerceDescendants",
        "permissions": {
            "readAccess": {
                "domains": [
                    "operator"
                ],
                "users": [
                    "operator"
                ],
                "endpoints": [
                    "operator"
                ],
                "policies": [
                    "operator"
                ],
                "accounts": [
                    "operator"
                ],
                "transactions": [
                    "operator"
                ],
                "requests": [
                    "operator"
                ],
                "events": [
                    "operator"
                ]
            }
        },
        "description": "A genesis payload for the creation of the root domain",
        "customProperties": {},
        "users": [
            {
                "id": "e1fe3431-f899-427b-9e67-a75fb9fe5e57",
                "alias": "operator@company.com",
                "publicKey": "MFkw...NfPfw/q9YW74Q==",
                "roles": [
                    "manager"
                ],
                "loginIds": [
                    {
                        "id": "op1@company.com",
                        "providerId": "harmonize"
                    },
                    {
                        "id": "op1@company.com",
                        "providerId": "azure-ad"
                    }
                ],
                "lock": "Unlocked",
                "description": "A manager user",
                "customProperties": {}
            }
        ],
        "policies": [
            {
                "id": "00000000-0000-0000-0000-000000000000",
                "alias": "Catch-All Policy",
                "rank": 20,
                "intentTypes": null,
                "scope": "Self",
                "scriptingEngine": "Javascript_v0",
                "condition": {
                    "expression": "context.request.author.id == 'e1fe3431-f899-427b-9e67-a75fb9fe5e57'",
                    "type": "Expression"
                },
                "workflow": [
                    {
                        "role": "manager",
                        "quorum": 1,
                        "type": "RoleQuorum"
                    }
                ],
                "lock": "Unlocked",
                "description": "Policy for exception handling",
                "customProperties": {}
            }
        ],
        "descendants": [{. . .}]]
    },
    "cryptoSetup": {
        "apiSigning": "Secp256r1",
        "collectionSigning": "Secp256r1",
        "messageSigning": "Ed25519"
    },
    "tickers": [
        {
            "id": "688b48e3-8ce1-4e01-b242-96f03ecb554a",
            "ledgerId": "bitcoin-testnet",
            "kind": "Native",
            "name": "Bitcoin testnet",
            "decimals": 8,
            "symbol": "tBTC",
            "ledgerDetails": {
                "properties": {
                    "type": "Native"
                },
                "type": "Bitcoin"
            },
            "lock": "Unlocked",
            "description": null,
            "customProperties": {}
        },
        {
            "id": "1e94173d-fafb-4e76-ae01-dbc11e4eaa17",
            "ledgerId": "ethereum-testnet",
            "kind": "Native",
            "name": "Ethereum testnet",
            "decimals": 18,
            "symbol": "tETH",
            "ledgerDetails": {
                "properties": {
                    "type": "Native"
                },
                "type": "Ethereum"
            },
            "lock": "Unlocked",
            "description": null,
            "customProperties": {}
        }
    ],
    "systemProperties": [
        {
            "value": {
                "publicKey": {
                    "value": "MFkw...HdVNyxTyl1plgAfh/Yg=="
                }
            },
            "type": "StateReviewAuthorityProperty"
        }
    ]
}
```

The main sections are described below.

### Root domain setup

This is the only mandatory section.

The `rootDomainSetup` section is similar to a standard new domain creation payload, where you specify the read permissions, users, and policies to be created in the newly created Ripple Custody instance. You can change the `rootDomainSetup` section to deploy new policies and users, together with their properties.

For more information, see [Ripple Custody API > Create domains](/products/custody/v1.26/api/environment/domain/create).

#### Governing strategy

During domain creation, you need to decide between the following governing strategies:

- `CoerceDescendants`: The domain ignores the policies of its subdomains.
- `ConsiderDescendants`: The domain considers the policies of its subdomains.


This field is optional. If you do not specify a governing strategy during domain creation, the domain defaults to a `ConsiderDescendants` strategy. Once a domain is created, the governing strategy cannot be changed.

The governing strategy and the presence of a matching policy for subdomains are evaluated using the `domainId` of the user submitting the intent. The `targetDomainId` must be a subdomain of the domain of intent origin. For a coercive intent, the policies of the  `targetDomainId` are entirely ignored.

If the coercive domain doesn't have a policy that is applicable to subdomains matching the intent, the intent is created in the subdomain with status `Failed` and a `NoApplicablePoliciesForDomain` error code.

To execute a coercive intent within a locked domain, the domain must be unlocked first.

#### Permissions

This access management section specifies the user roles that can view different entity types in the domain.

#### Users

This section is similar to a standard new user creation payload.

You need to create enough users, with appropriate roles, to fulfill the defined policies.

Users are identified by a unique alias and public key combination. These identifiers must respect the following guidelines:

- Users within the same domain cannot have the same alias.
- Users that have the same public key in different domains must have the same alias.



```json Example user with four roles and Azure AD SSO
    "users": [
        {
            "id": "e1fe3431-f899-427b-9e67-a75fb9fe5e57",
            "alias": "operator@ripple.com",
            "publicKey": "MFkw...NfPfw/q9YW74Q==",
            "roles": [
                "manager","compliance","director","operator"
            ],
            "loginIds": [
                {
                    "id": "op1@company.com",
                    "providerId": "harmonize"
                },
                {
                    "id": "op1@company.com",
                    "providerId": "azure-ad"
                }
            ],
            "lock": "Unlocked",
            "description": "A user",
            "customProperties": {}
        }
    ],
```

Once setup is complete, the initial set of users can log in to and use Ripple Custody.

For a detailed description of the user creation payload, see [Ripple Custody API > Create a user](/products/custody/v1.26/api/environment/user/create#create-a-user).

#### Policies

This section is similar to a standard new policy creation payload.
It is important to include a breakglass policy. For more information, see [Breakglass policy](/products/custody/v1.26/get-started/design/policies/breakglass).


```json Example catch-all policy
    "policies": [
        {
            "id": "00000000-0000-0000-0000-000000000000",
            "alias": "Catch-All Policy",
            "rank": 20,
            "intentTypes": null,
            "scope": "Self",
            "scriptingEngine": "Javascript_v0",
            "condition": {
                "expression": "context.request.author.id == 'e1fe3431-f899-427b-9e67-a75fb9fe5e57'",
                "type": "Expression"
            },
            "workflow": [
                {
                    "role": "manager",
                    "quorum": 1,
                    "type": "RoleQuorum"
                }
            ],
            "lock": "Unlocked",
            "description": "Policy for exception handling",
            "customProperties": {}
        }
    ],
```

For a detailed description of the policy creation payload, see [Ripple Custody API > Create policies](/products/custody/v1.26/api/environment/policy/create).

#### Descendants

This section is optional. You can specify subdomains as an array of domain objects inside the `descendants` property. For each subdomain, you specify the same information as for the root domain.

### Crypto setup

This section is optional.

The `cryptoSetup` section is used to specify the cryptographic methods (elliptic curves) that the governance engine uses to create and verify signatures, in order to securely exchange information with other parties.

You can specify different elliptic curves for different operations:

- `apiSigning`: The curve used to sign payloads returned to users following a `GET` request.
- `collectionSigning`: The curve used for signing the roots of all collections’ Merkle trees, which guarantees tamper-proof storage of the information. For more information about the Merkle tree, see [Merkle tree](/products/custody/v1.26/overview/architecture/security#merkle-tree).
- `messageSigning`: The curve used to sign internal messages from the governance engine to the vault.


For all types of operations the user can choose between `Secp256r1`, `Secp256k1` and `Ed25519` elliptic curves. Recommended values are shown in the example payload above.

For more information, see [Digital signature](/products/custody/v1.26/api/authentication#digital-signature).

### Tickers

This section is optional.

The `tickers` section includes a list of tickers and other assets available for blockchain ledgers. You can use this section to provide a list of pre-validated tickers.

### System properties

This section is optional.

In the `systemProperties` section, you register the public key of the state review authority. This is a public key in a standard Ripple Custody accepted format (secp256k1, secp256r1, or Ed25519) represented as a Base64-encoded string.

The state review authority acts as a trusted party to confirm the authenticity of the system state if the anti-rewind file (ARF) needs to be recovered.

If you do not specify this information during system setup, you need to specify it as soon as possible afterwards, since it allows you to recover your system in a disaster recovery scenario.

For more information, see [Disaster recovery](/products/custody/v1.26/system-management/disaster-recovery).

## Event updates

When you run the `genesis` operation, Ripple Custody includes two properties in the `GenesisSucceeded` event:

- `genesis`: A data structure holding the notary signed original genesis payload.
- `createdEntitiesReferences`: Key information on the data created.


For more information, see [Event management > Genesis event](/products/custody/v1.26/system-management/events#genesis-event).