Skip to content

The examples described below cover different business cases that you can use as a basis for creating your own.

You can implement the examples in one of the following ways:

  • With the policies payload of the genesis operation you run at system setup. For more information about this payload, see the example in Run system setup.
  • With the payload of the v0_CreatePolicy intent. For more information about this payload, see the example in Ripple Custody API > Create policies.

Roles

The following table gives an overview of the roles used in the examples:

RoleTypeDescription
system-operatorMakerHuman user in charge of the entities of the environment who creates and submits organizational intents (for example, user and account creation, vault registration).
policy-operatorMakerHuman user in charge of environment administration.
transaction-operatorMakerHuman user in charge of the operational entities of the environment who creates and submits operational intents (for example, transaction order creation).
transaction-operator-botMakerTechnical, or bot, user with the same rights as the human transaction-operator.
complianceCheckerHuman user in charge of signing and approving operational and management intents submitted by users with any other type of role.

Both human and bot users are included in the examples, with a minimum of two users recommended for all human roles.

For a description of maker and checker roles, see Central principles of the policy framework.

Organizational policies

The following set of example policies applies to organizational tasks.

User management

This policy is for user management operations, including creation of new users, updates to user roles, locking and unlocking users.

The policy has the following characteristics:

  • The intent type is set to a list of the different available actions for users so the policy is applicable to user intents, as long as the condition is met.
  • The condition specifies that the intent can be requested by users with system-operator role.
  • The intent must be approved by a second user with system-operator role.
Policy propertyJSON example
Intent types["v0_CreateUser", "v0_UpdateUser", "v0_LockUser", "v0_UnlockUser"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
  "type": "Expression"
}
Workflows[
  {
   "role": "system-operator",
   "quorum": 2,
   "type": "RoleQuorum"
  }
]

Account management

This policy is for account management operations, including creation of new accounts, updates to existing accounts, locking and unlocking accounts.

The policy has the following characteristics:

  • The intent type is set to a list of the different available actions for accounts so the policy is applicable to account intents, as long as the condition is met.
  • The condition specifies that the intent can be requested by users with system-operator role.
  • The intent must be approved by a second user with system-operator role and by a compliance role.
Policy propertyJSON example
Intent types["v0_CreateAccount", "v0_UpdateAccount", "v0_LockAccount","v0_UnlockAccount"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "system-operator",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Endpoint management – register a trusted address

This policy is for the management of endpoints that register trusted addresses, including creation of endpoints, updates to existing endpoints, locking and unlocking endpoints.

The policy has the following characteristics:

  • The intent type is set to a list of the different available actions for endpoints so the policy is applicable to endpoint intents, as long as the condition is met.
  • The condition specifies that the intent can be requested by users with system-operator role.
  • The intent must be approved by a second user with system-operator role.
Policy propertyJSON example
Intent types["v0_CreateEndpoint" , "v0_UpdateEndpoint" , "v0_LockEndpoint" , "v0_UnlockEndpoint"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
  "type": "Expression"
}
Workflows[
  {
   "role": "system-operator",
   "quorum": 2,
   "type": "RoleQuorum"
  }
]

Endpoint management – register a smart contract

This policy is for the creation of endpoints that represent smart contracts.

The policy has the following characteristics:

  • The intent type is set to create endpoints, so the other operations (update, lock, and unlock) match the previous policy. Note that the rank of this policy is higher than the generic endpoint policy as it must be evaluated first, otherwise the previous policy applies.
  • The condition specifies that the intent can be requested by users with system-operator role and that the parameters object must exist with a non-null value. This parameter object contains the ABI definition, so this indicates that the address belongs to a smart contract.
  • The intent must be approved by a second user with either system-operator role, and then escalated to a compliance user.
Policy propertyJSON example
Intent types["v0_CreateEndpoint" ]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator') &&
context.request.payload.hasOwnProperty('parameters') &&
context.request.payload.parameters != null",
  "type": "Expression"
}
Workflows[
  {
   "role": "system-operator",
   "quorum": 2,
   "type": "RoleQuorum"
  },
  {
   "role": "compliance",
  "quorum": 1,
  "type": "RoleQuorum"
  }
]

Policy management

This policy is to manage other policies, including the creation, update, locking and unlocking of policies. Generally a policy to update policies needs to have a high rank to be applied first. This policy enables the correction of other policies when mistakes occur.

The policy has the following characteristics:

  • The intent type is set to a list of the different available actions for policies so the policy is applicable to policy intents, as long as the condition is met.
  • The condition specifies that the order can be requested by users with policy-operator role. The intent must be approved by a second user with a policy-operator role and two compliance roles.
  • The policy needs an appropriately high-risk approval workflow, as creating and modifying policies is an extremely sensitive operation.
