KE
feat: add SNMP provider
keephq/keep#5664

SNMP Provider

Closes #2112

Adds a webhook-based SNMP provider that ingests SNMP trap events from network devices into Keep as alerts. Compatible with any SNMP trap forwarder (snmptrapd, Zabbix, OpenNMS, etc.) that can POST JSON to an HTTP endpoint.


Features

Protocol Support

  • SNMPv1 — generic trap types (0–6) via generic_trap integer field
  • SNMPv2c — standard notification OIDs (e.g. 1.3.6.1.6.3.1.1.5.3)
  • SNMPv3 — enterprise OID-based traps with user-supplied severity

Alert Mapping

  • Well-known trap OIDs map to human-readable names (linkDown, coldStart, authenticationFailure, etc.)
  • Automatic severity from OID: linkDown → CRITICAL, authenticationFailure → WARNING, linkUp → INFO
  • User-supplied severity field overrides OID default (supports: critical, major, minor, warning, info, clear)
  • Auto-resolve: linkUp traps (v1 generic_trap=3 and v2c 1.3.6.1.6.3.1.1.5.4) set status to RESOLVED
  • Status override via status field: firing, resolved, acknowledged, clear

Varbind Normalisation

  • Accepts varbinds as a flat dict, list of {oid, value} objects, or raw string (snmptrapd pipe output)

Fingerprinting

  • FINGERPRINT_FIELDS = ["oid", "agent_address", "enterprise", "specific_trap"]
  • Includes enterprise + specific_trap so enterprise-specific traps (generic_trap=6) from the same agent do not collapse into a single alert

Setup Documentation

  • webhook_markdown includes full snmptrapd config, handler script, and direct JSON payload examples for both v1 and v2c formats

Implementation

keep/providers/snmp_provider/
├── __init__.py
└── snmp_provider.py
  • No external dependencies — stdlib + Keep internals only
  • Webhook-only (no polling); no auth config required
  • _format_alert() handles all format variants; _get_trap_info() and _parse_varbinds() are separately testable static methods

Tests

tests/test_snmp_provider.py — 19 tests covering:

Test What it covers
v2c linkDown CRITICAL severity, FIRING status, correct OID
v1 linkDown generic_trap integer → OID resolution
v1 linkUp auto-resolve to RESOLVED / INFO
coldStart WARNING severity, not resolved
authFailure WARNING, description preserved
Enterprise v3 + severity override user severity=critical on unknown OID
Custom name + major severity name preserved, HIGH severity
User status override acknowledged overrides auto-status
Varbinds dict passthrough unchanged
Varbinds list normalised to flat dict
Varbinds string wrapped as {"raw": ...}
Varbinds missing defaults to {}
Empty event no crash, valid AlertDto
simulate_alert() mock wired correctly
Integer severity no AttributeError on .lower()
Enterprise-specific trap dedup specific_trap preserved for fingerprinting
id=None when missing not empty string
OID numeric-key fallback 1.3.6.1.6.3.1.1.4.1.0 key resolves correctly

/claim #2112

Claim

Total prize pool $200
Total paid $0
Status Pending
Submitted February 21, 2026
Last updated February 21, 2026

Contributors

MI

Michael

@jonesy827

100%

Sponsors

KE

Keep (YC W23)

@keephq

$200