# Security

Each layer of the Ripple Custody architecture consists of several microservices that are distributed as containerized applications. All containers are signed so that the integrity of the container and of the publisher of the container can be verified.

Internal communication between the components is authenticated and encrypted with Transport Layer Security (TLS).

The separation of components into layers ensures that Ripple Custody minimizes the attack surface for security critical components, while remaining agile, scalable, and modular for the other layers. The interaction and core layers rely on a Kubernetes setup: the security layer is designed to be deployed on confidential computing enclaves, to ensure integrity during execution.

The Ripple components communicate with customer-managed vaults and key management systems (KMS), giving you exclusive control over the enforcement of entitlements, the execution of transactions, and the management of cryptographic keys.

## Key concepts

The key concepts of the Ripple Custody security model are:

- Trusted and untrusted components
- Entities
- Merkle tree
- Anti-rewind file


### Trusted components

Trusted components are components with a sufficient level of security to access secure external components.

The governance engine is trusted.

### Untrusted components

Untrusted components are components that do not need a high level of security. If the components are fully compromised, they do not compromise the security of the trusted components.

The interaction and core components are untrusted, as is the database.

### Entities

Entities are the data objects that make up the Ripple Custody environment and governance model. As with components, entities can be trusted or untrusted, based on their level of security.

#### Trusted entities

The majority of Ripple Custody entities are trusted, as they are protected by the data security model described in [Data security](#data-security). They are
as follows:

- Domains
- Vaults
- Ledgers
- Accounts
- Tickers
- Intents
- Endpoints
- Policies
- Transaction orders
- Users


#### Untrusted entities

Ripple Custody also includes untrusted entities, which are used or exposed to users without a signature. All untrusted entities need to be protected with standard database security, to prevent unauthorized alterations.

Untrusted entities are as follows:

- Fees
- Addresses
- Balances
- Transactions
- Transfers
- Requests
- Events


### Merkle tree

Entities are versioned and signed, and the complete state, along with past revisions and a snapshot, are maintained as part of a Merkle tree. This is a signed, tamper-proof data structure in which every leaf node of the tree contains the cryptographic hash of a data block and every non-leaf node contains the concatenated hashes of its child nodes. Only the governance engine updates the Merkle tree.

This means that all entities that form part of the system state are fully resilient to at-rest and in-transit attacks.

### Anti-rewind file

The anti-rewind file (ARF) keeps track of the version of the most up-to-date Ripple Custody state, where the Ripple Custody state is defined as the set of trusted entity collections, that is, the set of all the domains, users, policies, and other system entities. This tracking is protected by cryptographic signatures and is therefore tamper-proof.

The ARF is an important security protection against replay attacks. Examples of attacks the file helps protect against are:

- Attempts to revert the system to a previous state.
- Attempts to resubmit a previously submitted intent.


When a request is made to the governance engine to change the state of the system with an intent, the governance engine evaluates the integrity of the current state, before proceeding to the update. For example, for an intent to create a transaction, the governance engine verifies the integrity of the applied policy to ensure that a correct policy is applied and not a policy that could have been tampered with. Since policies can be modified, the governance engine does not simply check for authenticity, but also that the most up-to-date version of that policy is being used.

Similarly, if the governance engine needs to create a transaction, the governance engine needs to ensure it is accessing the latest version of the transactions collection to make sure the transaction was not already created.

This version tracking is managed with the ARF. If the file is lost, corrupted, or inaccessible for any reason, the governance engine stops processing intents, making it impossible to use Ripple Custody for any write operation. Write operations can only resume if the file is recovered or rebuilt.

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

## Component security

The governance engine is responsible for enforcing governance policies, for ensuring the integrity of the system state as a whole (with appropriate versioning and digital signatures of state mutations), for maintaining a full audit trail, and for ordering the execution of transactions on a given vault.

The governance engine and vaults have mutual trust at the application layer so they can exchange information with no risk of a man-in-the-middle attack.

For more information, see [Components](/products/custody/v1.15/overview/architecture/infra-components).

## Data security

Trust in the state of the system is critical to the integrity of the execution process and the confidence given to the auditing process. The data security approach in Ripple Custody is inspired by blockchain technology.

### System update flow

Entities that make up the secure Ripple Custody data model are signed and protected by the governance engine.

Updates to the system state are requested and governed using the standard governance workflow described in [Governance workflow](/products/custody/v1.15/overview/governance#governance-workflow).

Ripple Custody enforces data integrity during the governance workflow with the following process:

![](/assets/system-update-flow.6fdd412eb22f5a155654be4b8c71b209a7e3da405a304bc3e3a9037809a99e4d.0d4a565c.png)

| Step | Description |
|  --- | --- |
| Merkle tree validation | Ripple Custody ensures validation of user requests to change data as follows:The system state is extracted from the database and shared with the governance engine alongside the intent to be executed.The governance engine verifies the version of the Merkle tree with its local version counter, validates its root signature with the governance engine public key, and checks its exact correspondence to the provided state data.The governance engine checks the user signature of the intent against the public key of the user that submitted the request.With this process, any attempt to tamper with the data is identified and rejected before the execution of a potentially compromised state mutation. |
| State mutation | The state is updated to its new version, by adding or updating the entities in the request. |
| Merkle-proofed generation | The Merkle tree is updated with the hash of the mutated entity. Its new root is signed by the governance engine, which also updates its local state in the anti-rewind file. |
| Entity signature | Each new entity is atomically signed to ensure consistency. This allows any third-party integrator to ensure the data was notarized by Ripple Custody. For system updates with a side effect, proof of state mutation is made available to the vault for execution. |


## End-to-end security

All information that is shared between the governance engine and the vault is signed and verified on both ends. A key exchange performed during system setup ensures a chain of trust is built between the security critical components.

For more information, see [Governance engine and vault keys](/products/custody/v1.15/overview/key-management#governance-engine-and-vault-keys).