Skip to main content
Version: 2.12.0

ECA Integration and Component Installation

After configuring the network connection between ECA and the ML Module, you need to install and configure the following components to establish data flow for threat hunting capabilities.

Installation Tracking

Monitor your installation progress at any point by running kubectl -n seed-ml get pods, which displays the current status of all components being deployed in the installation process.

Setting Up Database Components

Install Clickhouse

  1. Get ECA Kafka Node Hostnames

    Get the ECA Kafka node hostnames that you'll need for configuration.

    Kafka Node Hostnames

    info

    Retrieve ECA Kafka node hostnames from your ECA environment and note these for use in the configuration file below.

  2. Create Configuration File
    Set ClickHouse admin password and create the configuration file with proper hostnames and IPs to the ECA nodes.

    Set the ClickHouse admin password environment variable:

    export CLICKHOUSE_PASS=Clickhouse.Change-me.2025

    Create ClickHouse custom values file for on-premise installation:

    cat << EOF > clickhouse-onprem-values.yaml
    clickhouse:
    clusterName:
    shards: 1
    replicaCount: 1
    auth:
    password: $CLICKHOUSE_PASS
    extraOverrides: |
    <clickhouse>
    <kafka>
    <security_protocol>plaintext</security_protocol>
    </kafka>
    </clickhouse>
    zookeeper:
    enabled: false
    hostAliases:
    - ip: "<eca-node-1-ip>"
    hostnames:
    - "<kafka-node-1-hostname>"
    - ip: "<eca-node-2-ip>"
    hostnames:
    - "<kafka-node-2-hostname>"
    - ip: "<eca-node-3-ip>"
    hostnames:
    - "<kafka-node-3-hostname>"
    EOF
    Required Parameter Replacements

    Replace the placeholder values with your actual ECA node values:

    PlaceholderDescriptionExample
    <eca-node-1-ip>IP address of first ECA node10.152.1.148
    <eca-node-2-ip>IP address of second ECA node10.152.1.149
    <eca-node-3-ip>IP address of third ECA node10.152.1.150
    <kafka-node-1-hostname>Hostname of first Kafka nodekafka.node1.cluster.local
    <kafka-node-2-hostname>Hostname of second Kafka nodekafka.node2.cluster.local
    <kafka-node-3-hostname>Hostname of third Kafka nodekafka.node3.cluster.local
  3. Install ClickHouse
    Install ClickHouse using the custom values file.

    Install ClickHouse using Helm:

    helm upgrade --install clickhouse chart-seed-ml/charts/clickhouse -n seed-ml -f clickhouse-onprem-values.yaml

    Verify that the ClickHouse pod is running:

    kubectl -n seed-ml get pods
    Expected Result

    You should see a pod named clickhouse-0 with status Running.

Install Postgres

  1. Set Credentials and Install
    Set PostgreSQL admin password and install using Helm chart.

    Set PostgreSQL admin password environment variable:

    export POSTGRES_ADMIN_PASS=Postgres.Change-me.2025

    Install PostgreSQL Helm chart:

    helm upgrade --install postgres chart-seed-ml/charts/postgres -n seed-ml --create-namespace \
    --set postgresql.auth.postgresPassword=$POSTGRES_ADMIN_PASS \
    --set postgresql.primary.persistence.size=8Gi
  2. Export Credentials
    Retrieve and set environment variables for PostgreSQL credentials.

    Retrieve and set POSTGRES_USER environment variable:

    export POSTGRES_USER=$(kubectl get secret seed-ml-user-secret -n seed-ml -o jsonpath="{.data.username}" | base64 -d)

    Retrieve and set POSTGRES_PASS environment variable:

    export POSTGRES_PASS=$(kubectl get secret seed-ml-user-secret -n seed-ml -o jsonpath="{.data.password}" | base64 -d)

    Retrieve and set POSTGRES_SUPERSET_USER environment variable:

    export POSTGRES_SUPERSET_USER=$(kubectl get secret superset-user-secret -n seed-ml -o jsonpath="{.data.username}" | base64 -d)

    Retrieve and set POSTGRES_SUPERSET_PASS environment variable:

    export POSTGRES_SUPERSET_PASS=$(kubectl get secret superset-user-secret -n seed-ml -o jsonpath="{.data.password}" | base64 -d)
    tip

    These environment variables will be used in subsequent configuration files, so ensure they are properly exported.

Configuring Core ML Components

