Skip to content

Decision Processing

How the bouncer processes incoming CrowdSec decisions.

  1. Receive decision from LAPI

    The bouncer fetches new and expired decisions from the CrowdSec Local API.

  2. Check scope

    | Scope | Action | Example | | ------- | ------------------------------ | ------------- | | Ip | Added directly to address list | 192.168.1.1 | | Range | Added as CIDR to address list | 10.0.0.0/24 | | Other | Logged as warning, skipped | — |

  3. Filter by origin

    If origins is configured, only decisions from allowed origins pass through. Unmatched decisions are discarded.

  4. Filter by scenario

    If scenarios_containing or scenarios_not_containing is configured, only decisions whose scenario name passes those substring filters are processed.

  5. Apply action

    • Ban → Add IP/range to the MikroTik address list
    • Unban → Remove IP/range from the address list

When origins is configured, the bouncer only processes decisions from the specified origins:

| Origin | Source | | ---------- | ----------------------------------------- | | crowdsec | Local CrowdSec engine detections | | cscli | Manual bans via cscli decisions add | | CAPI | CrowdSec Central API community blocklists | | lists:* | Third-party blocklist subscriptions |

crowdsec:
origins: ["crowdsec", "cscli"] # Ignore CAPI community lists

When origins is empty (default), all origins are accepted.

Scenario filters use CrowdSec’s scenarios_containing and scenarios_not_containing fields. They match literal substrings in the scenario name, such as ssh, http, or crowdsecurity/ssh-bf.

crowdsec:
scenarios_containing:
- "ssh"
- "http"
scenarios_not_containing:
- "test"

Use scenarios_containing to keep only matching scenarios. Use scenarios_not_containing to exclude noisy or unwanted scenarios when the bouncer processes decisions received from CrowdSec’s LAPI.

When the same IP appears in multiple decisions (e.g., different scenarios or origins), the bouncer handles this efficiently:

  1. During bans: Checks the in-memory cache first. If the address is already known to be present, the RouterOS API call is skipped.
  2. During unbans: Checks the in-memory cache first and only removes from MikroTik if the IP is actually present
  3. On startup and periodic reconciliation: The decision collector deduplicates IPs before reconciliation
  4. After cache misses: If RouterOS still replies with already have such entry, the bouncer treats it as a device-level conflict, keeps the API session open, finds the existing entry, updates its timeout/comment, and records the address in cache. This write path only happens when the address was missing from the local cache.