Post Archive

Operationalizing MISP with Cratos API

Your MISP instance is full of hard-won intelligence. Getting it into the controls that act on it — without exposing credentials, context, or the instance itself — is a problem Cratos was built to solve.

Cratos FastAPI project logo

The indicator gap

MISP is where the intelligence lives. Events, attributes, relationships, context — years of curated threat data that analysts have fought to maintain. But when the firewall team asks for a fresh blocklist, or the EDR engineers want a daily feed of known-bad hashes, the answer is usually a bespoke script, a manual export, or a MISP API key handed to a team that probably shouldn't have it.

This is the indicator gap: the distance between intelligence that exists in MISP and controls that are ready to act on it. The gap is not always technical. Often it is organizational — a reluctance to expose the MISP instance broadly, or a lack of a clean, consistent interface that other teams can depend on without understanding MISP internals.

Cratos FastAPI was designed specifically to close that gap.

A proxy with purpose

Cratos is a lightweight FastAPI application that sits in front of one or more MISP instances and exposes a structured, token-authenticated REST API. Consumers — firewalls, SIEMs, proxies, EDR platforms — call Cratos endpoints to retrieve indicator lists. They never touch MISP directly. They never see event context. They receive exactly what they are authorized to receive, in a format they can immediately act on.

The architecture is intentionally simple. A single Python service, managed by systemd or Supervisor, fronted by Nginx, with optional Memcached caching to absorb repeated requests without hammering MISP. You can run it on the same host as MISP or on a dedicated jump box. Multi-MISP setups are supported — each instance gets its own site configuration file.

The classification model

The most important design decision in Cratos is how it maps intelligence to operational feeds. Rather than exposing raw MISP attributes, it uses a tag-based classification model. You decide which MISP tags map to which feed groups — and Cratos handles the extraction and serving.

Each MISP instance is registered with a short identifier called a tag prefix. That prefix, combined with a classification label, forms the MISP tag that Cratos looks for. The built-in classification groups are:

  • incident — indicators tied to active or confirmed incidents
  • alert — high-confidence indicators warranting immediate attention
  • block — indicators ready for active enforcement in controls
  • hunt — indicators useful for proactive threat hunting, not yet blocking

Beyond those, each site configuration can define up to five custom feed groups — mapped to any MISP tag you choose. This makes Cratos adaptable to environments that already have an established tagging convention: sinkhole traffic, TOR exit nodes, permanent blocks, or whatever classification scheme your team already uses.

Configuring a MISP connection

Each MISP instance you want to expose through Cratos gets a YAML file in the sites/ directory. The filename is the fully qualified hostname of the MISP instance. A site config controls authentication, IP allowlisting, caching timeouts, false-positive handling, and the custom feed mappings.

A site config for a MISP instance called misp.example.net might look like this:

---

enabled: true
debug: false
company: Example ApS
tag: example
mispVerifyCert: true
mispTimeoutSeconds: 100
memcached_all_timeout: 300
falsepositive_timeout: "1w"
list_stats: "1w"
allowed_ips:
  - "10.0.0.0/8"
  - "127.0.0.1/32"
  - "192.168.1.0/24"
custom_feeds:
  cust1: ":incident-classification=sinkhole"
  cust2: ":incident-classification=permanent-block"
  cust3: ":incident-classification=tor-exitnode"

With tag: example set, Cratos will look for MISP tags in the form example:incident-classification=block, example:incident-classification=hunt, and so on. Tag your events in MISP using that convention and the indicators flow automatically into the matching feed group — no further intervention required.

A key operational note: the allowed_ips field controls which sources may call the Cratos API for this particular MISP instance. This is a per-site restriction layered on top of the global allways_allowed_ips list in the core config, which is typically reserved for monitoring infrastructure.

What consumes the feeds

Once Cratos is running and indicators are tagged correctly in MISP, operationalizing intelligence becomes a matter of pointing consumers at the right endpoint. Common integration patterns include:

  • Firewalls — pull the block feed on a scheduled basis for active IP and domain enforcement
  • Mail gateways — ingest sender reputation and phishing domain feeds to block delivery
  • EDR / AV platforms — consume hash feeds for active blocking or passive detection depending on confidence level
  • Proxy solutions — enforce URL and domain blocklists derived from the block and alert feeds
  • SIEM — subscribe to the hunt feed for correlation rules that generate alerts without blocking
  • Vulnerability management teams — receive indicator feeds enriched with CVE context to prioritize patching against known-exploited infrastructure

Each of these integrations operates independently. A firewall team that only needs IP blocklists gets exactly that. A SIEM team building detection rules gets the hunt feed. Nobody needs MISP access. Nobody can query beyond what their token authorizes.

Token-gated access

Cratos uses API tokens rather than MISP credentials for consumer authentication. Tokens are generated through a built-in web form at /v1/generate_token_form once the service is running. Each token can be scoped to a specific set of feeds and IP ranges, so that a firewall integration pulling the block list operates under a different token than a SIEM team pulling the hunt feed.

This separation matters operationally. When a token needs to be rotated — because a vendor changed, or a team was restructured — you rotate one token without affecting any other integration. The blast radius of a compromised credential is contained to a single consumer.

Standing it up

The recommended deployment is a Debian or Ubuntu server. Getting Cratos running requires cloning the repository, installing system dependencies, creating a Python virtual environment, generating encryption keys for the core config, and writing the site YAML files for each MISP instance.

$ sudo apt install git
$ cd /opt
$ git clone https://github.com/eCrimeLabs/cratos-fastapi.git
$ cd cratos-fastapi
$ sudo apt install nginx gcc openssl libssl-dev python3-dev python3-venv
$ python3 -m venv .venv
$ .venv/bin/pip install -r requirements.txt

The core config at config/config.yaml requires a generated encryption key and salt. Both can be produced with one-liners using openssl and /dev/urandom. Memcached is optional but recommended in production environments — it prevents repeated API calls from hitting MISP directly and substantially reduces query latency for consumers that poll frequently.

For production deployments the recommended process manager is systemd backed by Gunicorn, which provides crash recovery, boot persistence, and resource controls. Nginx handles TLS termination and reverse proxying — be sure to configure the reverse_proxy and reverse_proxy_header options in the core config so Cratos sees real client IPs rather than the loopback address.

Presented at Hack.lu in 2023

Cratos was presented publicly at Hack.lu 2023 under the title "Cratos — Use your bloody indicators". The talk walked through the full lifecycle: from indicators sitting idle in MISP, to structured feeds flowing into active controls, to metrics showing the operational impact. If you prefer to see the concept in motion before deploying, the recording is a good starting point.

Watch the Hack.lu 2023 talk on YouTube →

The core argument of the talk mirrors the premise of this post: threat intelligence that does not reach the controls that act on it is expensive data storage, not intelligence. Cratos is the bridge.

Closing thoughts

Cratos does not try to replace MISP or redefine how you structure your intelligence. It respects the work already done — the tagging conventions, the event curation, the enrichment pipelines — and adds the missing layer: a controlled, observable, consumer-friendly interface that makes your indicators useful beyond the analyst who created them.

If your team is maintaining solid intelligence in MISP but struggling to get it into firewalls, EDR, or SIEM in a repeatable way, Cratos is worth an afternoon of evaluation. The install is straightforward, the configuration is legible, and the operational model maps cleanly onto how most security teams already think about indicator classification.

The project is open source under the MIT license and actively maintained on GitHub.