> ## Documentation Index
> Fetch the complete documentation index at: https://hoopdev-docs-changelog-1-43-2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes

This page provides instructions on how to configure the Helm chart to install Hoop in any cloud provider.

## Quick Start

<Steps>
  <Step title="Deploy the Gateway">
    ```sh theme={null}
    VERSION=$(curl -s https://releases.hoop.dev/release/latest.txt)
    helm upgrade hoop --install oci://ghcr.io/hoophq/helm-charts/hoop-chart --version $VERSION \
      --namespace hoopdev --create-namespace \
      --set postgres.enabled=true \
      --set defaultAgent.enabled=true \
      --set dataMasking.enabled=true \
      --set config.POSTGRES_DB_URI=postgres://root:default-pwd@hoopgateway-pg/postgres?sslmode=disable \
      --set config.API_URL=http://localhost:8009
    ```
  </Step>

  <Step title="Access it">
    1. Forward the hoopgateway service ports to your local machine to access the WebApp

    ```sh theme={null}
    kubectl port-forward service/hoopgateway 8009:8009 8010:8010 -n hoopdev
    ```

    2. [Visit the Webapp at http://127.0.0.1:8009/login](http://127.0.0.1:8009/login)

    <Note>
      The default installation method install a Postgres database with Host mounted storage.
      In case the node is decommissioned, all data will be lost.

      For more durable setups, use a Persistent Volume by providing the option below:

      * `--set postgres.storageClassName=<your-storage-class>`
    </Note>
  </Step>
</Steps>

## Installing

To install the latest version in a new namespace (example: `hoopdev`). Issue the command below:

```bash theme={null}
VERSION=$(curl -s https://releases.hoop.dev/release/latest.txt)
helm upgrade --install hoop \
  oci://ghcr.io/hoophq/helm-charts/hoop-chart --version $VERSION \
  -f values.yaml \
  --namespace hoopdev
```

### Overwriting or passing new attributes

It is possible to add new attributes or overwrite an attribute from a base `values.yaml` file.
In the example below a default agent is deployed as a sidecar container.

```bash theme={null}
helm upgrade --install hoop \
  oci://ghcr.io/hoophq/helm-charts/hoop-chart --version $VERSION \
  -f values.yaml \
  --set defaultAgent.enabled=true
```

## Database Configuration

Hoop uses Postgres as the backend storage of all data in the system.
It uses the schema `private` to create the tables of the system.
The command below creates a database and a user with privileges to access the database and the required schema.

```sql theme={null}
CREATE DATABASE hoopdb;
CREATE USER hoopuser WITH ENCRYPTED PASSWORD 'my-secure-password';
-- switch to the created database
\c hoopdb
CREATE SCHEMA IF NOT EXISTS private;
GRANT ALL PRIVILEGES ON DATABASE hoopdb TO hoopuser;
GRANT ALL PRIVILEGES ON SCHEMA public to hoopuser;
GRANT ALL PRIVILEGES ON SCHEMA private to hoopuser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO hoopuser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA private TO hoopuser;
```

<Note>
  In case of using a password with special characters, make sure to url encode it properly when setting the connection string.
</Note>

Use these values to assemble the configuration for POSTGRES\_DB\_URI:

* `POSTGRES_DB_URI=postgres://hoopuser:<passwd>@<db-host>:5432/hoopdb`

<Tip>
  Make sure to include `?sslmode=disable` option in the Postgres connection string in case your database setup doesn't support TLS.
</Tip>

## Agent Deployment

<AccordionGroup>
  <Accordion title="values.yaml (minimal)">
    ```yaml theme={null}
      config:
        HOOP_KEY: '<agent-key-dsn>'
    ```
  </Accordion>

  <Accordion title="values.yaml (full)">
    ```yaml theme={null}
    # base configuration
    config:
      HOOP_KEY: '<agent-key-dsn>'
      LOG_ENCODING: 'json' # json|console
      LOG_LEVEL: 'info' # debug|info|warn|error
      LOG_GRPC: '0' # 0|1|2

    # image default configuration
    image:
      repository: hoophq/hoopdev
      pullPolicy: Always
      tag: latest

    # define extra secret configuration to load as environment variables
    extraSecret: {}

    # -- Deployment strategy
    deploymentStrategy:
      type: Recreate

    # -- CPU/Memory resource requests/limits
    resources: {}
    #   limits:
    #     cpu: 1024m
    #     memory: 1Gi
    #   requests:
    #     cpu: 1024m
    #     memory: 1Gi

    # -- Node labels for pod assignment
    nodeSelector: {}

    # -- Toleration labels for pod assignment
    tolerations: []

    # -- Affinity settings for pod assignment
    affinity: {}

    ```
  </Accordion>
</AccordionGroup>

### Helm

Make sure you have helm installed in your machine. Check [Helm installation page](https://helm.sh/docs/intro/install/)

```bash theme={null}
VERSION=$(curl -s https://releases.hoop.dev/release/latest.txt)
helm upgrade --install hoopagent \
	oci://ghcr.io/hoophq/helm-charts/hoopagent-chart --version $VERSION \
	--set "config.HOOP_KEY=<AUTH-KEY>"
```

### Using Helm Manifests

```bash theme={null}
VERSION=$(curl -s https://releases.hoop.dev/release/latest.txt)
helm template hoopagent \
  oci://ghcr.io/hoophq/helm-charts/hoopagent-chart --version $VERSION \
  --set 'config.HOOP_KEY=<AUTH-KEY>' \
  --set 'image.tag=1.36.16' \
  --set 'extraSecret=AWS_REGION=us-east-1'
```

<Warning>
  Starting from version **1.21.9**, there is only one way to configure the agent key, which is by using the `config.HOOP_KEY` configuration. This requires creating a key in a DSN format in the API. To use legacy options, use the Helm chart version **1.21.4**.
</Warning>

### Standalone Deployment

<AccordionGroup>
  <Accordion title="deployment.yaml">
    ```yaml theme={null}
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hoopagent
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hoopagent
      template:
        metadata:
          labels:
            app: hoopagent
        spec:
          containers:
          - name: hoopagent
            image: hoophq/hoopdev
            env:
            - name: HOOP_KEY
              value: '<AUTH-KEY>'
    ```
  </Accordion>
</AccordionGroup>

### Sidecar Container

<AccordionGroup>
  <Accordion title="deployment.yaml">
    ```yaml theme={null}
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: myapp
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: myapp
        template:
          metadata:
            labels:
              app: myapp
          spec:
            containers:
            - name: myapp
              image: myapp
              ports:
              - containerPort: 8000
                name: http
                protocol: TCP
            - name: hoopagent
              image: hoophq/hoopdev
              env:
              - name: HOOP_KEY
                value: '<AUTH-KEY>'
    ```
  </Accordion>
</AccordionGroup>

## Gateway Chart Configuration

Check the [environment variables section](/setup/configuration/env-vars) for more information about each configuration.

<AccordionGroup>
  <Accordion title="values.yaml (full base configuration)">
    ```yaml theme={null}
    config:
      POSTGRES_DB_URI: 'postgres://<user>:<pwd>@<db-host>:<port>/<dbname>'
      API_URL: ''
      GRPC_URL: ''
      DEFAULT_AGENT_GRPC_HOST: ''
      API_KEY: ''
      TLS_CA: ''
      TLS_KEY: ''
      TLS_CERT: ''
      AUTH_METHOD: 'local|oidc|saml'
      IDP_CLIENT_ID: ''
      IDP_CLIENT_SECRET: ''
      IDP_ISSUER: ''
      IDP_AUDIENCE: ''
      IDP_GROUPS_CLAIM: ''
      IDP_CUSTOM_SCOPES: ''
      ASK_AI_CREDENTIALS: ''
      DLP_PROVIDER: 'gcp|mspresidio'
      DLP_MODE: 'best-effort|strict'
      GOOGLE_APPLICATION_CREDENTIALS_JSON: '{"type":"service_account",...}'
      MSPRESIDIO_ANALYZER_URL: ''
      MSPRESIDIO_ANONYMIZER_URL: ''
      WEBAPP_USERS_MANAGEMENT: 'on'
      WEBHOOK_APPKEY: ''
      MIGRATION_PATH_FILES: '/app/migrations'
      STATIC_UI_PATH: '/app/ui/public'
      PLUGIN_AUDIT_PATH: '/opt/hoop/sessions'
      ADMIN_USERNAME: 'admin'
      GODEBUG: 'http2debug=0'
      LOG_GRPC: '0'
      LOG_LEVEL: 'info'
      LOG_ENCODING: 'json'
    ```
  </Accordion>
</AccordionGroup>

### Authentication

<Tabs>
  <Tab title="Local Authentication">
    Local Authentication manages users and passwords locally and sign JWT access tokens to users.

    ```yaml theme={null}
    config:
      POSTGRES_DB_URI: 'postgres://<user>:<pwd>@<db-host>:<port>/<dbname>'
      API_URL: 'https://hoopdev.yourdomain.tld'
    ```
  </Tab>

  <Tab title="Oauth2/OIDC Authentication">
    The Oauth2/OIDC authentication integrates with any identity provider that support these protocols. The users are managed on the identity provider.

    ```yaml theme={null}
    config:
      POSTGRES_DB_URI: 'postgres://<user>:<pwd>@<db-host>:<port>/<dbname>'
      API_URL: 'https://hoopdev.yourdomain.tld'
      IDP_ISSUER: 'https://idp-issuer-url'
      IDP_CLIENT_ID: 'client-id'
      IDP_CLIENT_SECRET: 'client-secret'
      IDP_AUDIENCE: ''
      IDP_CUSTOM_SCOPES: ''
      IDP_GROUPS_CLAIM: ''
    ```
  </Tab>
</Tabs>

### Default Database

The chart allows deploying a Postgres database as part of the installation.

```yaml theme={null}
# -- Enable PostgreSQL
postgres:
  # it default to host mount when enabled
  enabled: false

  # set a storage class name to use a Persistent Volume Claim
  storageClassName: null

  # -- Size of PVC
  size: 10Gi
  # annotations: {}
```

<Tip>
  It creates a default Service resource named `hoopgateway-pg`.
  This service name could be used in the `POSTGRES_DB_URI` configuration.
</Tip>

### Persistence

We recommend using SSD for large deployments, it will help speed the I/O when handling many concurrent requests.
The following example shows how to enable a 50GB persistent volume when using AWS/EKS.

```yaml theme={null}
persistence:
  # -- Use persistent volume for write ahead log sessions
  enabled: true
  storageClassName: gp2

  # -- Size of persistent volume claim
  size: 50Gi
```

### Ingress Configuration

This section covers the ingress configuration. The gateway requires exposing the ports **HTTP/8009** and **HTTP2/8010.**
The ingress configuration establishes these two differing configurations based on the [ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) in use.

<Tabs>
  <Tab title="AWS ALB">
    AWS Load Balancer Controller is a controller to help manage Elastic Load Balancers for a Kubernetes cluster.

    <Steps>
      <Step title="Deploy the AWS Load Balancer Controller">
        * [https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/installation/](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/installation/)
      </Step>

      <Step title="Ingress Configuration">
        ```yaml theme={null}
        # HTTP/8009 - API / WebApp
        ingressApi:
          enabled: true
          # the public DNS name
          host: 'hoopgateway.yourdomain.tld'
          # the ingress class, in this case alb
          ingressClassName: 'alb'
          annotations:
            # uses the ACM service to use a valid public certificate issued by AWS
            alb.ingress.kubernetes.io/certificate-arn: 'arn:aws:acm:...'
            # the group name allows resuing the same lb for both protocols (HTTP/gRPC)
            alb.ingress.kubernetes.io/group.name: 'hoopdev'
            alb.ingress.kubernetes.io/healthcheck-path: '/'
            alb.ingress.kubernetes.io/healthcheck-protocol: 'HTTP'
            alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
            alb.ingress.kubernetes.io/scheme: 'internet-facing'
            alb.ingress.kubernetes.io/ssl-redirect: '443'
            alb.ingress.kubernetes.io/target-type: 'ip'

        # HTTP/8010 - gRPC Service
        ingressGrpc:
          enabled: true
          # the public DNS name
          host: 'hoopdev.yourdomain.tld'
          # the ingress class, in this case alb
          ingressClassName: 'alb'
          annotations:
            # configures the type of the protocol
            alb.ingress.kubernetes.io/backend-protocol-version: 'GRPC'
            # the certificate could be reused for the same protocol
            alb.ingress.kubernetes.io/certificate-arn: 'arn:aws:acm:...'
            # the group name allows resuing the same lb for both protocols (HTTP/gRPC)
            alb.ingress.kubernetes.io/group.name: 'hoopdev'
            alb.ingress.kubernetes.io/healthcheck-path: '/'
            alb.ingress.kubernetes.io/healthcheck-protocol: 'HTTP'
            alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 8443}]'
            alb.ingress.kubernetes.io/scheme: 'internet-facing'
            alb.ingress.kubernetes.io/target-type: 'ip'
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Nginx Ingress Controller">
    The Nginx Ingress Controller is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer.

    <Steps>
      <Step title="Deploy Nginx Ingress Controller">
        * [https://kubernetes.github.io/ingress-nginx/deploy/](https://kubernetes.github.io/ingress-nginx/deploy/)
      </Step>

      <Step title="Ingress Configuration">
        * TLS Termination on Nginx

        ```yaml theme={null}
        ingressApi:
          enabled: true
          host: hoopgateway.yourdomain.tld
          ingressClassName: 'nginx'
          tls:
          - hosts:
              - hoopgateway.yourdomain.tld
            secretName: hoopserver-tls

        ingressGrpc:
          enabled: true
          host: "hoop-grpc.yourdomain.tld"
          annotations:
            nginx.ingress.kubernetes.io/backend-protocol: GRPC
            nginx.ingress.kubernetes.io/proxy-body-size: '0'
          tls:
          - hosts:
              - hoop-grpc.yourdomain.tld
            secretName: hoopserver-tls
        ```

        <Note>
          This setup requires deploying a network load balancer (Layer 4) in your cloud provider.
        </Note>
      </Step>
    </Steps>
  </Tab>

  <Tab title="GCP Classic ALB">
    The external Application Load Balancer is a proxy-based Layer 7 load balancer that enables you to run and scale your services behind a single external IP address.
    [See the Architecture Overview](https://cloud.google.com/load-balancing/docs/https).

    <Note>
      The Classic ALB doesn't support establishing HTTP/2 connections with the Hoop Gateway without TLS.
      To accommodate this requirement, TLS certificates must be configured both on the ALB and within the Hoop Gateway
      to establish secure communication between these components.
    </Note>

    <Steps>
      <Step title="Deploy GKE Cluster">
        * Deploy GKE Cluster by following the [GKE Quick Start guide](https://cloud.google.com/kubernetes-engine/docs/quickstarts/create-cluster)
        * Obtain access to [your cluster via kubectl](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl)
      </Step>

      <Step title="Export your domain name">
        ```sh theme={null}
        export DOMAIN_HOSTNAME=hoopgateway.yourdomain.tld
        ```
      </Step>

      <Step title="Setup Certificates">
        <AccordionGroup>
          <Accordion title="Generate self signed certificates">
            <Note>
              This step is not necessary if you already have certificates issued by a known entity.
            </Note>

            * Create the CA private key

            ```sh theme={null}
            mkdir -p /tmp/hoopdemo && cd /tmp/hoopdemo
            openssl genrsa -aes256 -out ca.key 2048
            ```

            * Create the Root Certificate Authority (CA)

            ```sh theme={null}
            openssl req -x509 -new -nodes -key ca.key -sha256 -days 1826 -out ca.crt -subj '/CN=Hoop Root CA'
            ```

            * Creating the Certificate Signing Request (CSR)

            ```sh theme={null}
            openssl req -new -nodes -out server.csr -newkey rsa:2048 -keyout server.key -subj '/CN=HoopGateway'
            ```

            * Sign the Certificate

            ```sh theme={null}
            # create a v3 ext file for SAN properties
            cat > server.v3.ext << EOF
            authorityKeyIdentifier=keyid,issuer
            basicConstraints=CA:FALSE
            keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
            subjectAltName = @alt_names
            [alt_names]
            DNS.1 = $DOMAIN_HOSTNAME
            DNS.2 = grpc-$DOMAIN_HOSTNAME
            IP.1 = 127.0.0.1
            EOF
            ```

            ```sh theme={null}
            openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
                -CAcreateserial -out server.crt -days 730 -sha256 -extfile server.v3.ext
            ```

            <Note>
              Make sure to install the Root Certificate Authority in your browser/system
              to be able to visit the Web App. The browser won't allow access due to HSTS policy.

              This step is not necessary when using certificates issued by a known entity.
            </Note>
          </Accordion>
        </AccordionGroup>

        * Export the certificates for setting up the helm chart

        ```sh theme={null}
        export TLS_CA="base64://$(cat ca.crt | base64)"
        export TLS_KEY="base64://$(cat server.key | base64)"
        export TLS_CERT="base64://$(cat server.crt | base64)"
        ```

        <Note>
          The format `base64://<inline-certificate-content>` allows configuring inline TLS to Hoop Gateway.
        </Note>

        * Upload them into GCP

        ```sh theme={null}
        gcloud compute ssl-certificates create hoopserver \
          --certificate=server.crt \
          --private-key=server.key
        ```

        <Tip>
          We recommend using a valid certificates for production workloads.
        </Tip>
      </Step>

      <Step title="Configure DNS and create static Global IP Addresses">
        * Create the ip addresses of the load balancer

        ```sh theme={null}
        gcloud compute addresses create hoopgateway-grpc --global
        gcloud compute addresses create hoopgateway-http --global
        ```

        * Associate the ip address to the proper domains in your DNS provider

        | Public DNS              | IP Address                      |
        | ----------------------- | ------------------------------- |
        | `$DOMAIN_HOSTNAME`      | `<hoopgateway-http-ip-address>` |
        | `grpc-$DOMAIN_HOSTNAME` | `<hoopgateway-grpc-ip-address>` |
      </Step>

      <Step title="Deploy the Hoop Gateway">
        * Create a namespace

        ```sh theme={null}
        kubectl create ns hoopdemo
        ```

        <AccordionGroup>
          <Accordion title="Deploy a Postgres Server">
            * Generate Specification

            ```sh theme={null}
            cat - > /tmp/hoopdemo/postgres-spec.yaml <<EOF
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: postgres
            spec:
              replicas: 1
              selector:
                matchLabels:
                  app: postgres
              strategy:
                type: Recreate
              template:
                metadata:
                  labels:
                    app: postgres
                spec:
                  containers:
                  - env:
                    - name: POSTGRES_USER
                      value: root
                    - name: POSTGRES_PASSWORD
                      value: 1a2b3c4d
                    - name: POSTGRES_DB
                      value: hoopdb
                    image: postgres
                    name: postgres
                    ports:
                    - containerPort: 5432
                      name: pg
                      protocol: TCP
            ---
            apiVersion: v1
            kind: Service
            metadata:
              name: postgres
            spec:
              ports:
              - name: postgres
                port: 5432
                protocol: TCP
                targetPort: 5432
              selector:
                app: postgres
            EOF
            ```

            * Deploy it

            ```sh theme={null}
            kubectl apply -n hoopdemo -f /tmp/hoopdemo/postgres-spec.yaml
            ```
          </Accordion>
        </AccordionGroup>

        <AccordionGroup>
          <Accordion title="Deploy the Hoop Gateway">
            * Generate Helm values.yaml

            ```sh theme={null}
            cat - > /tmp/hoopdemo/values.yaml <<EOF
            config:
              POSTGRES_DB_URI: 'postgres://root:1a2b3c4d@postgres:5432/hoopdb?sslmode=disable'
              API_URL: "https://$DOMAIN_HOSTNAME"
              GRPC_URL: "grpcs://grpc-$DOMAIN_HOSTNAME:443"

            defaultAgent:
              enabled: true
              grpcHost: grpc-$DOMAIN_HOSTNAME:443

            mainService:
              annotations:
                beta.cloud.google.com/backend-config: '{"ports": {"http": "hoopgateway-http", "grpc": "hoopgateway-grpc"}}'
                cloud.google.com/app-protocols: '{"http":"HTTPS", "grpc":"HTTP2"}'
              httpBackendConfig:
                healthCheckType: HTTPS
              grpcBackendConfig:
                healthCheckType: HTTPS
                # it avoids clients being dropped for being idle
                timeoutSec: 259200

            ingressApi:
              enabled: true
              host: "$DOMAIN_HOSTNAME"
              annotations:
                kubernetes.io/ingress.class: 'gce'
                ingress.gcp.kubernetes.io/pre-shared-cert: 'hoopserver'
                kubernetes.io/ingress.global-static-ip-name: 'hoopgateway-http'

            ingressGrpc:
              enabled: true
              host: "grpc-$DOMAIN_HOSTNAME"
              annotations:
                kubernetes.io/ingress.class: 'gce'
                ingress.gcp.kubernetes.io/pre-shared-cert: 'hoopserver'
                kubernetes.io/ingress.global-static-ip-name: 'hoopgateway-grpc'
            EOF
            ```

            * Deploy it

            ```sh theme={null}
            helm upgrade --install hoop oci://ghcr.io/hoophq/helm-charts/hoop-chart -f values.yaml --namespace hoopdemo \
              --set config.TLS_CA=$TLS_CA \
              --set config.TLS_KEY=$TLS_KEY \
              --set config.TLS_CERT=$TLS_CERT
            ```
          </Accordion>
        </AccordionGroup>
      </Step>

      <Step title="Access It">
        * Wait for all resources to be provisioned, the command below will show any pending operations on GCP

        ```sh theme={null}
        gcloud compute operations list |grep -v DONE
        ```

        * Check if the ip addresses are displayed when listing the ingresses

        ```sh theme={null}
        kubectl get ing -n hoopdemo
        ```

        ```
        NAME               CLASS    HOSTS                   ADDRESS
        hoopgateway-grpc   <none>   grpc-$DOMAIN_HOSTNAME   XX.X.XX.XXX
        hoopgateway-web    <none>   $DOMAIN_HOSTNAME        XX.XXX.XXX.X
        ```

        * Navigate to the Web Application public URL at `https://$DOMAIN_HOSTNAME/login`
      </Step>
    </Steps>
  </Tab>
</Tabs>

### Service Configuration

The chart allows configuring the main service that exposes the service of the gateway.

```yaml theme={null}
mainService:
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"http": "hoopgateway-http", "grpc": "hoopgateway-grpc"}}'
    cloud.google.com/app-protocols: '{"http":"HTTPS", "grpc":"HTTP2"}'
  httpBackendConfig:
    healthCheckType: HTTPS
  grpcBackendConfig:
    healthCheckType: HTTPS
    timeoutSec: 259200
```

* `mainService.annotations` attribute allows adding an annotation mapping. GCP for instance configure aspects of how to configure the load balancer based on this configuration
* `mainService.httpBackendConfig`: It creates the `hoopgateway-http` Backend Config resource when this attribute is set. It could be referenced using the annotation `beta.cloud.google.com/backend-config`
  * `healthCheckType`: The protocol used by probe systems for health checking. The BackendConfig only supports creating health checks using the HTTP, HTTPS, or HTTP2
  * `timeoutSec`: The amount of time in seconds that Google Cloud waits for a response to a probe.
* `mainService.grpcBackendConfig`: It creates the `hoopgateway-grpc` Backend Config resource when this attribute is set. It could be referenced using the annotation `beta.cloud.google.com/backend-config`
  * `healthCheckType`: The protocol used by probe systems for health checking. The BackendConfig only supports creating health checks using the HTTP, HTTPS, or HTTP2
  * `timeoutSec`: The amount of time in seconds that Google Cloud waits for a response to a probe.

For more information of how to configure these resources, refer to the [GCP Ingress Configuration Reference](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-configuration#associating_backendconfig_with_your_ingress).

### Computing Resources

The helm-chart defaults to 1vCPU and 1GB, which is suitable for evaluation purposes only.
For production setups, we recommend allocating at least 8GB/4vCPU to the gateway process.

```yaml theme={null}
resources:
  gw:
    limits:
      cpu: 4096m
      memory: 8Gi
    requests:
      cpu: 4096m
      memory: 8Gi
```

### Image Configuration

By default, the latest version of all images is used. If you want to use a specific image or pin the versions, use the `image` attribute section.

```yaml theme={null}
image:
  gw:
    repository: hoophq/hoop
    pullPolicy: Always
    tag: latest
```

### Default Agent Sidecar

Adding this section will deploy a default agent as a sidecar container.

```yaml theme={null}
defaultAgent:
  enabled: true
  imageRepository: 'hoophq/hoopdev'
  imageTag: latest
  imagePullPolicy: Always
  grpcHost: 127.0.0.1:8009
```

<Note>
  The `grpcHost` allows configuring the host to connect when starting the agent.
  In case the gateway has TLS configured (`TLS_CA` env set), the host must match the certificate SAN.
</Note>

### Data Masking Configuration

To enable the Data Masking feature, you need to configure the `dataMasking` section in your `values.yaml` file.
It will deploy the [Microsoft Presidio](https://github.com/microsoft/presidio) on the same namespace as the Hoop Gateway.

```yaml theme={null}
dataMasking:
  enabled: true
  # https://github.com/microsoft/presidio/releases
  version: latest
  # best-effort | strict
  mode: best-effort

  analyzer:
    resources:
      limits:
        cpu: 512m
        memory: 1024Mi
      requests:
        cpu: 256m
        memory: 1024Mi

  anonymizer:
    resources:
      limits:
        cpu: 512m
        memory: 512Mi
      requests:
        cpu: 256m
        memory: 512Mi
```

<Note>
  When the `dataMasking` attribute is enabled, it takes control over the following configurations:

  * DLP\_MODE
  * DLP\_PROVIDER
  * MSPRESIDIO\_ANALYZER\_URL
  * MSPRESIDIO\_ANONYMIZER\_URL
  * GOOGLE\_APPLICATION\_CREDENTIALS\_JSON

  If you need more control over the deployment, we recommend using a standalone helm chart of Presidio.
  See more details above in the [Presidio Deployment](#presidio-deployment) section.
</Note>

<Tip>
  This attribute is available starting from version **1.37.16+** of the Helm chart.
</Tip>

### Node Selector

This configuration describes a pod that has a node selector, `disktype: ssd`. This means that the pod will get scheduled on a node that has a `disktype=ssd` label.

See [this documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) for more information.

```yaml theme={null}
# -- Node labels for pod assignment
nodeSelector:
  disktype: ssd
```

### Tolerations

See this article explaining how to configure [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)

```yaml theme={null}
# -- Toleration labels for pod assignment
tolerations:
- effect: NoExecute
  key: spot
  value: "true"
- effect: NoSchedule
  key: spot
  value: "true"
```

### Node Affinity

See [this article](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) explaining how to configure affinity and anti-affinity rules

```yaml theme={null}
# -- Affinity settings for pod assignment
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - antarctica-east1
          - antarctica-west1
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: another-node-label-key
          operator: In
          values:
          - another-node-label-value
```

## Presidio Deployment

The Data Masking feature uses Microsoft Presidio.
We provide a Helm chart that gives more control over the deployment.

```bash theme={null}
helm upgrade --install presidio \
  oci://ghcr.io/hoophq/helm-charts/presidio-chart --version v0.0.3 \
  -f values.yaml
```

<AccordionGroup>
  <Accordion title="values.yaml">
    ```yaml theme={null}

    # analyzer service configuration
    analyzer:
      replicas: 1
      imageRepository: mcr.microsoft.com/presidio-analyzer
      imagePullPolicy: Always
      # versions: https://github.com/microsoft/presidio/releases
      imageTag: latest
      resources:
        limits:
          cpu: 512m
          memory: 1024Mi
        requests:
          cpu: 256m
          memory: 1024Mi

      # -- Node labels for pod assignment
      nodeSelector: {}

      # -- Toleration labels for pod assignment
      tolerations: []

      # -- Affinity settings for pod assignment
      affinity: {}

    # anonymizer service configuration
    anonymizer:
      replicas: 1
      imageRepository: mcr.microsoft.com/presidio-anonymizer
      imagePullPolicy: Always
      # versions: https://github.com/microsoft/presidio/releases
      imageTag: latest
      resources:
        limits:
          cpu: 512m
          memory: 512Mi
        requests:
          cpu: 256m
          memory: 512Mi

      # -- Node labels for pod assignment
      nodeSelector: {}

      # -- Toleration labels for pod assignment
      tolerations: []

      # -- Affinity settings for pod assignment
      affinity: {}
    ```
  </Accordion>
</AccordionGroup>

The chart will create two services that are used in the gateway to configure the data masking feature:

* `presidio-analyzer` -  The analyzer service that detects PII data in text.
* `presidio-anonymizer` -  The anonymizer service that masks PII data in text

These services must be respectively configured in the Gateway with the following environment variables:

```conf theme={null}
DLP_PROVIDER=mspresidio
MSPRESIDIO_ANALYZER_URL=http://presidio-analyzer:3000
MSPRESIDIO_ANONYMIZER_URL=http://presidio-anonymizer:3000
```

For more information about new releases, consult the [Presidio Helm Chart repository](https://github.com/hoophq/presidio-helm).

### Presidio With Flair

<Note>
  Available under the agent version **1.37.22+** and the Helm Presidio Chart version **v0.0.2+**.
</Note>

We have a custom build of Presidio that leverages the use of [Flair](https://flairnlp.github.io/flair/), it provides better accuracy in detecting PII data.
To use this custom build, you could use our custom build of the Presidio Analyzer.

```yaml theme={null}
analyzer:
  replicas: 1
  imageRepository: hoophq/presidio-analyzer-flair
  imageTag: 0.0.3
  imagePullPolicy: Always
  resources:
    limits:
      cpu: 8192m
      memory: 16384Mi
    requests:
      cpu: 8192m
      memory: 16384Mi

# anonymizer service configuration
anonymizer:
  replicas: 1
  imageRepository: mcr.microsoft.com/presidio-anonymizer
  imagePullPolicy: Always
  resources:
    limits:
      cpu: 512m
      memory: 512Mi
    requests:
      cpu: 256m
      memory: 512Mi
```

<Warning>
  The custom build of Presidio Analyzer with Flair requires more resources than the default official image.
  We recommend allocating at least 8vCPU and 16GB to the analyzer process.
</Warning>

### Node Selector

<Note>
  Available on Helm Chart version **v0.0.3+**.
</Note>

This configuration describes a pod that has a node selector, `disktype: ssd`. This means that the pod will get scheduled on a node that has a `disktype=ssd` label.

See [this documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/) for more information.

```yaml theme={null}
# -- Node labels for pod assignment
nodeSelector:
  disktype: ssd
```

### Tolerations

<Note>
  Available on Helm Chart version **v0.0.3+**.
</Note>

See this article explaining how to configure [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)

```yaml theme={null}
# -- Toleration labels for pod assignment
tolerations:
- effect: NoExecute
  key: spot
  value: "true"
- effect: NoSchedule
  key: spot
  value: "true"
```

### Node Affinity

<Note>
  Available on Helm Chart version **v0.0.3+**.
</Note>

See [this article](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) explaining how to configure affinity and anti-affinity rules

```yaml theme={null}
# -- Affinity settings for pod assignment
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - antarctica-east1
          - antarctica-west1
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: another-node-label-key
          operator: In
          values:
          - another-node-label-value
```

## Generating Manifests

If you prefer using manifests over Helm, we recommend this approach. It allows you to track any modifications to the chart whenever a new version appears. You can apply a diff to your versioned files to identify what has been altered.

```bash theme={null}
VERSION=$(curl -s https://releases.hoop.dev/release/latest.txt)
helm template hoop \
  oci://ghcr.io/hoophq/helm-charts/hoop-chart --version $VERSION \
  -f values.yaml
```
