Catalyst SOAR on Ubuntu 24.04 on Azure User Guide
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.serviceon loopback127.0.0.1:8090, fronted by nginx on port 80catalyst-firstboot.servicecreating 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.

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).

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

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 dashboard summarises open tickets by type, tickets per week, and your assigned work at a glance:

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:

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:

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

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
analystgroup 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