Install SeedML

  1. Export Environment Variables
    Export environment variables needed by AWS.

    Set the AWS EKS cluster name:

    export AWS_EKS_CLUSTER="seed-qa-01"

    Set the default AWS region:

    export AWS_DEFAULT_REGION="ca-central-1"

    Set the AWS region (redundant with AWS_DEFAULT_REGION but often included for broad compatibility):

    export AWS_REGION="ca-central-1"

    Set the AWS ECR target repository URL:

    export AWS_ECR_TARGET="285688719016.dkr.ecr.ca-central-1.amazonaws.com"

    Set the AWS secret access key:

    export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"

    Set the AWS access key ID:

    export AWS_ACCESS_KEY_ID="<your-access-key-id>"
    Fixed AWS Configuration Values

    The following AWS configuration values are fixed and should be entered exactly as shown. Only the AWS credentials (secret access key and access key ID) need to be obtained separately.

    ParameterDescriptionValue
    AWS_EKS_CLUSTEREKS cluster name (fixed)seed-qa-01
    AWS_DEFAULT_REGIONAWS region (fixed)ca-central-1
    AWS_ECR_TARGETECR repository URL (fixed)285688719016.dkr.ecr.ca-central-1.amazonaws.com
    AWS_SECRET_ACCESS_KEYYour AWS secret access key(obtain from AWS IAM)
    AWS_ACCESS_KEY_IDYour AWS access key ID(obtain from AWS IAM)
  2. Add AWS Authentication for K3s
    Configure AWS CLI and create ECR authentication for K3s.

    Download the AWS CLI v2 installer:

    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

    Unzip the AWS CLI installer:

    unzip awscliv2.zip

    Install the AWS CLI:

    sudo ./aws/install

    Get an ECR login password:

    ECR_PASSWORD=$(aws ecr get-login-password --region ${AWS_REGION})

    Create a Kubernetes Docker registry secret for ECR:

    kubectl create secret docker-registry supernaregcred \
    --namespace seed-ml \
    --docker-server="${AWS_ECR_TARGET}" \
    --docker-username="AWS" \
    --docker-password="${ECR_PASSWORD}"
  3. Create Configuration File
    Create seed-ml custom values file for on-premise installation.

    cat << EOF > seedml-onprem-values.yaml
    fqdn: dashboard.ml
    default:
    image:
    registry: $AWS_ECR_TARGET
    tag: $RELEASE
    pullPolicy: IfNotPresent
    pullSecrets:
    - name: supernaregcred
    ingress:
    exposeDevRoutes: false
    ml-data-exfiltration:
    enabled: true
    image:
    name: seed-ml-public/ml-data-exfiltration
    config: |
    app:
    swagger:
    server.url: http://127.0.0.1:58080
    port: 5000
    extraEnv:
    - name: ML_DB_URL
    value: clickhousedb://admin:$CLICKHOUSE_PASS@clickhouse/seed_ml?send_receive_timeout=300
    - name: ML_SHARED_VOLUME
    value: /mnt/ml-data
    service-inventory:
    enabled: true
    image:
    name: seed-ml-public/service-inventory
    config: |
    spring:
    datasource:
    username: $POSTGRES_USER
    password: $POSTGRES_PASS
    app:
    swagger:
    server.url: http://127.0.0.1:58080
    logging:
    level:
    io.superna: INFO
    extraEnv:
    - name: DB_JDBC_URL
    value: jdbc:postgresql://postgres-postgresql/seed_ml
    - name: ML_DB_URL
    value: clickhousedb://admin:$CLICKHOUSE_PASS@clickhouse/seed_ml?send_receive_timeout=300
    service-pipelines:
    enabled: true
    image:
    name: seed-ml-public/service-pipelines
    config: |
    spring:
    flyway:
    locations: ["classpath:db/migration/local"]
    clusterName: ""
    placeholders:
    kafka-bootstrap-servers: <eca-node-1-ip>:9092,<eca-node-2-ip>:9092,<eca-node-3-ip>:9092
    kafka:
    bootstrap-servers: <eca-node-1-ip>:9092,<eca-node-2-ip>:9092,<eca-node-3-ip>:9092
    streams:
    properties:
    security.protocol: PLAINTEXT
    app:
    swagger:
    server.url: http://127.0.0.1:58080
    services:
    ml-data-exfiltration.url: http://seedml-ml-data-exfiltration:5000
    inventory.url: http://seedml-service-inventory:8080
    logging:
    level:
    io.superna: INFO
    extraEnv:
    - name: DB_JDBC_URL
    value: jdbc:clickhouse://admin:$CLICKHOUSE_PASS@clickhouse/seed_ml?send_receive_timeout=300
    - name: KAFKA_USER
    value: $KAFKA_USER
    - name: KAFKA_PASS
    value: $KAFKA_PASS
    hosts:
    - ip: "<eca-node-1-ip>"
    hostnames:
    - "<kafka-node-1-hostname>"
    - ip: "<eca-node-2-ip>"
    hostnames:
    - "<kafka-node-2-hostname>"
    - ip: "<eca-node-3-ip>"
    hostnames:
    - "<kafka-node-3-hostname>"
    EOF
    Required Parameter Replacements

    Replace the placeholder values with your actual configuration:

    PlaceholderDescriptionExample
    <ml-server-ip>ML server IP address10.152.20.90
    <port>ML server port (fixed)31443
    <eca-node-1-ip>IP address of first ECA node10.152.1.148
    <eca-node-2-ip>IP address of second ECA node10.152.1.149
    <eca-node-3-ip>IP address of third ECA node10.152.1.150
    <kafka-node-1-hostname>Hostname of first Kafka nodekafka.node1.cluster.local
    <kafka-node-2-hostname>Hostname of second Kafka nodekafka.node2.cluster.local
    <kafka-node-3-hostname>Hostname of third Kafka nodekafka.node3.cluster.local
  4. Install SeedML
    Install seed-ml services using the custom values file.

    helm upgrade --install seedml chart-seed-ml/charts/seedml -n seed-ml --create-namespace -f seedml-onprem-values.yaml
  5. Update Service Inventory Prebuilt ML Models
    Before installing seed-ml services, you need to update the docker image registry and tag for the prebuilt ML models in the inventory service.

    1. Expose Service Inventory API
      Port-forward the service inventory to access its API locally.

      kubectl -n seed-ml port-forward svc/seedml-service-inventory 58080:8080
      API Access

      The service API will be accessible at: http://127.0.0.1:58080/swagger-ui/index.html#

    2. Access the Swagger UI
      Open your browser and navigate to the Swagger UI URL to access the inventory endpoints.

      You'll use these two endpoints:

      • GET /models - Retrieve current model configurations
      • POST /models - Update model configurations

      Inventory GET and POST endpoints

    3. Update Each ML Model
      You need to update 4 models: data-exfil-rwmr, data-exfil-rwmw, data-exfil-ml1, and data-exfil-ml2.

      For each model, follow these steps:

      Model code field

    4. Get Current Configuration

      • Execute the GET /models endpoint
      • Enter the model name in the code field (e.g., data-exfil-rwmr)
      • Copy the response payload for the specific model (without the array brackets [,])

      GET model response

    5. Update Docker Configuration

      POST model update

      • Paste the copied JSON into the POST /models input area

      • Update these two attributes:

        • dockerImage: Change from seed-containers.artifactory.build.superna.net/seed-ml/ml-data-exfiltration to 285688719016.dkr.ecr.ca-central-1.amazonaws.com/seed-ml-public/ml-data-exfiltration
        • dockerTag: Change from test to 1.0.0
      • Click the Execute button to save changes

    6. Verify Updates

      • Run the GET /models endpoint again
      • Confirm the new values for dockerImage and dockerTag are present

      Verify model update

      Model Update Required

      Repeat this process for all 4 models:

      • data-exfil-rwmr
      • data-exfil-rwmw
      • data-exfil-ml1
      • data-exfil-ml2

