# Wazuh 5.0 decoder that matches source.ip against the known_malicious_ips KVDB.
#
# Pattern taken from the official CDB-to-KVDB migration guide:
# https://github.com/wazuh/wazuh/blob/main/docs/guide/migration/cdb-to-kvdb-migration.md
#
# In Wazuh 4.x this logic lived in a rule, as <list field="srcip" lookup="address_match_key">.
# In 5.0 there is no <list> element and no rule-level lookup: KVDB lookups live in a decoder's
# check or normalize stage.
#
# PARTIAL BY DESIGN: `parents` below points at decoder/json/0, which is the parent used in the
# migration guide's own example. Set it to the parent that actually decodes your log source in
# your deployment, and generate a fresh UUIDv4 for `id`.

name: decoder/ip-blocklist-misp/0
id: <replace-with-a-new-uuidv4>
enabled: true
parents:
  - decoder/json/0
metadata:
  title: Source IP present in the MISP blocklist
  description: Matches source IPs found in the known_malicious_ips KVDB.
  author: Security Operations
  date: "2026-09-22"
check:
  # kvdb_match succeeds only when the current value of source.ip exists as a KEY in the KVDB.
  # Exact string match. For subnets use ip_cidr_match instead, for example:
  #   - ip_cidr_match/192.0.2.0/24/$source.ip
  - source.ip: kvdb_match('known_malicious_ips')
normalize:
  - map:
      - wazuh.threat.groups: array_append(misp-blocklist)

# Allowlist variant: swap kvdb_match for kvdb_not_match to reproduce the 4.x not_match_key
# behaviour, which fired when a value was ABSENT from the list.
#
# check:
#   - source.ip: kvdb_not_match('egress_allowlist')
#
# Retrieving the stored value instead of only testing membership uses kvdb_get in a map stage:
#
# normalize:
#   - map:
#       - wazuh.threat.groups: kvdb_get('known_malicious_ips', $source.ip)
#
# A failed normalize block is skipped without rejecting the event; a failed check rejects the
# event from this decoder branch.
