Finally, install the CDR application services. For these charts, ensure you set the image tag to the corresponding tag found in the latest release notes.

The examples below are pre-populated with the tags for [v2.19.0](/halo/v2190):

## 8.1 Engine

To integrate Halo with ReversingLabs, set the `enable_reversing_labs` variable to `true`. Ensure the required ReversingLabs secrets are created in Key Vault as described in Step 3.

```sh
enable_reversing_labs=""
helm upgrade --install cdrplatform-engine cdrplatform-engine \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.ENABLE_REVERSING_LABS="${enable_reversing_labs}" \
  --atomic
```

## 8.2 - Sync API

```sh
helm upgrade --install cdrplatform-sync-api cdrplatform-sync-api \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --atomic
```

## 8.3 API Access service

The API Access service acts as a gateway to the Glasswall Halo Synchronous API and the Policy Management API.

It exposes CDR functionality over HTTP. If your environment requires secure communication, configure the service to use HTTPS with TLS or SSL by following the TLS or SSL installation instructions. Otherwise, follow the instructions for installation without TLS or SSL.

### 8.3A - For deployments without TLS/SSL

```sh
helm upgrade --install cdrplatform-api-access cdrplatform-api-access \
 --set image.registry=glasswallhub.azurecr.io \
 --set image.tag=2.19.0-189642 \
 --atomic
```

### 8.3B - For deployments with TLS/SSL

To enable SSL on the CDR API, create a private key and certificate for the domain in use.

Create a Kubernetes secret from the private key and certificate files using the command below. This command creates a secret named `tls-secret` using `server.key` as the private key and `server.crt` as the certificate. In this example, the private key must not be protected by a passphrase.

```sh
kubectl create secret tls tls-secret --key server.key --cert server.crt
```

This secret can then be used to enable TLS on the ingress ensuring that the domain name is set in the command below:

```sh
helm upgrade --install cdrplatform-api-access cdrplatform-api-access \
  --set image.tag=2.19.0-189642\
  --set image.registry=glasswallhub.azurecr.io \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=<domain name> \
  --set ingress.tls.secretName=tls-secret \
  --atomic
```

### 8.3C - To enable basic API authentication

Authentication in Glasswall Halo is disabled by default. When enabled, it applies to both the Glasswall Halo Synchronous API and the Policy API.

To enable authentication:

- Create two secrets in Azure Key Vault. One secret stores the organisation ID, and the other stores the organisation tokens. When specifying multiple tokens, separate them with commas. Ensure that individual tokens do not contain commas. Azure Key Vault secrets must follow the naming conventions below:

>- **Organisation ID secret**
  >>- Must start with `organisation`
  >>- Must end with `-id`
  >>- Include a numeric index between the prefix and suffix  
  >>- Examples: `organisation0-id`, `organisation1-id`, `organisation2-id`

>- **Organisation tokens secret**
  >>- Must start with `organisation`
  >>- Must end with `-tokens`
  >>- Include a numeric index between the prefix and suffix  
  >>- Examples: `organisation0-tokens`, `organisation1-tokens`, `organisation2-tokens`

- Set `configuration.AuthenticationScheme=Basic` while deploying the Helm chart. For example:
  
>```sh
>helm upgrade --install cdrplatform-api-access  cdrplatform-api-access \
>  --set image.registry=glasswallhub.azurecr.io \
>  --set image.tag=2.19.0-189642 \
>  --set configuration.AuthenticationScheme=Basic \
>  --atomic
>```

### 8.3D - To enable Azure AD API authentication

To enable Azure AD based authentication, set `configuration.AuthenticationScheme=Bearer` and configure the `tenant_id` and `domain_name` variables when deploying the Helm chart.

Note that the app registration URI may vary depending on when the app was created. Always copy the app registration URI from the Azure portal and use it as the valid audience.

```sh
tenant_id=""
domain_name=""
valid_audiences="api://cdrplatform-api-access" or "api://${tenant_id}/cdrplatform-api-access" # (verify app registration URI from Azure)
helm upgrade --install cdrplatform-api-access cdrplatform-api-access --wait --atomic \
  --set image.tag="2.19.0-189642" \
  --set image.registry=glasswallhub.azurecr.io \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${domain_name} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.AuthenticationScheme="Bearer" \
  --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0=${valid_audiences} \
  --set configuration.Authentication__Schemes__Bearer__ValidIssuer=https://sts.windows.net/${tenant_id}/ \
  --set configuration.Authentication__Schemes__Bearer__Authority=https://login.microsoftonline.com/${tenant_id}/v2.0/
```

<details>
<summary><strong>Azure US Government Users</strong></summary>

Use the following command when deploying to Azure US Government.

These settings ensure the correct endpoints and environment values are used.