Configuring Advanced Components

Install SeedML Backend

The API service includes basic HTTP security, which is protected by a predefined username and password.

Configuration Prerequisites

The following steps guide you through gathering critical configuration values before creating the configuration file. Collect all these values before proceeding to the configuration file creation.

  1. Prepare Configuration Values

    1. ML Machine Address

      Identify the ML machine's IP address to use in the FQDN parameter within both the service-ml-core and api-ml sections of the configuration file.

    2. ML Machine Port

      Determine the port for the ML machine to use in the FQDN parameter (format: <IP_ADDRESS>:31443).

    3. Eyeglass URL

      Identify your Eyeglass server's full address (including https://) for the EYEGLASS_URL parameter.

    4. Authentication Token

      Create a token for ML integration:

      • Navigate to Eyeglass Menu → Integrations → API Tokens
      • Generate a new token and save it for the EYEGLASS_TOKEN parameter
      info

      For detailed instructions on creating API tokens, see Authenticating Remote Services.

    5. Eyeglass Public Key

      Obtain the Eyeglass public key for the EYEGLASS_PUBLIC_KEY parameter:

      cat /opt/superna/eca/data/common/.secure/rsa/isilon.pub
      tip

      Run this command on any ECA node and save the entire output.

    6. Kafka Connection Details

      Identify all ECA node IP addresses and their corresponding Kafka hostnames for the KAFKA_SERVERS parameter and hosts section (port stays as 9092).

  2. Create Configuration File

    Create the SeedML Backend configuration file:

     cat << EOF > seedmlback-onprem-values.yaml
    fqdn: dashboard.ml
    environment:
    kind: dev
    name: onprem
    default:
    image:
    registry: $AWS_ECR_TARGET
    tag: $RELEASE
    pullPolicy: IfNotPresent
    pullSecrets:
    - name: supernaregcred
    ingress:
    exposeDevRoutes: false
    service-ml-core:
    enabled: true
    image:
    name: seed-ml-public/service-ml-core
    config: |
    app:
    fqdn: "<ML_MODULE_ADDRESS>:31443"
    swagger:
    server.url: http://127.0.0.1:58080
    eyeglass:
    enabled: true
    url: https://<EYEGLASS_ADDRESS>
    #heartbeat-delay: 60 # heartbeat delay in seconds
    #node-name: ml-cluster
    #esaid: 1
    token: <EYEGLASS_TOKEN>
    public-key: <EYEGLASS_PUBLIC_KEY>
    ml-training:
    enabled: true # ml-training deployment enabled or not
    delta-time:
    value: 48 # delta value for adjusting training time (in the example below will train with data till 2 days ago)
    unit: HOURS # ChronoUnit format: MINUTES, HOURS, DAYS
    # zones where training will collect data. Combination of <cron>:<cluster_name>:<path>:<models (empty to apply all)>
    zones:
    - "0 0 0 * * *:isi-mock-127:/ifs/data/tests/AccessZoneA:data-exfil-rwmr"
    - "0 0 1 * * *:isi-mock-127:/ifs/data/tests/AccessZoneA:data-exfil-rwmw"
    - "0 0 2 * * *:isi-mock-127:/ifs/data/tests/AccessZoneA:data-exfil-ml1"
    - "0 0 3 * * *:isi-mock-127:/ifs/data/tests/AccessZoneA:data-exfil-ml2"
    extraEnv:
    - name: DB_JDBC_URL
    value: jdbc:clickhouse://admin:$CLICKHOUSE_PASS@clickhouse/seed_ml
    - name: KAFKA_SERVERS
    value: <ECA_NODE1_IP>:9092,<ECA_NODE2_IP>:9092,<ECA_NODE3_IP>:9092
    hosts:
    - ip: "<ECA_NODE1_IP>"
    hostnames:
    - "kafka.node1.jmseca1.eca.local"
    - ip: "<ECA_NODE2_IP>"
    hostnames:
    - "kafka.node2.jmseca1.eca.local"
    - ip: "<ECA_NODE3_IP>"
    hostnames:
    - "<KAFKA_NODE3_HOST>"
    api-ml:
    image:
    name: seed-ml-public/api-ml
    config: |
    app:
    fqdn: "<ML_MODULE_ADDRESS>:31443"
    services:
    core.url: http://seedmlback-service-ml-core:8080
    auth:
    # Default username. Define a new one if required
    #name: mladmin
    # Default password. To generate a new one for example: htpasswd -bnBC 12 "" my_secret_password
    #password: "{bcrypt}<generated password>"
    ui-ml:
    image:
    name: seed-ml-public/ui-ml
    EOF
    Required Parameter Replacements

    Replace these placeholders with your actual values:

    PlaceholderDescriptionExample
    <ML_MODULE_ADDRESS>IP address of ML module serverxxx.xxx.xxx.10
    <ML_MODULE_PORT>Port for ML module server (fixed)31443
    <EYEGLASS_ADDRESS>IP address of Eyeglass serverxxx.xxx.xxx.20
    <EYEGLASS_TOKEN>API token from EyeglasseyJhbGciOiJIUzI1...
    <EYEGLASS_PUBLIC_KEY>RSA public key from ECA nodessh-rsa AAAAB3NzaC1...
    <CLUSTER_NAME>Isilon cluster namecluster1
    <SUPERVISED_PATH_1>Directory path to supervise/ifs/data/tests/folder1
    <ECA_NODE1_IP>IP address of first ECA nodexxx.xxx.xxx.30
    <ECA_NODE2_IP>IP address of second ECA nodexxx.xxx.xxx.31
    <ECA_NODE3_IP>IP address of third ECA nodexxx.xxx.xxx.32
    <KAFKA_NODE1_HOST>Hostname of first Kafka nodekafka-node1
    <KAFKA_NODE2_HOST>Hostname of second Kafka nodekafka-node2
    <KAFKA_NODE3_HOST>Hostname of third Kafka nodekafka-node3
  3. Install SeedML Backend

    Install the SeedML backend with your configuration:

    helm upgrade --install seedmlback chart-seed-ml/charts/seedmlback -n seed-ml --create-namespace -f seedmlback-onprem-values.yaml

