Project: CloudEvents (App Definition and Development / Streaming & Messaging)
File: http-webhook.md

"Webhooks" are a popular pattern to deliver notifications between applications and via HTTP endpoints. In spite of pattern usage being widespread, there is no formal definition for Web Hooks. This specification aims to provide such a definition for use with , but is considered generally usable beyond the scope of CloudEvents. 1.1. 1.2. are a popular pattern to deliver notifications between applications and via HTTP endpoints. Applications that make notifications available, allow for other applications to register an HTTP endpoint to which notifications are delivered. This specification defines a HTTP method by how notifications are delivered by the sender, an authorization model for event delivery to protect the delivery target, and a registration handshake that protects the sender from being abused for flooding arbitrary HTTP sites with requests. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in . This specification prescribes rules constraining the use and handling of specific and headers. This specification also applies equivalently to HTTP/2 (), which is compatible with HTTP 1.1 semantics. Notifications are delivered using a HTTP request. The response indicates the resulting status of the delivery. HTTP-over-TLS (HTTPS) MUST be used for the connection. The HTTP method for the delivery request MUST be . The header MUST be carried and the request MUST carry a notification payload of the given content type. Requests without payloads, e.g. where the notification is entirely expressed in HTTP headers, are not permitted by this specification. This specification does not further constrain the content of the notification, and it also does not prescribe the that is used for delivery. If the delivery target supports and requires [Abuse Protection](#4-abuse-protection), the delivery request MUST include the `WebHook-Request-Origin` header. The `WebHook-Request-Origin` header value is a DNS name expression that identifies the sending system. The delivery response MAY contain a payload providing detail status information in the case of handling errors. This specification does not attempt to define such a payload. The response MUST NOT use any of the and the client MUST NOT follow any such redirection. If the delivery has been accepted and processed, and if the response carries a payload with processing details, the response MUST have the or status code. In this case, the response MUST carry a header. If the delivery has been accepted and processed, but carries no payload, the response MUST have the or status code. If the delivery has been accepted, but has not yet been processed or if the processing status is unknown, the response MUST have the status

If a delivery target has been retired, but the HTTP site still exists, the site SHOULD return a status code and the sender SHOULD refrain from sending any further notifications. If the delivery target is unable to process the request due to exceeding a request rate limit, it SHOULD return a status code and MUST include the header. The sender MUST observe the value of the Retry-After header and refrain from sending further requests until the indicated time. If the delivery cannot be accepted because the notification format has not been understood, the service MUST respond with status code [415 Unsupported Media Type][415]. All further error status codes apply as specified in . The delivery request MUST use one of the following two methods, both of which lean on the OAuth 2.0 Bearer Token model. The delivery target MUST support both methods. The client MAY use any token-based authorization scheme. The token can take any shape, and can be a standardized token format or a simple key expression. Challenge-based schemes MUST NOT be used. The access token is sent in the request header field defined by HTTP/1.1. For tokens, the "Bearer" scheme MUST be used. Example: ```text POST /resource HTTP/1.1 Host: server.example.com Authorization: Bearer mF_9.B5f-4.1JqM ``` When sending the access token in the HTTP request URI, the client adds the access token to the request URI query component as defined by "Uniform Resource Identifier (URI): Generic Syntax" , using the "access_token" parameter. For example, the client makes the following HTTP request: ```text POST /resource?accesstoken=mF9.B5f-4.1JqM HTTP/1.1 Host: server.example.com ``` The HTTP request URI query MAY include other request-specific parameters, in which case the "access_token" parameter MUST be properly separated from the request-specific parameters using "&" character(s) (ASCII code 38). For example: https://server.example.com/resource?accesstoken=mF9.B5f-4.1JqM&p=q Clients using the URI Query Parameter method SHOULD also send a Cache-Control header containing the "no-store" option. Server success (2XX status) responses to these requests SHOULD contain a Cache-Control header with the "private" option. Because of the security weaknesses associated with the URI method (see [RFC6750, Section 5][rfc6750]), including the high likelihood that the URL containing the access token will be logged, it SHOULD NOT be used unless it is impossible to transport the access token in the "Authorization" request header field or the HTTP request entity-body. All further caveats cited in apply equivalently. Any system that allows registration of and delivery of notifications to arbitrary HTTP endpoints can potentially be abused such that someone maliciously or inadvertently registers the address of a system that does not expect such requests and for which the registering party is not authorized to perform such a registration. In extreme cases, a notification infrastructure could be abused to launch denial-of-service attacks against an arbitrary web-site. To protect the sender from being abused in such a way, a legitimate delivery target needs to indicate that it agrees with notifications being delivered to

Reaching the delivery agreement is realized using the following validation handshake. The handshake can either be executed immediately at registration time or as a "pre-flight" request immediately preceding a delivery. It is important to understand is that the handshake does not aim to establish an authentication or authorization context. It only serves to protect the sender from being told to a push to a destination that is not expecting the traffic. While this specification mandates use of an authorization model, this mandate is not sufficient to protect any arbitrary website from unwanted traffic if that website doesn't implement access control and therefore ignores the `Authorization` header. Delivery targets SHOULD support the abuse protection feature. If a target does not support the feature, the sender MAY choose not to send to the target, at all, or send only at a very low request rate. The validation request uses the HTTP method. The request is directed to the exact resource target URI that is being registered. With the validation request, the sender asks the target for permission to send notifications, and it can declare a desired request rate (requests per minute). The delivery target will respond with a permission statement and the permitted request rate. The following header fields are for inclusion in the validation request. The `WebHook-Request-Origin` header MUST be included in the validation request and requests permission to send notifications from this sender, and contains a DNS expression that identifies the sending system, for example "eventemitter.example.com". The value is meant to summarily identify all sender instances that act on the behalf of a certain system, and not an individual host. After the handshake and if permission has been granted, the sender MUST use the `WebHook-Request-Origin` request header for each delivery request, with the value matching that of this header. Example: ```text WebHook-Request-Origin: eventemitter.example.com ``` The `WebHook-Request-Callback` header is OPTIONAL and augments the `WebHook-Request-Origin` header. It allows the delivery target to grant send permission asynchronously, via a simple HTTPS callback. If the receiving application does not explicitly support the handshake described here, an administrator could nevertheless still find the callback URL in the log, and call it manually and therewith grant access. The delivery target grants permission by issuing an HTTPS GET or POST request against the given URL. The HTTP GET request can be performed manually using a browser client. If the WebHook-Request-Callback header is used, the callback target MUST support both methods. The delivery target MAY include the `WebHook-Allowed-Rate` response in the callback. The URL is not formally constrained, but it SHOULD contain an identifier for the delivery target along with a secret key that makes the URL difficult to guess so that 3rd parties cannot spoof the delivery target. For example: ```text WebHook-Request-Callback:

``` The `WebHook-Request-Rate` header MAY be included in the request and asks for permission to send notifications from this sender at the specified rate. The value is the string representation of a positive integer number greater than zero and expresses the request rate in "requests per minute". For example, the following header asks for permission to send 120 requests per minute: ```text WebHook-Request-Rate: 120 ``` If and only if the delivery target does allow delivery of the events, it MUST reply to the request by including the `WebHook-Allowed-Origin` and `WebHook-Allowed-Rate` headers. If the delivery target chooses to grant permission by callback, it withholds the response headers. If the delivery target does not allow delivery of the events or does not expect delivery of events and nevertheless handles the HTTP OPTIONS method, the existing response ought not to be interpreted as consent, and therefore the handshake cannot rely on status codes. If the delivery target otherwise does not handle the HTTP OPTIONS method, it SHOULD respond with HTTP status code 405, as if OPTIONS were not supported. The OPTIONS response SHOULD include the header indicating the method being permitted. Other methods MAY be permitted on the resource, but their function is outside the scope of this specification. The `WebHook-Allowed-Origin` header MUST be returned when the delivery target agrees to notification delivery by the origin service. Its value MUST either be the origin name supplied in the `WebHook-Request-Origin` header, or a singular asterisk character ('\*'), indicating that the delivery target supports notifications from all origins. ```text WebHook-Allowed-Origin: eventemitter.example.com ``` or ```text WebHook-Allowed-Origin: * ``` The `WebHook-Allowed-Rate` header MUST be returned alongside `WebHook-Allowed-Origin`if the request contained the `WebHook-Request-Rate` header, otherwise it SHOULD be returned. For the callback model, the `WebHook-Allowed-Rate` header SHOULD be included in the callback request. If the header is not included, for instance when a callback is issued through a browser as a GET request, the allowed rate SHOULD correspond to the requested rate. The header grants permission to send notifications at the specified rate. The value is either an asterisk character or the string representation of a positive integer number greater than zero. The asterisk indicates that there is no rate limitation. An integer number expresses the permitted request rate in "requests per minute". For request rates exceeding the granted notification rate, the sender ought to expect request throttling. Throttling is indicated by requests being rejected using HTTP status code . For example, the following header permits to send 100 requests per minute: ```text WebHook-Allowed-Rate: 100 ``` Key words for use in RFCs to Indicate Requirement Levels HTTP over TLS The OAuth 2.0 Authorization Framework: Bearer Token Usage Additional HTTP Status Codes Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content Hypertext Transfer Protocol (HTTP/1.1): Authentication Hypertext Transfer Protocol Version 2 (HTTP/2)