Documentation

Install, run and deploy zsazsa

This guide is distilled from the project README. For the complete reference, including every configuration tab and data collection source type, see the README on GitHub.

zsazsa is a CTI program management and production platform built around MISP. It sits on top of your MISP infrastructure and does not install MISP or misp-scraper for you.

Before you install

zsazsa requires the following infrastructure to be in place first:

  • A MISP server to store CTI program data. Where zsazsa saves its objects: stakeholders, PIRs, GIRs, flash intel alerts, advisories, briefings and so on. This is the server you point MISP_WEBAPP_URL at.
  • A MISP server running misp-scraper. The scraper feeds threat events into a MISP instance that zsazsa polls for the data collection view and analyser pipeline. This is the server you point MISP_URL at, and it can be the same server as above.
  • One or more additional MISP servers (optional but recommended). Supplementary intelligence feeds configured under Collection sources, ideally partner-operated or community instances.
zsazsa
CTI program management app
MISP
Program data store · MISP_WEBAPP_URL
MISP scraper
Collection pipeline · MISP_URL

zsazsa runs on top of MISP. One MISP instance stores its program data; another, running misp-scraper, feeds the collection pipeline. The two can be the same server.

Note: Follow the official installation guides for MISP and misp-scraper first. zsazsa does not install them.

Installation

Installation is recommended inside the MISP custom application directory so it runs under the same web user as MISP. On Ubuntu this means installing as www-data:

# Create the custom app directory if it doesn't exist
mkdir /var/www/MISP/misp-custom
chown www-data:www-data /var/www/MISP/misp-custom

cd /var/www/MISP/misp-custom
sudo -u www-data git clone https://github.com/zsazsa-project/zsazsa/ zsazsa
cd zsazsa
sudo -u www-data bash docs/install.sh

The installer creates a venv in the project root, installs Python dependencies, prepares the data directory, and creates config/__init__.py if needed. After installation, edit config/__init__.py and set your MISP URL and API key settings.

Running the application

For local testing, start the application directly:

source venv/bin/activate
python run_webapp.py

For any real deployment, run zsazsa behind a reverse proxy rather than exposing the built-in server directly. The proxy can be the same web server that already serves your MISP instance, so zsazsa lives under a subpath of your existing MISP site (for example https://misp.example.com/zsazsa). This is the recommended setup and is covered in Production deployment behind Apache below.

The analyser pipeline runs separately, typically via cron:

source venv/bin/activate
python run_analyser.py
python run_imap_collector.py

Production deployment behind Apache

zsazsa can be served under a subpath of the MISP Apache virtual host, for example https://misp.example.com/zsazsa. The application adapts to any subpath automatically.

1. Keep it running with systemd. Copy the service template, then enable it. For production, bind the listener to localhost (127.0.0.1) in run_webapp.py so it is only reachable through Apache.

sudo cp docs/zsazsa.service.template /etc/systemd/system/zsazsa.service
sudo systemctl daemon-reload
sudo systemctl enable --now zsazsa.service

2. Enable required Apache modules:

sudo a2enmod proxy proxy_http headers
sudo systemctl reload apache2

3. Add the proxy inside the existing <VirtualHost *:443> block:

# zsazsa CTI application
ProxyPreserveHost On
RequestHeader set X-Forwarded-Prefix "/zsazsa"
RequestHeader set X-Forwarded-Proto "https"

ProxyPass        /zsazsa  http://127.0.0.1:5000/
ProxyPassReverse /zsazsa  http://127.0.0.1:5000/

The value in X-Forwarded-Prefix must match the path used in ProxyPass/ProxyPassReverse. The application reads these headers at runtime to construct links and build correct https:// URLs. Without a proxy, both headers are absent and the application behaves exactly as before.

Configuration

Almost all runtime settings live in config/__init__.py, and most can be changed from the web interface without editing the file directly. The main settings page at /config groups settings across eight tabs:

TabCovers
ConnectionsThe MISP server zsazsa uses as its own data store (MISP_WEBAPP_URL, MISP_WEBAPP_KEY, MISP_WEBAPP_VERIFYCERT)
ProductsProduct type catalogue and organisation-wide focus points
SystemAnalyser window, log retention, web server host/port and TLS
PromptsPrompt templates in zsazsaprompts/
AIThe OpenAI and local LLM providers, and per-feature provider, model, temperature and prompt overrides — see AI providers
Context elementsMISP tags, markers and action presets
NotificationsNamed delivery channels: Mattermost webhooks, e-mail over SMTP and Flowintel instances (Teams planned)
StylingBranding used in PDF exports and notifications

Collection sources, namely the MISP scraper connection, additional MISP servers, manual sources and IMAP mailboxes for automatic newsletter collection, are managed separately at /config/sources/. The config file is backed up to config/__init__.py.backup before each save.

zsazsa collection sources configuration
Collection sources are managed centrally at /config/sources/, including the scraper, additional MISP servers and manual sources.

AI providers

zsazsa's AI-assisted features work with two kinds of LLM provider, both set up on the AI tab of the settings page. Each can be enabled on its own, and one of the two is marked as the default provider.

  • OpenAI — an API key, a default model and the token usage counters.
  • Local LLM — any server speaking the OpenAI API, for example Ollama. You give it the base URL of the endpoint, such as http://127.0.0.1:11434, and the /v1 path is appended for you if you leave it off. Ollama ignores the API key, so leave it empty unless the server sits behind a proxy that checks it.
Where your event text goes. These features send raw MISP event text to whichever provider is configured. Running a local model keeps that content on your own infrastructure.

Below the provider cards, a table lists every AI-assisted feature with the provider it uses, an optional model override, a sampling temperature and its prompt file. An empty model field means the feature falls back to its provider's default model, and a provider cannot be disabled while features still point at it. Token usage is recorded per provider, so local calls are counted separately from OpenAI ones.

zsazsa AI provider and per-feature configuration
The AI tab: provider cards for OpenAI and a local LLM, with the per-feature provider, model, temperature and prompt table underneath.

Two things are worth knowing before you point features at a local model. Leaving the temperature empty hands sampling to the model, which locally can mean a value as high as 1.0; since nearly every feature parses the response back into structured data, a low temperature keeps that output stable. And reasoning models spend part of the token budget thinking before they answer — zsazsa asks the server to skip that step, which Ollama honours, but a server that ignores the request can spend the whole budget and return nothing.

The exact settings for both providers, and the per-feature overrides, are documented in INSTALL.md in the repository.

MISP data model

Each business entity is stored as one MISP event, with data held inside a custom MISP object. Custom object templates live in webapp/misp_objects/.

EntityMISP object
Stakeholderzsazsa-stakeholder
PIRzsazsa-pir
GIRzsazsa-gir
RFIzsazsa-rfi
Flash intel alertzsazsa-flash-intel
VEAzsazsa-vea
Daily briefingzsazsa-daily-briefing
Threat landscape reportzsazsa-threat-landscape-report
Indicator feedzsazsa-indicator-feed
Threat actor profilezsazsa-threat-actor-profile
Collection sourcezsazsa-collection-source

Every entity event carries a type tag so it can be searched independently of the object. All tags in the zsazsa: namespace are applied as local tags, so they never sync to connected MISP instances.

zsazsa product content and context stored in MISP
Product content and supporting context sit together in MISP, so analysts can trace from collection evidence to published output.

Full reference

This page covers the essentials. The complete README documents the notification and distribution flow, per-product coverage, every configuration setting, and how to create each data collection source type.

Read the full README Go to download