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.
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
-
Get ECA Kafka Node Hostnames
Get the ECA Kafka node hostnames that you'll need for configuration.
infoRetrieve ECA Kafka node hostnames from your ECA environment and note these for use in the configuration file below.
-
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>"
EOFRequired Parameter ReplacementsReplace the placeholder values with your actual ECA node values:
Placeholder Description Example <eca-node-1-ip>
IP address of first ECA node 10.152.1.148 <eca-node-2-ip>
IP address of second ECA node 10.152.1.149 <eca-node-3-ip>
IP address of third ECA node 10.152.1.150 <kafka-node-1-hostname>
Hostname of first Kafka node kafka.node1.cluster.local <kafka-node-2-hostname>
Hostname of second Kafka node kafka.node2.cluster.local <kafka-node-3-hostname>
Hostname of third Kafka node kafka.node3.cluster.local -
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 ResultYou should see a pod named
clickhouse-0
with statusRunning
.
Install Postgres
-
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 -
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)
tipThese environment variables will be used in subsequent configuration files, so ensure they are properly exported.
Configuring Core ML Components
Install SeedML
-
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 ValuesThe 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.
Parameter Description Value AWS_EKS_CLUSTER
EKS cluster name (fixed) seed-qa-01 AWS_DEFAULT_REGION
AWS region (fixed) ca-central-1 AWS_ECR_TARGET
ECR repository URL (fixed) 285688719016.dkr.ecr.ca-central-1.amazonaws.com AWS_SECRET_ACCESS_KEY
Your AWS secret access key (obtain from AWS IAM) AWS_ACCESS_KEY_ID
Your AWS access key ID (obtain from AWS IAM) -
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}" -
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>"
EOFRequired Parameter ReplacementsReplace the placeholder values with your actual configuration:
Placeholder Description Example <ml-server-ip>
ML server IP address 10.152.20.90 <port>
ML server port (fixed) 31443 <eca-node-1-ip>
IP address of first ECA node 10.152.1.148 <eca-node-2-ip>
IP address of second ECA node 10.152.1.149 <eca-node-3-ip>
IP address of third ECA node 10.152.1.150 <kafka-node-1-hostname>
Hostname of first Kafka node kafka.node1.cluster.local <kafka-node-2-hostname>
Hostname of second Kafka node kafka.node2.cluster.local <kafka-node-3-hostname>
Hostname of third Kafka node kafka.node3.cluster.local -
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
-
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.-
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 AccessThe service API will be accessible at:
http://127.0.0.1:58080/swagger-ui/index.html#
-
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
-
Update Each ML Model
You need to update 4 models:data-exfil-rwmr
,data-exfil-rwmw
,data-exfil-ml1
, anddata-exfil-ml2
.For each model, follow these steps:
-
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
[,]
)
-
Update Docker Configuration
-
Paste the copied JSON into the POST /models input area
-
Update these two attributes:
dockerImage
: Change fromseed-containers.artifactory.build.superna.net/seed-ml/ml-data-exfiltration
to285688719016.dkr.ecr.ca-central-1.amazonaws.com/seed-ml-public/ml-data-exfiltration
dockerTag
: Change fromtest
to1.0.0
-
Click the Execute button to save changes
-
-
Verify Updates
- Run the GET /models endpoint again
- Confirm the new values for
dockerImage
anddockerTag
are present
Model Update RequiredRepeat 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.
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.
-
Prepare Configuration Values
-
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. -
ML Machine Port
Determine the port for the ML machine to use in the
FQDN
parameter (format:<IP_ADDRESS>:31443
). -
Eyeglass URL
Identify your Eyeglass server's full address (including https://) for the
EYEGLASS_URL
parameter. -
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
infoFor detailed instructions on creating API tokens, see Authenticating Remote Services.
-
Eyeglass Public Key
Obtain the Eyeglass public key for the
EYEGLASS_PUBLIC_KEY
parameter:cat /opt/superna/eca/data/common/.secure/rsa/isilon.pub
tipRun this command on any ECA node and save the entire output.
-
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).
-
-
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
EOFRequired Parameter ReplacementsReplace these placeholders with your actual values:
Placeholder Description Example <ML_MODULE_ADDRESS>
IP address of ML module server xxx.xxx.xxx.10 <ML_MODULE_PORT>
Port for ML module server (fixed) 31443 <EYEGLASS_ADDRESS>
IP address of Eyeglass server xxx.xxx.xxx.20 <EYEGLASS_TOKEN>
API token from Eyeglass eyJhbGciOiJIUzI1... <EYEGLASS_PUBLIC_KEY>
RSA public key from ECA node ssh-rsa AAAAB3NzaC1... <CLUSTER_NAME>
Isilon cluster name cluster1 <SUPERVISED_PATH_1>
Directory path to supervise /ifs/data/tests/folder1 <ECA_NODE1_IP>
IP address of first ECA node xxx.xxx.xxx.30 <ECA_NODE2_IP>
IP address of second ECA node xxx.xxx.xxx.31 <ECA_NODE3_IP>
IP address of third ECA node xxx.xxx.xxx.32 <KAFKA_NODE1_HOST>
Hostname of first Kafka node kafka-node1 <KAFKA_NODE2_HOST>
Hostname of second Kafka node kafka-node2 <KAFKA_NODE3_HOST>
Hostname of third Kafka node kafka-node3 -
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.
-
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
-
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 -
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
-
Access Eyeglass Interface
Open the Eyeglass web interface in your browser.
-
Navigate to Services
Go to Settings → Services in the main navigation menu.
-
Verify ML Cluster
Expected ResultConfirm the presence of
ml-cluster
in the services list. -
Check Component Status
tipAll 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:
-
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. -
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 LocationThe dashboard files are located in the
seed-ml/charts/superset/resources/
directory and have a.zip
extension. -
Provide Database Credentials
You may be prompted for the password used in the ClickHouse or Postgres database. Provide it when necessary.Password ReferenceUse the passwords you set earlier:
$CLICKHOUSE_PASS
for ClickHouse and$POSTGRES_ADMIN_PASS
for Postgres. -
Complete Import Process
Once these steps are completed, the dashboard will have been imported successfully. -
Update ML_Model_Instances Dataset
Update theML_Model_Instances
dataset. This step ensures that the dataset correctly references theml-data-exfiltration
service using its proper IP address and port.Dataset Update RequiredThis step is mandatory for proper dashboard functionality. The dataset must reference the correct IP address and port of the
ml-data-exfiltration
service.-
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
. -
Edit Connection Details
Within theML_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/
.Service ConfigurationThe IP address and port should match the configuration from your
ml-data-exfiltration
service deployment.
-
-
Clean Up Temporary Files
In production environments, remove temporal files created (add more if needed).rm *-onprem-values.yaml
Production EnvironmentThis cleanup step is recommended for production environments to maintain security and reduce clutter.