Security Azure

Catalyst SOAR on Ubuntu 24.04 on Azure User Guide

| Product: Catalyst SOAR on Ubuntu 24.04 LTS on Azure

Overview

Catalyst is a self-hosted SOAR (security orchestration, automation and response) and incident-response platform. It manages the full lifecycle of alerts, incidents, vulnerabilities and threat hunts as structured tickets — each with tasks, a timeline, comments, links and evidence files — and automates repetitive triage with reactions (a trigger such as a webhook fires an action such as a Python script or an outbound HTTP call).

The cloudimg image runs the pinned Catalyst release as a single Go binary under systemd, fronted by nginx. The current upstream stack is deliberately simple: an embedded SQLite database plus local file storage for uploads — there is no external database or object store to run. At first boot, catalyst-firstboot.service creates the database fresh, generates all platform secrets at random, and creates one administrator account with a per-VM password written to /root/catalyst-credentials.txt (mode 0600, root only). No default login is baked into the image.

What is included:

  • Catalyst 0.15.7 single Go binary (/usr/local/bin/catalyst)
  • Embedded SQLite database + tus file storage at /var/lib/catalyst/catalyst_data (no separate database to maintain)
  • catalyst.service on loopback 127.0.0.1:8090, fronted by nginx on port 80
  • catalyst-firstboot.service creating the per-VM database + admin account
  • python3 available for reaction (automation) Python actions
  • Web console (embedded Vue UI) at /ui/
  • Ubuntu 24.04 LTS base, latest patches, no swap on disk
  • 24/7 cloudimg support, 24h response SLA

Prerequisites

An active Azure subscription, an SSH key, and a VNet + subnet. Recommended VM size: Standard_B2s (2 vCPU / 4 GB) — Catalyst is a single lightweight Go binary and runs comfortably in 4 GB.

Step 1: Deploy from the Azure Portal

Search the Marketplace for Catalyst SOAR, choose the plan, and deploy into your VNet. In the NSG, allow TCP 22 (SSH) and TCP 80 (web console) from your client networks only. Front port 80 with a TLS reverse proxy or Azure Application Gateway in production.

Step 2: Deploy from the Azure CLI

RG="catalyst-prod"; LOCATION="eastus"; VM_NAME="catalyst-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/catalyst-soar-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name cat-vnet --address-prefix 10.103.0.0/16 --subnet-name cat-subnet --subnet-prefix 10.103.1.0/24
az network nsg create -g "$RG" --name cat-nsg
az network nsg rule create -g "$RG" --nsg-name cat-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name cat-nsg --name allow-web --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name cat-vnet --subnet cat-subnet --nsg cat-nsg --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

Both catalyst.service and catalyst-firstboot.service run automatically on first boot.

Step 4: Verify the Service

sudo systemctl is-active catalyst.service nginx.service catalyst-firstboot.service
sudo test -f /var/lib/cloudimg/catalyst-firstboot.done && echo FIRSTBOOT_DONE
sudo ss -tlnp | grep -E ':8090 |:80 '
swapon --show || echo "no swap (correct)"

Catalyst listens on loopback 127.0.0.1:8090 and is reached only through the nginx reverse proxy on port 80.

catalyst, nginx and firstboot services active; Catalyst on 127.0.0.1:8090 loopback and nginx on port 80; no swap on disk

Step 5: Retrieve the Admin Credentials

sudo cat /root/catalyst-credentials.txt
CATALYST_URL=http://<vm-ip>/
CATALYST_ADMIN_EMAIL=admin@catalyst.local
CATALYST_ADMIN_PASSWORD=<CATALYST_PASSWORD>

The password is unique to this VM, generated at first boot, and stored in a root-only file (mode 0600).

the per-VM credentials file at /root/catalyst-credentials.txt with a unique admin password, mode 0600 root:root

Step 6: Exercise the REST API

Log in for a bearer token, create an incident ticket, and read it back:

EMAIL=$(sudo grep '^CATALYST_ADMIN_EMAIL=' /root/catalyst-credentials.txt | cut -d= -f2-)
PASS=$(sudo grep '^CATALYST_ADMIN_PASSWORD=' /root/catalyst-credentials.txt | cut -d= -f2-)