Install Superset Dashboard

Superset provides the visualization dashboard for your threat hunting data.

  1. Set Environment Variables

    Set the required secret key and admin password for Superset:

    export SUPERSET_ADMIN_USER_PASS=Change-me-2024
    export SUPERSET_SECRET_KEY=Change-it-2024
  2. Create Configuration File

    Create the Superset configuration file:

     cat << EOF > superset-onprem-values.yaml
    superset:
    extraSecretEnv:
    SUPERSET_SECRET_KEY: $SUPERSET_SECRET_KEY
    init:
    adminUser:
    password: $SUPERSET_ADMIN_USER_PASS
    postgresql:
    auth:
    username: $POSTGRES_SUPERSET_USER
    password: $POSTGRES_SUPERSET_PASS
    supersetNode:
    connections:
    db_host: postgres-postgresql
    db_pass: $POSTGRES_SUPERSET_PASS
    ingress:
    enabled: true
    ingressClassName: haproxy-superset
    EOF
  3. Install Superset

    Deploy Superset using Helm:

    helm upgrade --install superset chart-seed-ml/charts/superset -n seed-ml --create-namespace -f superset-onprem-values.yaml

Verifying the Installation

Verify Eyeglass Integration

  1. Access Eyeglass Interface

    Open the Eyeglass web interface in your browser.

  2. Navigate to Services

    Go to Settings → Services in the main navigation menu.

    Eyeglass Services Menu

  3. Verify ML Cluster

    Expected Result

    Confirm the presence of ml-cluster in the services list.

  4. Check Component Status

    tip

    All ML module components should show a green icon indicating healthy status.

