Skip to content

feat(insights): push ban decisions to insights - #193

Draft
gsanchietti wants to merge 1 commit into
mainfrom
insights
Draft

feat(insights): push ban decisions to insights#193
gsanchietti wants to merge 1 commit into
mainfrom
insights

Conversation

@gsanchietti

Copy link
Copy Markdown
Member

Summary

Each node only bans what it saw itself, so the fleet has no shared memory of a scanner hitting many machines. This sends every ban decision to nethesis-insights, where a later project can turn them into a global blacklist. Building that blacklist is not part of this PR.

Delivery reuses CrowdSec's own notification-http plugin, the same mechanism the email alerts already use — no polling, no cursor, no extra timer. Decisions fired within 30 seconds go out in one request. It is best effort: a decision made while the service is restarting is not retried.

Identity is the node's subscription, read fresh from Redis every time the config is written. Nothing is stored in the module environment, so a configured webhook cannot be aimed at another tenant, and a node that subscribes later starts working on its next reload. A terminated subscription clears the config.

The receiving endpoint does not exist yet, so nothing works end to end until nethesis-insights implements POST /v1/blocklist-evidence. The body it will receive:

{
  "schema_version": 1,
  "system_id": "<system_id>",
  "decisions": [
    {
      "id": 1234,
      "value": "203.0.113.7",
      "scope": "Ip",
      "type": "ban",
      "scenario": "crowdsecurity/ssh-bf",
      "origin": "crowdsec",
      "duration": "3h59m59s",
      "created_at": "2026-08-07T14:00:00Z"
    }
  ]
}

Auth is Authorization: Basic base64(system_id:auth_token), same as the existing /v1/bundles. Configuration input matches ns8-loki #70.

How to test

api-cli run module/crowdsec1/set-insights --data '{
  "active": true, "base_url": "http://<stub>", "verify_tls": false
}'
api-cli run module/crowdsec1/get-configuration | jq .insights

# provoke a decision, then check the stub received a POST
runagent -m crowdsec1 cscli decisions add --ip 203.0.113.7 --duration 1m

api-cli run module/crowdsec1/set-insights --data '{"active": false}'

Reload must not drop the container, and no token should appear in journalctl -u crowdsec1 or in module/crowdsec1/environment.

Not done yet

  • Never run against a live CrowdSec. The alert payload shape is built from upstream's pkg/models, verified only by executing the Go template against synthetic decisions locally.
  • No automated tests. This repo has no unit-test harness and the Robot suite was not extended.

Each node only bans what it saw itself, so the fleet has no shared
memory of a scanner hitting many machines. Send every ban decision to
nethesis-insights, where a later project can turn them into a global
blacklist.

Delivery reuses CrowdSec's own http notification plugin, the same way
email alerts already work: no polling, no cursor, no extra timer.
Decisions within 30 seconds go out in one request.

Identity is the node subscription, read fresh from Redis at every
render. Nothing is stored in the module environment, so a configured
webhook cannot be aimed at another tenant, and a node that subscribes
later starts working on its next reload.

Delivery is best effort. A decision made while the service restarts is
not retried.

The receiving endpoint does not exist yet.

Assisted-by: Claude Code:claude-opus-5[1m]
@gsanchietti gsanchietti self-assigned this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant