Class: Insika::Channels::Webhook
- Inherits:
-
Object
- Object
- Insika::Channels::Webhook
- Defined in:
- lib/insika/channels/webhook.rb
Overview
A webhook as a Shape B "channel": the recipient of operator ALERTS (WS6). One instance per configured URL, registered in the ChannelRegistry so ChannelDelivery's outbox+claim+retry pipeline delivers the alert the same way it delivers a chat answer — at-most-once, bounded retry, boot sweep. Deliberately NOT Slack/CRM/anything: it POSTs the event as JSON and the consumer interprets it (the engine transports, it does not integrate).
The target URL is operator configuration, so the POST crosses the SAME
egress guard the Relay applies: https-only (fails closed), private/
loopback/metadata targets and DNS-rebindable hosts blocked. Without it the
alerts.webhook URL is an SSRF vector — a URL pointed at cloud metadata
or an internal API exfiltrates alert events out of the boundary (WS6).
Instance Method Summary collapse
-
#deliver(payload, to:, delivery_id: nil) ⇒ Object
The ChannelDelivery contract: -> HTTP status (200..299 = delivered).
-
#initialize(url, http:, allow_http: false, allow_private: false) ⇒ Webhook
constructor
A new instance of Webhook.
Constructor Details
#initialize(url, http:, allow_http: false, allow_private: false) ⇒ Webhook
Returns a new instance of Webhook.
20 21 22 23 24 |
# File 'lib/insika/channels/webhook.rb', line 20 def initialize(url, http:, allow_http: false, allow_private: false) @http = http @allow_http = allow_http @allow_private = allow_private end |
Instance Method Details
#deliver(payload, to:, delivery_id: nil) ⇒ Object
The ChannelDelivery contract: -> HTTP status (200..299 = delivered). Every failure becomes a DeliveryError so the bounded retry records it.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/insika/channels/webhook.rb', line 28 def deliver(payload, to:, delivery_id: nil) if (reason = egress_violation(to)) raise Insika::DeliveryError, "webhook egress blocked for #{to}: #{reason}" end result = @http.request( method: :post, url: to, headers: { "content-type" => "application/json" }, body: JSON.generate(payload) ) result[:status].to_i rescue Insika::DeliveryError raise rescue StandardError => e raise Insika::DeliveryError, "webhook: #{e.}" end |