This document defines a Webhook-based notification suite for the Linked Web Storage (LWS) protocol, enabling LWS servers to deliver resource change notifications to registered endpoints via HTTP POST.

This is an unofficial proposal.

Introduction

The [[!LWS10-CORE|Linked Web Storage]] protocol defines a notification mechanism that allows clients to subscribe to resource changes and receive updates through various delivery channels. This document describes the Webhook notification suite — a server-to-server mechanism whereby the LWS storage server delivers change events to a registered endpoint via HTTP POST.

Terminology

The terms "notification", "subscription", "subscriber", "notification suite", "storage description resource", and "agent" are defined by the Linked Web Storage Protocol [[!LWS10-CORE]].

The terms "controlled identifier document", "verification method", and "verification relationship" are defined by Controlled Identifiers 1.0 [[!CID-1.0]].

This specification defines the following additional terms:

Creating a Webhook Subscription

When a client creates a webhook notification subscription, the subscription body MUST include a type field equal to WebhookSubscription. In addition, a server MUST support the following fields:

POST /subscriptions HTTP/2
Host: notification.example
Authorization: Bearer <access-token>
Content-Type: application/lws+json

{
  "@context": ["https://www.w3.org/ns/lws/v1"],
  "type": "WebhookSubscription",
  "topic": [
    "https://storage.example/alice/notes/",
    "https://storage.example/alice/profile"
  ],
  "inbox": "https://receiver.example/hooks/lws",
  "expires": "2026-06-09T12:00:00Z"
}
      

A successful response body has these additional requirements:

HTTP/2 200 OK
Content-Type: application/lws+json
Location: https://notification.example/subscriptions/9e8d7c6b5a4f

{
  "@context": ["https://www.w3.org/ns/lws/v1"],
  "type": "WebhookSubscription",
  "subscription": "https://notification.example/subscriptions/9e8d7c6b5a4f",
  "expires": "2026-06-09T12:00:00Z"
}
      

Webhook Authentication

When a server delivers a notification to an inbox, the subscriber needs to verify that the request is authentic.

A server SHOULD sign each outbound request using HTTP Message Signatures [[!RFC9421]]. When an inbox receives a signed message, it MUST verify the signature using the notification server's public key, discoverable via the storage description resource.

A server that supports HTTP Message Signatures MUST include the signing key in the storage description resource. The key MUST be expressed as a verification method in a verificationMethod array, and MUST be referenced from an authentication verification relationship, following the Controlled Identifiers 1.0 [[!CID-1.0]] data model.

{
  "@context": ["https://www.w3.org/ns/lws/v1"],
  "id": "https://storage.example/",
  "type": "Storage",
  "verificationMethod": [{
    "id": "https://storage.example/#key-20260320",
    "type": "JsonWebKey",
    "controller": "https://storage.example/",
    "publicKeyJwk": {
      "kid": "key-20260320",
      "kty": "EC",
      "crv": "P-256",
      "alg": "ES256",
      "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
      "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
    }
  }],
  "authentication": ["https://storage.example/#key-20260320"],
  "service": [{
    "type": "NotificationService",
    "serviceEndpoint": "https://notification.example/subscriptions",
    "subscriptionType": ["WebhookSubscription"]
  }]
}
      

Signature Requirements

A server that signs webhook delivery requests MUST include at least the following components in the signature base:

The Signature-Input field MUST include the created and keyid parameters. The keyid value MUST correspond to the id of a key in the verificationMethod array of the storage description resource.

Signature Verification

To verify a webhook signature, a receiver MUST perform the following steps:

  1. Extract the keyid value from the Signature-Input field. The keyid value MUST be a URL with a fragment component.
  2. Remove the fragment component from the keyid URL. The resulting URL is the storage identifier.
  3. Dereference the storage identifier to retrieve the storage description resource. The id property of the top-level document map MUST match the storage identifier.
  4. Find the object in the verificationMethod array whose id property matches either the full keyid URL or the fragment component of the keyid URL.
  5. Verify the HTTP Message Signature using the located verification method.

Subscription Management

The value of the serviceEndpoint property for a NotificationService that supports WebhookSubscription MUST be a URL that supports GET operations to list a subscriber's active webhook subscriptions. The resulting serialization MUST conform to the requirements for LWS Containers [[!LWS10-CORE]]. The response SHOULD support LWS Paging.

Each subscription resource listed in this container MUST support GET and DELETE operations. A GET request returns the current state of the subscription. A DELETE request cancels the subscription.

Notification Delivery

The server sends an HTTP POST request to the registered inbox with the notification envelope as the request body. The request body MUST conform to the application/lws+json media type.

Subscription Type Identifier

A Webhook subscription MUST use the WebhookSubscription string as its subscription type when interacting with the NotificationService.

Security Considerations

Privacy Considerations