```bash
tenant_id=""
domain_name=""
valid_audiences="api://cdrplatform-api-access" or "api://${tenant_id}/cdrplatform-api-access" # (verify app registration URI from Azure portal)
helm upgrade --install cdrplatform-api-access cdrplatform-api-access --wait --atomic \
  --set image.tag="2.19.0-189642" \
  --set image.registry=glasswallhub.azurecr.io \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${domain_name} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.AuthenticationScheme="Bearer" \
  --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0=${valid_audiences} \
  --set configuration.Authentication__Schemes__Bearer__ValidIssuer=https://sts.windows.net/${tenant_id}/ \
  --set configuration.Authentication__Schemes__Bearer__Authority=https://login.microsoftonline.us/${tenant_id}/v2.0/
```

</details>

## 8.4 Portal

To deploy the Portal service, run the following commands:

### 8.4A - For deployments without TLS/SSL

**Note:** the `<IP-address>` mentioned in this command refers to the Load Balancer's public IP address. This can be retrieved through the "Portal & API Access" steps below.

```sh
helm upgrade --install cdrplatform-portal cdrplatform-portal \
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.BackendUrl="http://<IP-address>" \
  --set image.tag=2.19.0-189642 \
  --set configuration.HaloVersion=2.19.0 \
  --atomic
```

### 8.4B - For deployments with TLS/SSL

If TLS is required, add the `--set ingress.tls.enable_tls=true` parameter and set `portal_domain=<domain name>`.  

In the example below, the same Kubernetes secret created for the API Access service is used to retrieve the TLS certificates.

```sh
portal_domain=""
helm upgrade --install cdrplatform-portal cdrplatform-portal \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${portal_domain} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.BackendUrl="https://${portal_domain}" \
  --set configuration.HaloVersion=2.19.0 \
  --atomic
```

### 8.4C - Enable admin access without authentication

When Single Sign-On (SSO) login is not enabled in the Portal, administrative features, such as license management and policy configuration are not accessible. To enable access to these admin features without setting up SSO, deploy the Helm chart with the following configuration:

```sh
helm upgrade --install cdrplatform-portal cdrplatform-portal \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${portal_domain} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.AutoAdmin="true" \
  --atomic
```

### 8.4D To configure SSO login in Glasswall Halo's Portal

Set the `portal_domain`, `portal_client_id`, and `tenant_id` variables in the commands below, then run them.

The `portal_domain` is the domain name used to configure TLS for the Portal service and must match the domain used in the `cdrplatform-portal-client` app registration.

`portal_client_id` is the application (client) ID of the `cdrplatform-portal-client` app registration created in the prerequisites step.

`tenant_id` is of the tenant where APP registrations are created.

`enabled_pages` should contain various pages that needs to be enabled. Pass the values separated by comma(,).

For example it should be set to `SystemSettings\,PolicySettings\,ValidationSettings\,IcapSettings\,IcapRequests\,IcapReporting` when Policy API, ICAP server and ReversingLabs is deployed, Or set it to `SystemSettings\,PolicySettings\,ValidationSettings` if only Policy API is deployed.

If none of the Policy API and ICAP server are deployed, set it to `enabled_pages="SystemSettings"`.

```sh
portal_domain=""
portal_client_id=""
tenant_id=""
enabled_pages="SystemSettings\,PolicySettings\,ValidationSettings"
helm upgrade --install cdrplatform-portal cdrplatform-portal \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${portal_domain} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.BackendUrl="https://${portal_domain}" \
  --set configuration.EnabledPages=${enabled_pages} \
  --set configuration.OIDC.ProviderOptions.Authority="https://login.microsoftonline.com/${tenant_id}/v2.0" \
  --set configuration.OIDC.ProviderOptions.RedirectUri="https://${portal_domain}/authentication/login-callback" \
  --set configuration.OIDC.ProviderOptions.ClientId="${portal_client_id}" \
  --set configuration.OIDC.ProviderOptions.PostLogoutRedirectUri="https://${portal_domain}/authentication/logout-callback" \
  --set configuration.HaloVersion=2.19.0 \
  --atomic
```

<details>
<summary><strong>Azure US Government Users</strong></summary>

Use the following command when deploying to Azure US Government.

These settings ensure the correct endpoints and environment values are used.