TOKEN=$(curl -sf -X POST http://127.0.0.1:8090/auth/local/login \
  -H 'Content-Type: application/json' \
  -d "{\"email\":\"${EMAIL}\",\"password\":\"${PASS}\"}" \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')

# Create an incident (the "incident" ticket type ships by default; severity is in state)
TID=$(curl -sf -X POST http://127.0.0.1:8090/api/tickets \
  -H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
  -d '{"type":"incident","name":"Phishing campaign against finance","description":"Reported by SOC","open":true,"schema":{},"state":{"severity":"High"}}' \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')

# Read it back
curl -sf http://127.0.0.1:8090/api/tickets/${TID} -H "Authorization: Bearer ${TOKEN}" | python3 -m json.tool

REST API round-trip: login returns a per-VM signed JWT, POST /api/tickets creates an incident, GET reads it back with severity High

Step 7: Open the Web Console

Browse to http://<vm-ip>/ — Catalyst redirects to the /ui/ console. Sign in with the email and password from /root/catalyst-credentials.txt.

the Catalyst web console sign-in form with Email and Password fields

The dashboard summarises open tickets by type, tickets per week, and your assigned work at a glance:

the Catalyst dashboard: task, ticket, user and reaction counts, a tickets-by-type donut chart and a tickets-per-week trend

Step 8: Work Incidents

The Incidents view lists every open incident with its age and owner. Alerts, Incidents and Vulnerabilities are separate ticket types, each with its own list:

the Catalyst incident list showing open incidents with title, owner and age, filterable by open or closed

Opening a ticket shows its full workspace: description, severity, tasks, comments, a timeline, links and evidence files — everything an analyst needs to run the investigation in one place:

an open Catalyst incident ticket with severity High, tasks, comments and timeline sections, and links and files panels

Automations live under Reactions in the sidebar: pair a trigger (webhook or collection hook) with an action (Python or outbound HTTP) to enrich or triage tickets without a human in the loop.

Step 9: Server Components

Component Path
Catalyst binary /usr/local/bin/catalyst
Data dir (SQLite + uploads) /var/lib/catalyst/catalyst_data
Environment file /etc/catalyst/catalyst.env
systemd unit /etc/systemd/system/catalyst.service
Firstboot script /usr/local/sbin/catalyst-firstboot.sh
nginx site /etc/nginx/sites-available/cloudimg-catalyst
Credentials /root/catalyst-credentials.txt (mode 0600)
Sentinel /var/lib/cloudimg/catalyst-firstboot.done
/usr/local/bin/catalyst --version
sudo ls -la /var/lib/catalyst/catalyst_data/
sudo systemctl is-enabled catalyst.service nginx.service catalyst-firstboot.service

catalyst binary version, the catalyst_data directory holding the SQLite database and uploads, and all three services enabled

Step 10: Managing the Service

sudo systemctl restart catalyst.service
sudo journalctl -u catalyst.service --no-pager -n 50
# Create an additional admin (username is derived from the email)
sudo bash -c 'cd /var/lib/catalyst && runuser -u catalyst -- /usr/local/bin/catalyst admin create analyst@example.com "$(openssl rand -hex 20)"'

Step 11: Security Recommendations

  • Rotate the admin password in the console (top-left account menu) or with catalyst admin set-password <email> <password>.
  • Restrict the NSG so port 80 only reaches trusted networks.
  • Front Catalyst with TLS at a reverse proxy or Azure Application Gateway for production — the built-in listener is plain HTTP on loopback behind nginx.
  • Add analyst accounts with the analyst group rather than sharing the admin login; manage users and groups in the console.
  • Back up /var/lib/catalyst/catalyst_data/ (the SQLite database and uploaded evidence) to Azure Blob storage.
  • Patch the OS monthly with sudo apt-get update && sudo apt-get upgrade && sudo reboot.

Step 12: Support and Licensing

Catalyst is licensed under AGPL-3.0. cloudimg provides commercial support for the image separately.

  • Email: support@cloudimg.co.uk
  • Website: www.cloudimg.co.uk
  • Support hours: 24/7, 24h response SLA

Deploy on Azure

Launch Catalyst SOAR on Ubuntu 24.04 with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7. support@cloudimg.co.uk