Policy propertyJSON example
Intent types["v0_CreatePolicy", "v0_UpdatePolicy", "v0_LockPolicy","v0_UnlockPolicy"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('policy-operator')",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "policy-operator",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Transaction policies

The following set of example policies applies to transaction tasks.

Transfer out to an unknown address (XRPL and ETH)

This policy is for transaction orders where the destination is an unknown ledger address. The policy applies to XRPL and Ethereum Virtual Machine ledgers.

The policy has the following characteristics:

  • The intent type is set to v0_CreateTransactionOrder so the policy is applicable to transaction order intents, as long as the condition is met.
  • The condition specifies that the order can be requested by users with transaction-operator role and that the destination is an address. Before checking for the destination type, we check if a destination.type object exists. This is because for some ledgers (other than XRPL and ETH) the structure of the payload is different and the data at this location does not exist, which will trigger an error in the policy.
  • The order must be approved by a second user with either transaction-operator role and two compliance roles.
Policy propertyJSON example
Intent types["v0_CreateTransactionOrder"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') &&
context.request.payload.parameters.hasOwnProperty('destination') &&
context.request.payload.parameters.destination.type == 'Address'",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "transaction-operator",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Transfer out to a trusted address (XRPL and ETH)

This policy is for transaction orders where the destination is a trusted address. A trusted address is an address registered as an endpoint where the trust score is set to a value higher than a threshold. For this example, the threshold is set to 75.

The policy has the following characteristics:

  • The intent type is set to v0_CreateTransactionOrder so the policy applicable to transaction order intents as long as the condition is met.
  • The condition specifies that the order can be requested by users with either transaction-operator role or transaction-operator-bot role, and that the destination is an endpoint with a score greater than 75. Before checking for the destination type, we check if a destination.type object exists. This is because for some ledgers (other than XRPL and ETH) the structure of the payload is different and the data at this location does not exist, which will trigger an error in the policy.
  • The order must be approved by a second user with either transaction-operator role or transaction-operator-bot role.
Policy propertyJSON example
Intent types["v0_CreateTransactionOrder"]
Conditions{
  "expression": "(context.references.users[context.request.author.id].roles.includes('transaction-operator-bot') ||
context.references.users[context.request.author.id].roles.includes('transaction-operator') ) &&
context.request.payload.parameters.hasOwnProperty('destination') &&
context.request.payload.parameters.destination.type == 'Endpoint' &&
context.references.endpoints[context.request.payload.parameters.destination.endpointId].trustScore >= 75",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "transaction-operator",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "transaction-operator-bot",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "type": "Or"
  },
  {
   "left": {
    "role": "transaction-operator",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "transaction-operator-bot",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "type": "Or"
  }
]

Transfer out of ETH with a large amount (irrespective of destination)

This policy is for transaction orders where the amount is higher than a defined threshold.

The policy has the following characteristics:

  • The intent type is set to v0_CreateTransactionOrder so the policy is applicable to transaction order intents as long as the condition is met.
  • The condition specifies that the order can be requested by users with transaction-operator role, that the source account is from a specific ledger (in this case ethereum-testnet) and that the amount is greater than 5 ETH.
  • The order must be approved by two users with compliance role.
Policy propertyJSON example
Intent types["v0_CreateTransactionOrder"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') &&
context.references.accounts[context.request.payload.accountId].ledgerId == 'ethereum-testnet' &&
context.request.payload.parameters.amount >= BigInt(5000000000000000000)",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "transaction-operator",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Transfer out of BTC with a large amount (irrespective of destination)

This policy is for transaction orders where the amount is higher than a defined threshold.

The policy has the following characteristics:

  • The intent type is set to v0_CreateTransactionOrder so the policy is applicable to transaction order intents as long as the condition is met.
  • The condition specifies that the order can be requested by users with transaction-operator role, that the source account is from a specific ledger (in this case bitcoin-testnet) and that the amount is greater than 5 BTC.
  • The order must be approved by two users with compliance role.
Policy propertyJSON example
Intent types["v0_CreateTransactionOrder"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') && context.references.accounts[context.request.payload.accountId].ledgerId == 'bitcoin-testnet' && contextrequest.payload.parameters.outputs.reduce((acc, v) => BigInt(acc) + BigInt(v.amount), 0) >= BigInt(500000000)",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "transaction-operator",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 2,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Transfer in

This policy is to manage anti-money laundering (AML) on incoming funds. All incoming funds are put under quarantine with no exception and must be explicitly released.

The policy has the following characteristics:

  • The intent type is set to v0_ReleaseQuarantinedTransfers so the policy is applicable to transaction order intents as long as the condition is met.
  • The condition specifies that the order can be requested by users with system-operator role.
  • The approval workflow consists of the approval of the maker role system-operator, and a further approval from one compliance role
Policy propertyJSON example
Intent types["v0_ReleaseQuarantinedTransfers"]
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "role": "system-operator",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "right": {
    "role": "compliance",
    "quorum": 1,
    "type": "RoleQuorum"
   },
   "type": "And"
  }
]

Catch-all

A catch-all policy is always recommended as a fail-safe mechanism to capture business workflows that have not been accounted for. This may be due to a new business requirement being introduced or to a use case not previously accounted for.

We recommend that the catch-all policy is associated with a high-risk approval workflow, since the purpose of this policy is to catch exceptions and not be a standard policy for regular business flows.

This policy also needs a particularly low rank, to ensure that the system first tries to look for an existing policy and only resorts to using the catch-all if no other system policy can govern an intent.

The policy has the following characteristics:

  • The intent type is set to null so the policy is applicable to all types of intents as long as the condition is met.
  • The condition specifies that the user must have one of the maker roles named above. This is to ensure that any other user without one of the maker roles is not able to propose an intent. In a more general case, the condition could also be set to null, to further capture any attempt to create an intent.
  • The approval consists of a quorum of two compliance roles. The first step of the approval workflow is a combination of workflow objects, to enable any of the maker roles to give the first approval.
Policy propertyJSON example
Conditions{
  "expression": "context.references.users[context.request.author.id].roles.includes('system-operator') || context.references.users[context.request.author.id].roles.includes('policy-operator') || context.references.users[context.request.author.id].roles.includes('transaction-operator')",
  "type": "Expression"
}
Workflows[
  {
   "left": {
    "left": {
     "role": " system-operator ",
     "quorum": 1,
     "type": " RoleQuorum "
    },
    "right": {
     "role": " policy-operator ",
     "quorum": 1,
     "type": " RoleQuorum "
    },
    "type": "Or"
   },
   "right": {
    "role": "transaction-operator",
    "quorum": 1,
    "type": " RoleQuorum "
   },
   "type": "Or"
  },
  {
   "role": "compliance",
   "quorum": 2,
   "type": "RoleQuorum"
  }
]