# Red Hat OpenShift

This is an OpenShift-specific guide on how to deploy Immuta with the following managed services:

* Cloud-managed PostgreSQL
* Cloud-managed Redis
* Cloud-managed Elasticsearch

## Prerequisites

Review the following criteria before proceeding with deploying Immuta.

### PostgreSQL

1. The PostgreSQL instance has been provisioned and is actively running.
2. The PostgreSQL instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](https://documentation.immuta.com/2024.2/troubleshooting#common).
3. The PostgreSQL instance is [accepting connections](https://documentation.immuta.com/2024.2/troubleshooting#postgresql).
4. The Helm chart only supports username/password authentication for PostgreSQL. At this time, other authentication mechanisms are not supported.

### Redis

1. The Redis instance has been provisioned and is actively running.
2. The Redis instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](https://documentation.immuta.com/2024.2/troubleshooting#common).
3. The Redis instance is [accepting connections](https://documentation.immuta.com/2024.2/troubleshooting#redis).

### Elasticsearch

1. The Elasticsearch instance has been provisioned and is actively running.
2. The Elasticsearch instance's hostname/FQDN is [resolvable from within the Kubernetes cluster](https://documentation.immuta.com/2024.2/troubleshooting#common).
3. The Elasticsearch instance is [accepting connections](https://documentation.immuta.com/2024.2/troubleshooting#elasticsearch).
4. The user must have the [required permissions](https://documentation.immuta.com/2024.2/deployment-requirements#opensearch-user).
5. The Helm chart only supports username/password authentication for Elasticsearch. At this time, other authentication mechanisms are not supported.

## Authenticate with OCI registry

{% hint style="warning" %}
**Helm chart availability**

The deprecated Immuta Helm chart (IHC) is not available from ocir.immuta.com.
{% endhint %}

Copy the snippet below and replace the placeholder text with the credentials provided to you by your customer success manager:

```shell
echo <token> | helm registry login --password-stdin --username <username> ocir.immuta.com
```

## Setup

1. Create a new OpenShift project named `immuta` for Immuta.

   ```shell
   oc new-project immuta
   ```
2. Get the UID range allocated to the project. Each running container's UID must fall within this range. This value will be referenced later on.

   ```shell
   oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
   ```
3. Get the GID range allocated to the project. Each running container's GID must fall within this range. This value will be referenced later on.

   ```shell
   oc get project immuta --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
   ```
4. Switch to project `immuta`.

   ```shell
   oc project immuta
   ```
5. Create a container registry pull secret. Your credentials to authenticate with ocir.immuta.com can be viewed in your user profile at [support.immuta.com](https://support.immuta.com).

   ```bash
   oc create secret docker-registry immuta-oci-registry \
       --docker-server=https://ocir.immuta.com \
       --docker-username="<username>" \
       --docker-password="<token>" \
       --docker-email=support@immuta.com
   ```

### Cloud-managed PostgreSQL

{% hint style="info" %}
**Connecting to the database**

There are numerous ways to connect to a PostgreSQL database. This step demonstrates how to connect by creating an ephemeral Kubernetes pod.
{% endhint %}

1. Connect to the database as superuser (postgres) by creating an ephemeral container inside the Kubernetes cluster. A shell prompt will not be displayed after executing the `oc run` command outlined below. Wait 5 seconds, and then proceed by entering a password.

   ```bash
   oc run pgclient \
       --stdin \
       --tty \
       --rm \
       --image docker.io/bitnami/postgresql -- \
       psql --host <postgres-fqdn> --username <postgres-admin> --dbname postgres --port 5432 --password
   ```
2. Create an `immuta` role and database.

   ```sql
   CREATE ROLE immuta with login encrypted password '<postgres-password>';

   GRANT immuta TO CURRENT_USER;

   CREATE DATABASE immuta OWNER immuta;

   GRANT all ON DATABASE immuta TO immuta;
   ALTER ROLE immuta SET search_path TO bometadata,public;
   ```
3. Revoke privileges from `CURRENT_USER` as they're no longer required.

   ```sql
   REVOKE immuta FROM CURRENT_USER;
   ```
4. Enable the `pgcrypto` extension.

   ```sql
   \c immuta
   CREATE EXTENSION pgcrypto;
   ```
5. Type `\q`, and then press `Enter` to exit.

## Install Immuta

{% hint style="warning" %}
**Audit records**

**Preserving legacy audit records**

Immuta does not migrate legacy audit records to the [universal audit model (UAM)](https://documentation.immuta.com/2024.2/detect-your-activity/audit/reference-guides/universal-audit-model-uam), so when you upgrade Immuta those audit records will be lost unless you enable the following setting in your immuta-values.yaml file:

```
secure:
  extraEnvVars:
    - name: FeatureFlag_auditLegacyViewHide
      value: "false"
```

**Audit record retention**

Immuta defaults to keeping audit records for 7 days. To change this duration, set the following values in the immuta-values.yaml file. The example below configures audit records to be kept for 90 days:

```yaml
audit:
  deployment:
      extraEnvVars:
        - name: AUDIT_RETENTION_POLICY_IN_DAYS
          value: "90"
```

{% endhint %}

This section demonstrates how to deploy Immuta using the Immuta Enterprise Helm chart once the prerequisite cloud-managed services are configured.

1. Create a Helm values file named `immuta-values.yaml` with the content below. Because the Ingress resource will be managed by an OpenShift route you will create when [configuring Ingress](https://documentation.immuta.com/2024.2/configure/ingress-configuration#openshift-ingress-operator) and not the Immuta Enterprise Helm chart, `ingress` is set to `false` below. TLS comes pre-configured with OpenShift, so `tls` is also set to `false`.

   ```yaml
   global:
     imageRegistry: ocir.immuta.com
     imagePullSecrets:
       - name: immuta-oci-registry
     imageRepositoryMap:
       immuta/immuta-service: stable/immuta-service
       immuta/immuta-db: stable/immuta-db
       immuta/immuta-fingerprint: stable/immuta-fingerprint
       immuta/audit-service: stable/audit-service
       immuta/audit-export-cronjob: stable/audit-export-cronjob
       immuta/classify-service: stable/classify-service
       immuta/cache: stable/cache

   audit:
     config:
       databaseConnectionString: postgres://immuta:<postgres-password>@pg-db-postgresql.immuta.svc.cluster.local:5432/immuta?schema=audit
       elasticsearchEndpoint: http://es-db-elasticsearch.immuta.svc.cluster.local:9200
       elasticsearchUsername: <elasticsearch-username>
       elasticsearchPassword: <elasticsearch-password>

     deployment:
       podSecurityContext:
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
         runAsUser: <user-id>
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
         runAsGroup: <group-id>
         seccompProfile:
           type: RuntimeDefault
         
       containerSecurityContext:
         allowPrivilegeEscalation: false
         capabilities:
           drop:
             - ALL

   discover:
     deployment:
       podSecurityContext:
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
         runAsUser: <user-id>
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
         runAsGroup: <group-id>
         seccompProfile:
           type: RuntimeDefault
         
       containerSecurityContext:
         allowPrivilegeEscalation: false
         capabilities:
           drop:
             - ALL

   secure:
     extraEnvVars:
       - name: FeatureFlag_AuditService
         value: "true"
       - name: FeatureFlag_detect
         value: "true"
       - name: FeatureFlag_auditLegacyViewHide
         value: "true"

     ingress:
       enabled: false
       tls: false

     postgresql:
       host: <postgres-fqdn>
       port: 5432
       database: immuta
       username: immuta
       password: <postgres-password>
       ssl: false

     web:
       podSecurityContext:
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
         runAsUser: <user-id>
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
         runAsGroup: <group-id>
         seccompProfile:
           type: RuntimeDefault
         
       containerSecurityContext:
         allowPrivilegeEscalation: false
         capabilities:
           drop:
             - ALL

     backgroundWorker:
       podSecurityContext:
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.uid-range"}}{{"\n"}}'
         runAsUser: <user-id>
         # A number that is within the project range:
         #   oc get project <project-name> --output template='{{index .metadata.annotations "openshift.io/sa.scc.supplemental-groups"}}{{"\n"}}'
         runAsGroup: <group-id>
         seccompProfile:
           type: RuntimeDefault
         
       containerSecurityContext:
         allowPrivilegeEscalation: false
         capabilities:
           drop:
             - ALL
   ```
2. Update all [placeholder values](https://documentation.immuta.com/2024.2/self-managed-deployment/conventions) in the `immuta-values.yaml` file.

{% hint style="warning" %}
**Avoid these special characters in generated passwords**

whitespace, `$`, `&`, `:`, `\`, `/`, `'`
{% endhint %}

3. Deploy Immuta.

   ```shell
   helm install immuta oci://ocir.immuta.com/stable/immuta-enterprise \
       --values immuta-values.yaml \
       --version 2024.2.20
   ```

## Validation

1. Wait for all pods in the namespace to become ready.

   ```shell
   oc wait --for=condition=Ready pods --all
   ```
2. Determine the name of the Secure service.

   ```shell
   oc get service --selector "app.kubernetes.io/component=secure" --output name
   ```
3. Listen on local port `8080`, forwarding TCP traffic to the Secure service's port named `http`.

   ```shell
   oc port-forward service/<name> 8080:http
   ```

## Next steps

* [Configure Ingress](https://documentation.immuta.com/2024.2/configure/ingress-configuration#openshift-ingress-operator) to complete your installation and access your Immuta application.
* [Learn more about best practices for Immuta in Production](https://documentation.immuta.com/2024.2/self-managed-deployment/configure/immuta-in-production).
