# AWS

The Relay Server is the plumbing that all MPC communication goes through. It is built in a way that it is completely untrusted and so the MPC SDKs and MPC Vertex will encrypt all data before sending it through the Relay.
To deploy the Relay server on your cloud environment please read the guide below.

## Architecture

The self-hosted solution comes in two forms: a dedicated [Terraform module](https://developer.hashicorp.com/terraform/intro) per cloud provider, and a general use [Helm chart](https://helm.sh/docs/topics/charts/). Both should be run on your organization's computing infrastructure.
We recommend you first look at our example Terraform module and modify it according to your organization's needs.

## Requirements

Before starting the installation process, make sure you have the following installed:

1. The `terraform` [CLI](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).
2. The `aws` CLI tool for AWS.
   1. Make sure you are **logged in** (i.e `aws sso login`).
   2. Make sure your account has permissions to **create resources** (such as EKS clusters, load balancers, etc...).

In addition, this guide assumes you're running the provided example Terraform module as the root module (although most steps are applicable when running it as a submodule as well).

## Installation Process

The installation process consists of the following steps:

1. Collecting installation parameters
2. Obtaining a TLS certificate
3. Setting a preconfigured API key
4. Obtaining the Terraform Module
5. Applying the Terraform module
6. Setting the DNS record to `URL_ENDPOINT`
7. Modify existing code

### 1. Collecting Parameters

At this step you should collect the following pieces of information, listed down below.
At the end of each bullet we put in parentheses a capitalized name which will be used to refer to the value being set throughout the rest of this guide.

1. The endpoint URL that you wish to host your relay server at (`URL_ENDPOINT`).
2. The Sodot Artifactory user and token which provide access to the **Terraform modules, Helm charts, and Docker images** (`ARTIFACTORY_USER` and `ARTIFACTORY_TOKEN`). You can obtain these by following the [Obtaining Credentials](/relay-server/obtaining-artifacts-credentials) guide.

### 2. Obtaining a TLS Certificate

You should obtain a TLS certificate for the `URL_ENDPOINT` domain via AWS Certificate Manager. The certificate can either be requested or imported from an existing certificate.
We will need the unique ARN of your certificate (`TLS_CERT_ARN`).

### 3. Setting a Preconfigured API Key

When setting up your relay server, you should configure an API key.
This is done by passing the `relay_api_key` variable to the `terraform apply` invocation (more on that below).

The `relay_api_key` value is encoded as `KEY,NAME` where `KEY` is the base64url encoding (not plain base64) of a 16-byte value and `NAME` is the name of the API key.

:::info[Example]
To set a 16-byte API key with the following hexadecimal representation: `00112233445566778899aabbccddeeff` with the name `AdminKey` pass `relay_api_key=ABEiM0RVZneImaq7zN3u_w==,AdminKey` when invoking `terraform apply`.
:::

:::tip
A hexadecimal string can be base64url-encoded in bash-like shells using the following command.

```bash
$ echo -n '00112233445566778899aabbccddeeff' | xxd -r -p | base64 | tr '+/' '-_'
ABEiM0RVZneImaq7zN3u_w==
```
:::

### 4. Obtaining the Terraform Module

You can consume the **Relay Server** Terraform module from the Sodot private registry in one of two ways:

#### A. Use the module directly from the registry

First, you'll need to log in to the Sodot Terraform module registry using the credentials you obtained in the previous step.

```bash
terraform login repo.sodot.dev
```

Then, you can use the module directly from the registry by adding it to your Terraform configuration.
Add the following block to your `main.tf` (or similar) and run `terraform init`. Terraform will pull the module from your JFrog Artifactory registry at runtime.

```hcl
module "relay" {
  source  = "repo.sodot.dev/sodot-terraform-modules__sodot/relay/aws"
  ...
}
```

#### B. Download the raw Terraform module to customize it

1. Fetch the desired release (replace `<VERSION>` with a tag such as `v1.3.12`):

   ```bash
   curl -u "<ARTIFACTORY_USER>:<ARTIFACTORY_TOKEN>" \
     -O "https://repo.sodot.dev/artifactory/sodot-terraform-modules/sodot/relay/aws/<VERSION>.zip"
   ```

   Alternatively, you can use the Artifactory GUI instead.<br /><br />

2. Unzip and make it your root module:

   ```bash
   unzip <VERSION>.zip -d relay
   cd relay
   ```

### 5. Applying the Terraform Module to Your Cloud Environment

Setting up the Relay infrastructure is done with `terraform apply` (after `terraform init`).
Where you run those commands depends on the option you chose in [Obtaining the Terraform Module](#4-obtaining-the-terraform-module).

#### Configuring Terraform

The module’s inputs are declared in `variables.tf` and have sensible defaults where appropriate.
You **must** supply the following variables when invoking **both** `terraform apply` and `terraform destroy`:

* `artifactory_user=<ARTIFACTORY_USER>` - allows Terraform to install the relevant Helm chart and access the Relay image.
* `artifactory_token=<ARTIFACTORY_TOKEN>` - allows Terraform to install the relevant Helm chart and access the Relay image.
* `relay_helm_version=<RELAY_HELM_VERSION>` - the Helm chart version for the Relay deployment (for example: `4.0.1`).
* `relay_api_key=<RELAY_API_KEY>` - described [above](#3-setting-a-preconfigured-api-key).
* `tls_certificate_arn=<TLS_CERT_ARN>` - described [above](#2-obtaining-a-tls-certificate).
* `relay_dns_address=<URL_ENDPOINT>` - described [above](#1-collecting-parameters).

If you chose to download the zip, run this terraform command from the root module directory:

```bash
terraform init

terraform apply \
    -var "region=us-east-1" \
    -var "tls_certificate_arn=arn:aws:acm:us-xxxx-1:330782005503:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
    -var "artifactory_user=a_user" \
    -var "artifactory_token=XXXXXXXXXXX" \
    -var "relay_helm_version=4.0.1" \
    -var "relay_dns_address=my-relay.XXX.com" \
    -var "relay_api_key=ABEiM0RVZneImaq7zN3u_w==,AdminKey"
```

If not and you chose to use the module directly from the registry, run the same command from the root module directory which references `module "relay"`.

### 6. Setting the DNS Record for `URL_ENDPOINT` to Point to the Relay Server

After running `terraform apply` successfully, the resulting load-balancer hostname address will be output under the name `load_balancer_hostname`.

After getting the load-balancer hostname of your Relay Server, you will need to create an A record for `URL_ENDPOINT` that points to that address (you can also use an A-alias record to point directly at the load balancer object).
Then, at `https://URL_ENDPOINT` you will be able to communicate with your Relay server.

To verify, you can run:

```bash
curl -H "Authorization: Bearer <RELAY_API_KEY>" https://URL_ENDPOINT/create_room/2
```

Note that `<RELAY_API_KEY>` here is only the `KEY` portion of the `relay_api_key` value, without the `,NAME` suffix (for the example above: `ABEiM0RVZneImaq7zN3u_w==`).

Which should yield a new room ID string if a Relay Server is configured behind the address correctly.

### 7. Modify Existing Code

By default, the `Ecdsa`,`Ed25519`,`StatefulEcdsa` and `StatefulEd25519` classes are routed to a Sodot owned Relay Server. This can be changed by supplying an additional parameter specifying the URL of the on-prem Relay Server.

For instance, consider the `const ecdsa = new Ecdsa()` constructor call.
Calling it should now be made with the extra parameter of `URL_ENDPOINT` like so:

```typescript
const ecdsa = new Ecdsa(URL_ENDPOINT);
```

The same holds for the calling to any of the following constructors as well:

```typescript
const ed25519 = new Ed25519(URL_ENDPOINT);
const ecdsa = new StatefulEcdsa(URL_ENDPOINT);
const ed25519 = new StatefulEd25519(URL_ENDPOINT);
```

More information can be reviewed in the API references for each of the different classes.

* [`new Ecdsa()`](/web/api-ref/classes/Ecdsa#new-ecdsa)
* [`new Ed25519()`](/web/api-ref/classes/Ed25519#new-ed25519)
* [`new StatefulEcdsa()`](/rn/api-ref/classes/StatefulEcdsa#new-statefulecdsa) (React Native SDK)
* [`new StatefulEd25519()`](/rn/api-ref/classes/StatefulEd25519#new-statefuled25519) (React Native SDK)