```bash
portal_domain=""
portal_client_id=""
tenant_id=""
enabled_pages="SystemSettings\,PolicySettings\,ValidationSettings"
helm upgrade --install cdrplatform-portal cdrplatform-portal \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=${portal_domain} \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.BackendUrl="https://${portal_domain}" \
  --set configuration.EnabledPages=${enabled_pages} \
  --set configuration.OIDC.ProviderOptions.Authority="https://login.microsoftonline.us/${tenant_id}/v2.0" \
  --set configuration.OIDC.ProviderOptions.RedirectUri="https://${portal_domain}/authentication/login-callback" \
  --set configuration.OIDC.ProviderOptions.ClientId="${portal_client_id}" \
  --set configuration.OIDC.ProviderOptions.PostLogoutRedirectUri="https://${portal_domain}/authentication/logout-callback" \
  --set configuration.HaloVersion=2.19.0 \
  --set appenvironment.HTTP_CSP_CONNECT_SRC="'self'https://login.microsoftonline.us https://graph.microsoft.us" \
  --set appenvironment.HTTP_CSP_FRAME_SRC="'self' https://login.microsoftonline.us" \
  --set appenvironment.HTTP_CSP_FRAME_ANCESTORS="'self' https://login.microsoftonline.us" \
  --atomic
```

</details>

## 8.5 Portal access

Portal Access acts as the backend for the Portal. It enables the Halo Portal to access the Policy Management API and the Synchronous API.

### 8.5A For deployments with TLS/SSL

If TLS is required, add the `--set ingress.tls.enable_tls=true` and `--set ingress.tls.domain=<domain name>` parameters.

In the example below, the same Kubernetes secret created for the API Access service is used to retrieve the TLS certificates.

```sh
helm upgrade --install cdrplatform-portal-access cdrplatform-portal-access \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --set ingress.tls.enabled=true \
  --set ingress.tls.domain=<domain-name> \
  --set ingress.tls.secretName=tls-secret \
  --set configuration.AuthenticationScheme=None \
  --atomic
```

### 8.5B For deployments without TLS/SSL

```sh
helm upgrade --install cdrplatform-portal-access cdrplatform-portal-access \
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.AuthenticationScheme=None \
  --set image.tag=2.19.0-189642 \
  --atomic
```

### 8.5C Without authentication

```sh
helm upgrade --install cdrplatform-portal-access cdrplatform-portal-access \
 --set image.registry=glasswallhub.azurecr.io \
 --set image.tag=2.19.0-189642 \
 --set configuration.AuthenticationScheme=None \
 --atomic
```

### 8.5D To enable Azure AD authentication

Portal Access enables SSO authentication using Azure AD.

Set the `tenant_id` and `portal_domain` variables in the commands below, then run them.

Note that the APP registration URI may vary depending on when it was created. Always copy the app registration URI from the Azure portal and use it as the valid audience.

```sh
tenant_id=""
portal_domain=""
valid_audiences=""  # Application (client) ID of the cdrplatform-portal-access app registration (copy from Azure portal)
helm upgrade --install cdrplatform-portal-access cdrplatform-portal-access \
 --set image.registry=glasswallhub.azurecr.io \
 --set image.tag=2.19.0-189642 \
 --set ingress.tls.enabled=true \
 --set ingress.tls.domain=${portal_domain} \
 --set ingress.tls.secretName=tls-secret \
 --set configuration.AuthenticationScheme=Bearer \
 --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0=${valid_audiences} \
 --set configuration.Authentication__Schemes__Bearer__ValidIssuer=https://sts.windows.net/${tenant_id}/ \
 --set configuration.Authentication__Schemes__Bearer__Authority=https://login.microsoftonline.com/${tenant_id}/v2.0/ \
 --atomic
```

<details>
<summary><strong>Azure US Government Users</strong></summary>

Use the following command when deploying to Azure US Government.

These settings ensure the correct endpoints and environment values are used.

```bash
tenant_id=""
portal_domain=""
valid_audiences=""  # Application (client) ID of the cdrplatform-portal-access app registration (copy from Azure portal)
helm upgrade --install cdrplatform-portal-access cdrplatform-portal-access \
 --set image.registry=glasswallhub.azurecr.io \
 --set image.tag=2.19.0-189642 \
 --set ingress.tls.enabled=true \
 --set ingress.tls.domain=${portal_domain} \
 --set ingress.tls.secretName=tls-secret \
 --set configuration.AuthenticationScheme=Bearer \
 --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0=${valid_audiences} \
 --set configuration.Authentication__Schemes__Bearer__ValidIssuer=https://sts.windows.net/${tenant_id}/ \
 --set configuration.Authentication__Schemes__Bearer__Authority=https://login.microsoftonline.us/${tenant_id}/v2.0/ \
 --atomic
```

</details>

## 8.6 Policy Management API

The Policy Management API is used to manage Glasswall Halo content management flags. This service is optional and should be installed only if you plan to create and use custom policies.

```sh
helm upgrade --install cdrplatform-policy-api  cdrplatform-policy-api \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --set configuration.DATABASE__Provider=${database_provider}
```

- The Policy Management API swagger page can be accessed using:

>```
>http://<ip>/swagger/index.html
>```

## 8.7 License Management

The License Management service is used to manage licenses in the Glasswall Halo Portal.

