standard-webhooks / standard-webhooks

The Standard Webhooks specification

Home Page:https://www.standardwebhooks.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

spec: RFC - add source/type as header metadata

Ch4ni opened this issue · comments

commented

Per the payload specification, the payload body type, structure, shape, and required keys are not prescribed, though there are recommendations.

It seems as though the webhook metadata headers aim to mitigate this by providing an event's unique id, which I have interpreted as the idempotent id of a particular instance of an event:

The unique identifier is a unique identifier associated with a specific event triggered, and it remains the same no matter how many times a webhook that has failed is retried. The ID is often used as an idempotency key, which lets a consumer ensure that they only process a specific event once, even if sent multiple times maliciously, in error, or due to networking issues.

The lack of appropriate metadata will require new endpoints, or provider-defined (implementation detail) metadata, which appears contrary to the proposed goal of this standard.

Consider

A sample ecommerce system that integrates with payment provider foo and payment provider bar. Providing a webhook for providers to indicate the success of a transaction would be desirable using a single endpoint that could determine the event source so that the event could be routed through the appropriate code paths.

Let us assume that provider foo transmits data via https using serialized JSON, and provider bar uses a proprietary encrypted binary payload.

There is no method, via the spec, to determine if an event is sent by provider foo, or sent by provider bar, leaving the only methods to differentiate:

  1. Using a different endpoint for each provider
  2. Attempting to determine the provider by deserializing the payload - this depends entirely upon implementation details.

This is a side effect of the nature of the internet - a provider need not send a request from a particular ip block or domain, and not all events are required to come from the same origin. In theory, an event may come from one domain/ip block, and a retry for the idempotent event id may originate from a different domain or ip block. Potential examples of this may be a provider making use of hybrid cloud, with producers spread across different cloud providers (such as aws and azure) - these event producers may not be assigned a public domain if the services are egress-only.

Proposal

Italics to be interpreted per RFC-2119

Include webhook-source headers that must be populated by a producer (the thing sending events to a webhook endpoint). At minimum, this value must be unique per provider (for example, two services that send webhook events by provider foo may use the same value, but there must not be any collision with the values used by any other provider. It is recommended that producers use a unique reverse DNS format as in the Java package naming standards.

A producer should also include a webhook-type header to allow proper routing of payload deserialization in the event that a single provider (webhook-source) produces different events that may contain disparate payload formats.

The two proposed headers are complementary, though they may alternatively be combined into a single header using a fully-qualified (read: namespaced) event type, allowing multiple producers to use the same event type without collisions.

The standard webhook specification must define the format of said header, which is beyond the scope of this rfc at its current stage.

Rationale/Benefits

Providing lightweight metadata that is prescribed by the standard webhook specification will open the door for unified webhook endpoints that can handle a single logical event from multiple providers. In theory, it could also be used to provide a single universal webhook endpoint - how this is implemented is entirely up to event consumers.

With the standardized metadata, a consumer can make decisions about how to handle an event with minimal (cognitive or technical) overhead, i.e. without attempting to deserialize the event payload.

Alternative

To mitigate the considered issue, the standard webhook specification could instead prescribe compatible payload formats (i.e. JSON, protobuf) and a minimum required set of top-level keys in the payload (such as: source, type, event-uid, and then a data key to store what would currently be the payload or request body).

This approach seems overly restrictive, and potentially less flexible.