# Azure

Sodot MPC Vertex is a self-hosted deployable service that represents an MPC party for MPC operations (such as keygen, sign, refresh etc.).
It takes care of storing the secret share, as well as running the MPC operations themselves. It can be used seamlessly with all Sodot MPC SDKs.
The Vertex exposes a REST API, documented [here](https://docs.sodot.dev/vertex-api-reference), that allows creating and managing secret shares easily.

## Architecture

The self-hosted solution comes in two forms: a dedicated [Terraform module](https://developer.hashicorp.com/terraform/intro) and a [Helm chart](https://helm.sh/docs/topics/charts/) (which the Terraform module uses internally). 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 `az` CLI tool for Azure.
3. Make sure you are **logged in** (i.e `az login`).
4. Make sure your account has permissions to **create resources** (such as 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 is made of the following steps:

1. Collecting installation parameters
2. Obtaining a TLS certificate
3. Obtaining the Terraform module
4. (Optional) Setting Up Azure Confidential Containers
5. Applying the Terraform module to your cloud environment
6. Setting the DNS Record for `URL_ENDPOINT` to point to the Vertex

### 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 Vertex at (`URL_ENDPOINT`).
2. The Sodot Docker registry user and token which provides access to all relevant Helm charts, Docker images and Terraform modules (`ARTIFACTORY_USER` and `ARTIFACTORY_TOKEN`). You can obtain these by following the [Obtaining Credentials](/vertex/deployment/obtaining-artifacts-credentials) guide.
3. The product you wish to deploy over the Vertex (`PRODUCT`).
   Currently, the supported products are `mpc-infra` and `exchange-api-vault`.

### 2. Obtaining a TLS Certificate

You should obtain a TLS certificate for the `URL_ENDPOINT` domain.
The certificate should be configured inside an instance of [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault) (`KEY_VAULT_NAME`). To use this certificate for the Vertex, make sure you pass the relevant variables when performing the `terraform apply` operation (more on that specifically below).

### 3. Obtaining the Terraform Module

You can consume the **Vertex** Terraform module from the Sodot private registry by downloading it as a zip file by its version.

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

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

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

2. Unzip and make it your working directory:

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

### 4. Secure Key Release (SKR) with Azure Confidential Workloads on ACI

:::info[Secure Key Release Feature]
Secure Key Release (SKR) is a functionality of Azure Key Vault (AKV) Managed HSM.

Secure key release enables the release of an HSM protected key from AKV to an attested Trusted Execution Environment (TEE), such as the Vertex confidential workload on ACI Deployment.

SKR adds another layer of access protection to your data decryption/encryption keys where you can let only a specific application + TEE runtime environment with known configuration get access to the key material (in our case, only the Vertex will be able to access the DB encryption key).

The SKR policies defined at the time of the KEK (key encryption key) creation govern the access to these keys.
:::

In order to use the SKR feature, you will need to [spawn and activate a new Managed HSM instance](https://learn.microsoft.com/en-us/azure/key-vault/managed-hsm/quick-create-cli), with you as the Managed HSM Administrator.
After activating the Managed HSM, you will have to give yourself the `Managed HSM Crypto Officer` role (using the `Local RBAC` tab of the mHSM resource) in order to be able to create and manage keys.

In order to run the Vertex as a confidential workload on ACI, the Terraform module needs to generate a Kata policy, which is specific to your environment thus has to be generated locally.
As the policy generation requires access to the Azure CLI, and specifically to the `az confcom` extension, there are two options to perform this step:

**Option A**: If you are running on a Linux machine, you can just install the `confcom` extension and run the terraform commands directly from your machine.

**Option B**: If you are running on MacOS (as the `confcom` extension is not supported), or do not wish to install the `confcom` extension on your machine, you can use the provided Dockerfile to build a container that will run the terraform commands for you.

#### Linux with confcom Extension

If you are running on a Linux machine, you can install the `confcom` extension by running:

```bash
az extension add --name confcom
```

#### MacOS Builder Image

Inside the downloaded terraform code directory, build the builder image:

```bash
    cd policy_builder
    # build the image
    docker build . -t sodot-policy-terraform
    cd ..
```

Now prepare the builder with all required credentials:

```bash
    # Create a docker volume to store your az credentials
    docker volume create azure_creds

    # Create a docker volume to store your artifactory credentials
    docker volume create docker_creds

    # First, login to az cli and store the creds
    docker run -v azure_creds:/root/.azure -v docker_creds:/root/.docker -it sodot-policy-terraform az login

    # Second, login to docker.io using Sodot Artifactory token - fill the token as the requested password
    docker run -v azure_creds:/root/.azure -v docker_creds:/root/.docker -it sodot-policy-terraform docker login repo.sodot.dev -u <ARTIFACTORY_USER> -p <ARTIFACTORY_TOKEN>
```

Finally, run the terraform commands inside the builder image from the **root** directory of the repo:

```bash
    # Run these commands in the terraform code directory
    docker run -v azure_creds:/root/.azure -v docker_creds:/root/.docker -v .:/root/ -it sodot-policy-terraform terraform init

    docker run -v azure_creds:/root/.azure -v docker_creds:/root/.docker -v .:/root/ -it sodot-policy-terraform terraform apply

    # You can use the same command to perform other tf commands (e.g. destroy)
```

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

Setting up the relevant infrastructure is performed by running `terraform init` followed by `terraform apply`.
Where you run those commands depends on the option you chose in [Obtaining the Terraform Module](#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`:

* `azure_subscription_id` - the ID of the Azure subscription where the cluster will be provisioned.
* `location` - the location at which the cluster (and the rest of the resources) will be provisioned.
* `artifactory_user=<ARTIFACTORY_USER>` - provides Terraform with permissions to pull the Helm chart and the Vertex Docker image.
* `artifactory_token=<ARTIFACTORY_TOKEN>` - provides Terraform with permissions to pull the Helm chart and the Vertex Docker image.
* `product_name=<PRODUCT>` - the Sodot product to deploy over the Vertex (e.g. `mpc-infra` or `exchange-api-vault`).
* `sodot_relay_api_key=<RELAY_API_KEY>` - an API key for accessing the Sodot Relay Server.
* `sodot_relay_url=<RELAY_URL>` - the URL for your organization's deployed Relay Server.
* `admin_access_token=<ADMIN_TOKEN>` - the secret admin token that will be used to set up all other users of the Vertex.
* `tls_cert_key_vault_name=<KEY_VAULT_NAME>` - configure the name of the key vault holding the certificate.
* `tls_cert_rg_name=<KEY_VAULT_RESOURCE_GROUP>` - configure which Resource Group the key vault is associated with.
  * NOTE: This is **not** the Resource Group that the Vertex cluster will be created under.
* `tls_cert_uri=<CERTIFICATE_ID>` - the ID (URI) of the certificate that will be used for TLS termination.
* `vertex_dns_address=<URL_ENDPOINT>` - equal to `URL_ENDPOINT`.
* `secure_key_release_encryption_hsm_name=<HSM_NAME>` - the name of the Managed HSM instance that will be used for SKR (see above requirements).
* `secure_key_release_encryption_hsm_rg_name=<HSM_RESOURCE_GROUP>` - the name of the Resource Group that the Managed HSM instance is associated with.

The rest of the variables have sensible defaults, but it is recommended to go over them and customize them for your own needs.

:::tip[Backup Settings]
If you wish to backup your key shares manually, consult the [Backing Up Key Shares](/vertex/backup_key_shares#configuring-backup-settings-for-the-vertex) guide for more Terraform configurations and info.
:::

The Terraform module will attempt to create a new Resource Group for all of its resources. To change this behavior, you can modify the following optional variable:

* `existing_resource_group_name` - will reuse the specified existing Resource Group instead of creating a new one when provisioning resources.

Example for **option B** (inside the unzipped directory):

```bash
terraform init

terraform apply \
    -var "azure_subscription_id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" \
    -var "location=westus" \
    -var "tls_cert_uri=https://keyvault-xx.vault.azure.net/secrets/cert-xx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -var "tls_cert_key_vault_name=keyvault-xx" \
    -var "tls_cert_rg_name=DefaultResourceGroup-XXX" \
    -var "artifactory_user=my-artifactory-user" \
    -var "artifactory_token=my-artifactory-token" \
    -var "product_name=mpc-infra" \
    -var "sodot_relay_api_key=ABEiM0RVZneImaq7zN3u8g==" \
    -var "sodot_relay_url=my-relay.XXXXX.com" \
    -var "admin_access_token=XXXXXXXXXXXXXXXXXX" \
    -var "vertex_dns_address=my-vertex.XXXXX.com" \
    -var "secure_key_release_encryption_hsm_name=my-hsm-name" \
    -var "secure_key_release_encryption_hsm_rg_name=my-hsm-resource-group"
```

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

After running `terraform apply` there will be a command that is output of the format:

```bash
az aks get-credentials --resource-group "<DATA_HERE>" --name "<MORE_DATA_HERE>"
```

Run this command and then run:

```bash
kubectl get ingress
```

To get the IP address for your Vertex.
Then you will need to create an A record for `URL_ENDPOINT` that points to that IP.
Then, at `https://URL_ENDPOINT` you will be able to communicate with your Vertex.

Now, you can run:

```bash
curl https://URL_ENDPOINT/health -vvv
```

To verify that you get an empty `200 OK` response from the Vertex and that it is indeed up and running.