```sh
helm upgrade --install cdrplatform-license-management cdrplatform-license-management -n license-management\
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --set configuration.DATABASE__Provider=${database_provider} \
  -n license-management \
  --atomic
```

## 8.8 Clean up service

The Clean up service deletes original and rebuilt files from persistent storage after processing is complete.

```sh
helm upgrade --install cdrplatform-cleanup cdrplatform-cleanup \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=2.19.0-189642 \
  --atomic
```

## 8.9 Asynchronous API

The Asynchronous API can be deployed using the command below. A MongoDB database is required for the Asynchronous API.

```sh
helm upgrade --install cdrplatform-async-api cdrplatform-async-api \
  --set image.tag=2.19.0-189642\
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.DATABASE__Provider=${database_provider} \
  --atomic
```

## 8.10 Metrics projection

The Metrics projection service is used to pull reporting data from MongoDB to display in the Halo Portal UI.

```sh
helm upgrade --install cdrplatform-metrics-projection cdrplatform-metrics-projection \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.DATABASE__Provider=${database_provider} \
  --set cloud_provider=azure \
  --atomic
```

## 8.11 Report extractor

The Report extractor service extracts analysis reports and publishes them for reporting.

```sh
helm upgrade --install cdrplatform-report-extractor cdrplatform-report-extractor \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --atomic
```

## 8.12 Tally accumulator

The Tally accumulator service tracks and maintains a tally of usage statistics.

```sh
helm upgrade --install cdrplatform-tally-accumulator cdrplatform-tally-accumulator \
  --set image.tag=2.19.0-189642 \
  --set image.registry=glasswallhub.azurecr.io \
  --set configuration.DATABASE__Provider=${database_provider} \
  --atomic
```

## 8.13 MongoDB

**Note:** if MongoDB is already configured in Azure and you do not want to install or manage MongoDB within your cluster, you can skip this step and proceed.

### MongoDB operator

```sh
helm install community-operator mongodb/community-operator --namespace cdrplatform \
  --set operator.version=0.9.0 \
  --set agent.version=107.0.0.8465-1 \
  --atomic
```

### Install MongoDB

```sh
helm upgrade -i cdrplatform-mongodb cdrplatform-mongodb -n cdrplatform --atomic \
  --set cloud_provider=azure
```

- Retrieve the connection string from the Kubernetes secret

```sh
kubectl get secret mongodb-cdrplatform-cdrp-user -o jsonpath='{.data.connectionString\.standard}' | base64 -d
```

- Update the Azure Key Vault secret with the MongoDB connection string

```sh
az keyvault secret set --name "mongodb-connectionstring" --vault-name "${kvname}" --value "<output-from-previous-step>"
```

## 8.14 Storage Monitoring Service

The Storage Monitoring service provides an API to subscribe and track changes made to documents in configured storage mechanisms such as SharePoint and OneDrive.

TLS must be enabled for the Webhook.

Add the `--set ingress.tls.enable_tls=true` and `--set ingress.tls.domain=<domain name>` parameters.

In the example below, the same Kubernetes secret created for the API Access service is used to retrieve the TLS certificates.

```sh
helm upgrade --install cdrplatform-storage-monitor cdrplatform-storage-monitor --wait --atomic \
    --set image.tag="2.19.0-189642" \
    --set image.registry=glasswallhub.azurecr.io \
    --set configuration.DATABASE__Provider="${database_provider}" \
    --set configuration.WEBHOOKS__CallbackBaseAddress="https://<domain-name>" \
    --set ingress.tls.enabled=true \
    --set ingress.tls.domain=<domain-name> \
    --set ingress.tls.secretName=tls-secret \
    --atomic
```

## 8.15 Optional Prometheus scaling

Install the Prometheus scaling chart only if you want to enable Prometheus-based scaling.

```sh
helm upgrade --install prometheus-scaling prometheus-scaling --wait --atomic \
  --set image.registry=glasswallhub.azurecr.io \
  --set image.tag=3.10.0 \
  --set imagePullSecrets[0].name=acr-secret \
  --set keda.icap.enabled=<true|false>
```

## 8.16 Portal & API Access

Use the following command to determine the external IP address associated with your cluster.

The external IP corresponds to the public IP address assigned to the Azure load balancer.

```sh
kubectl get services --namespace cdrplatform nginx-ingress-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}'
```

You can now use the IP returned above to navigate to the Halo Portal and API documentation (use https if TLS enabled):

```
Portal: http://<ip>
API Documentation: http://<ip>/swagger/index.html
```


<!-- markdownlint-disable MD033 -->
<div class="text--center margin-top--lg" style={{display: 'flex', justifyContent: 'center', gap: '12px'}}>
  <a href="https://www.glasswall.com/support" class="button button--primary">
    Need help →
  </a>

</div>
<!-- markdownlint-disable MD033 -->