Dashboard Configuration

Import Superset Dashboards

Several dashboards have been prepared that will allow you to analyze the different available data more effectively. To manually import these dashboards, follow the procedure below:

  1. Access Superset Interface
    Upon first access, you will find the dashboards empty. Click on the icon in the upper right corner to import the dashboard.

    Dashboard Import Button

  2. Select Dashboard Files
    Select the dashboard you wish to import. These are located at the following path: seed-ml/charts/superset/resources/*.zip.

    Dashboard File Selection

    Dashboard File Location

    The dashboard files are located in the seed-ml/charts/superset/resources/ directory and have a .zip extension.

  3. Provide Database Credentials
    You may be prompted for the password used in the ClickHouse or Postgres database. Provide it when necessary.

    Password Reference

    Use the passwords you set earlier: $CLICKHOUSE_PASS for ClickHouse and $POSTGRES_ADMIN_PASS for Postgres.

  4. Complete Import Process
    Once these steps are completed, the dashboard will have been imported successfully.

  5. Update ML_Model_Instances Dataset
    Update the ML_Model_Instances dataset. This step ensures that the dataset correctly references the ml-data-exfiltration service using its proper IP address and port.

    Dataset Update Required

    This step is mandatory for proper dashboard functionality. The dataset must reference the correct IP address and port of the ml-data-exfiltration service.

    1. Locate the ML_Model_Instances Dataset
      Navigate to the dataset configuration within the application's interface.

      Find and select the dataset named ML_Model_Instances.

      ML Model Instances Dataset Selection

    2. Edit Connection Details
      Within the ML_Model_Instances dataset configuration, locate the connection or data source settings.

      Update the IP address to the correct IP of your ml-data-exfiltration service.

      Update the port to the correct port exposed by your ml-data-exfiltration service - https://10.152.20.90:31330/prod/ml-data-exfiltration/.

      Dataset Connection Configuration

      Service Configuration

      The IP address and port should match the configuration from your ml-data-exfiltration service deployment.

  6. Clean Up Temporary Files
    In production environments, remove temporal files created (add more if needed).

    rm *-onprem-values.yaml
    Production Environment

    This cleanup step is recommended for production environments to maintain security and reduce clutter.