<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-knauer-secure-webhook-token-01" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="SWT">Secure Webhook Token (SWT)</title><seriesInfo value="draft-knauer-secure-webhook-token-01" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="S." surname="Knauer" fullname="Stephan Knauer"><organization></organization><address><postal><street></street>
<city>Leipzig, SN</city>
<country>Germany</country>
</postal><email>mail@knauer.consulting</email>
</address></author><date year="2025" month="November" day="11"></date>
<area>Security</area>
<workgroup>Network Working Group</workgroup>

<abstract>
<t>The Secure Webhook Token (SWT) is a specialized JSON Web Token (JWT) format designed for securely authorizing and verifying webhook requests.
It defines a set of claims to ensure that the token is explicitly tied to webhook events and that its integrity can be reliably validated by the recipient.
A key feature of SWT is the introduction of a unique claim, <tt>webhook</tt>, which encapsulates webhook-specific information, such as the event type.</t>
<t>By providing a structured and secure approach to webhook authentication, SWT aims
to be a lightweight and flexible solution while maintaining compatibility with typical JWT structures.
It is designed with the best practices in mind and may serve as a foundation for future standardization efforts.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>The increasing use of webhooks requires a secure,
standardized approach to authorizing webhook requests and verifying the sender's authenticity.
The SWT specifies a JWT-based <xref target="RFC7519"></xref> structure, which includes unique claims tailored for webhook events.
This specification mandates that all tokens must be transmitted using HTTP POST requests (see <xref target="RFC9110" sectionFormat="of" section="9.3.3"></xref>),
with the token in the <tt>Authorization</tt> header and event data in the request body, ensuring secure transmission and optimal compatibility with typical HTTP implementations.</t>

<section anchor="notational-conventions"><name>Notational Conventions</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,
&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and
&quot;OPTIONAL&quot; in this document are to be interpreted as described in
&quot;Key words for use in RFCs to Indicate Requirement Levels&quot; <xref target="RFC2119"></xref>.
The interpretation should only be applied when the terms appear in
all capital letters.</t>
</section>
</section>

<section anchor="secure-webhook-token-swt-overview"><name>Secure Webhook Token (SWT) Overview</name>
<t>This specification defines required claims within the JWT <xref target="RFC7519"></xref> payload and prescribes the transport protocol as HTTP POST.
The token is transmitted in the <tt>Authorization</tt> header while the webhook event data is sent in the request body.
These constraints ensure interoperability across diverse systems and provide a consistent approach to webhook authorization.</t>
</section>

<section anchor="transport-requirements"><name>Transport Requirements</name>
<t>SWTs MUST be transmitted using HTTP POST requests only.</t>
<t>The token MUST be included in the <tt>Authorization</tt> header using the Bearer scheme, while the webhook event data MUST be sent in the request body.</t>
</section>

<section anchor="token-size-limitation"><name>Token Size Limitation</name>
<t><strong>Recommended Maximum Token Size</strong>: While there is no strict maximum size for an SWT, the token SHOULD be kept concise, containing only essential claims to support efficient processing and minimize resource usage. The primary use case for SWTs is to securely authorize and trigger events rather than transmit extensive data.</t>
<t><strong>Header Size Considerations</strong>: Since the token is transmitted in the <tt>Authorization</tt> header, implementers should be aware of HTTP header size limits imposed by web servers and proxies. Most web servers have a default maximum HTTP header size of 8KB, though this can often be configured. To ensure broad compatibility, the JWT token itself SHOULD remain reasonably small (typically under 4KB).</t>
</section>

<section anchor="jwt-structure"><name>JWT Structure</name>
<t>An SWT comprises the following:</t>

<section anchor="header"><name>Header</name>

<ul spacing="compact">
<li><strong>alg</strong>: Specifies the signing algorithm <xref target="RFC7518"></xref>, typically <tt>&quot;HS256&quot;</tt> (HMAC SHA-256).</li>
<li><strong>typ</strong>: Specifies the token type, which MUST be <tt>&quot;SWT&quot;</tt>. This distinguishes Secure Webhook Tokens from generic JWTs and enables recipients to recognize and process them according to this specification.</li>
</ul>

<section anchor="example-header-structure"><name>Example Header Structure</name>

<sourcecode type="json"><![CDATA[{
  "alg": "HS256",
  "typ": "SWT"
}
]]></sourcecode>
</section>
</section>

<section anchor="payload"><name>Payload</name>
<t>The payload contains the following required claims, carefully chosen to meet security and identification needs:</t>

<ul>
<li><t><strong>webhook</strong>: Custom claim specific to this specification.</t>

<ul spacing="compact">
<li><strong>event</strong>: Describes the webhook event type (e.g., <tt>&quot;payment.received&quot;</tt>).
Values should be concise to meet the size limitations.</li>
<li><strong>hash</strong> (OPTIONAL): The cryptographic hash of the request body (see <eref target="#request-body-integrity">Request Body Integrity</eref>).
This field MUST be present when the request body is non-empty and MUST be omitted when the request body is empty.</li>
<li><strong>retry_count</strong> (OPTIONAL): A non-negative integer indicating the delivery attempt number (0 = initial attempt, 1+ = retry).
See <eref target="#webhook-claim-specification">JWT webhook claim</eref> for detailed specification.</li>
</ul></li>
<li><t><strong>iss</strong> (Issuer): Identifies the token issuer (e.g., a unique name or domain representing the entity).
Short, meaningful identifiers are RECOMMENDED.</t>
</li>
<li><t><strong>sub</strong> (Subject) (OPTIONAL): While traditionally used to identify the principal subject of a JWT, the <tt>sub</tt> claim is not required in SWT.
The purpose and intent of the token are unambiguously defined by the <tt>webhook</tt> claim.
However, implementers may include <tt>sub</tt> to identify the system, service, or entity responsible for issuing the token, if such context is useful.</t>
</li>
<li><t><strong>exp</strong> (Expiration): Specifies the token's expiration time as a Unix timestamp. This prevents tokens from being valid
indefinitely.</t>
</li>
<li><t><strong>nbf</strong> (Not Before): Specifies the earliest time the token is considered valid, using a Unix timestamp.</t>
</li>
<li><t><strong>iat</strong> (Issued At): The timestamp when the token was issued, aiding in token age validation.</t>
</li>
<li><t><strong>jti</strong> (JWT ID): A unique identifier for each token to prevent replay attacks. A UUID <xref target="RFC9562"></xref> or similarly unique identifier
is RECOMMENDED.</t>
</li>
</ul>

<section anchor="example-payload-structure"><name>Example Payload Structure</name>

<section anchor="swt-payload-with-empty-body-notification-only"><name>SWT payload with empty body (notification only):</name>

<sourcecode type="json"><![CDATA[{
  "webhook": {
    "event": "ping"
  },
  "exp": 1733987961,
  "nbf": 1733987661,
  "iat": 1733987661,
  "iss": "swt.example.com",
  "jti": "2020B14D-C365-4BCF-84CD-5D423E0C6687"
}
]]></sourcecode>
</section>

<section anchor="swt-payload-with-body-content"><name>SWT payload with body content:</name>

<sourcecode type="json"><![CDATA[{
  "webhook": {
    "event": "delivery.scheduled",
    "hash": "sha-256:22b793b7c031e6a3...05ba920b",
    "retry_count": 0
  },
  "exp": 1733987961,
  "nbf": 1733987661,
  "iat": 1733987661,
  "iss": "swt.example.com",
  "jti": "2020B14D-C365-4BCF-84CD-5D423E0C6687"
}
]]></sourcecode>
</section>

<section anchor="swt-payload-for-retry-attempt"><name>SWT payload for retry attempt:</name>

<sourcecode type="json"><![CDATA[{
  "webhook": {
    "event": "delivery.scheduled",
    "hash": "sha-256:22b793b7c031e6a3...05ba920b",
    "retry_count": 3
  },
  "exp": 1733988561,
  "nbf": 1733988261,
  "iat": 1733988261,
  "iss": "swt.example.com",
  "jti": "A1C3F89E-2F4D-4A8C-9B2E-7D8F1C3E5A9B"
}
]]></sourcecode>
</section>
</section>
</section>
</section>

<section anchor="request-body-integrity"><name>Request Body Integrity</name>

<section anchor="overview"><name>Overview</name>
<t>To ensure payload integrity when sending body content, webhook requests with non-empty request bodies MUST include a cryptographic hash of the request body. Instead of using separate fields for algorithm and value, a self-describing hash field is used:</t>

<sourcecode type="json"><![CDATA["webhook": {
  "event": "delivery.scheduled",
  "hash": "sha-512:f8f24b01df358f10...df03db5cf"
}
]]></sourcecode>
<t>This format allows the server to interpret the algorithm dynamically and accept or reject hashes according to its policies.</t>
</section>

<section anchor="format"><name>Format</name>
<t><tt>hash = &quot;&lt;algorithm&gt;:&lt;hash_value&gt;&quot;</tt></t>

<ul spacing="compact">
<li><tt>&lt;algorithm&gt;</tt>: The cryptographic hash algorithm, using standardized names such as sha-256, sha-512, sha3-256.</li>
<li><tt>&lt;hash_value&gt;</tt>: The lowercase hexadecimal representation of the hash of the request body. Hexadecimal encoding is REQUIRED for interoperability.</li>
</ul>

<section anchor="examples"><name>Examples</name>

<sourcecode type="json"><![CDATA[  "hash": "sha-256:04ef96c3bc56b3c4...200a5353"
  "hash": "sha-512:f8f24b01df358f10...df03db5cf"
]]></sourcecode>
</section>
</section>

<section anchor="server-side-processing"><name>Server-side Processing</name>

<ol spacing="compact">
<li>Parse the hash string to separate algorithm and value.</li>
</ol>

<sourcecode type="pseudo"><![CDATA[[algo, value] = hash.split(":")
]]></sourcecode>

<ol spacing="compact" start="2">
<li>Validate the algorithm against the server’s allowed list.</li>
<li>Compute the hash of the received payload using algo.</li>
<li><t>Compare computed hash with value.</t>

<ul spacing="compact">
<li>If they match → payload integrity verified.</li>
<li>If they do not match → reject the webhook request.</li>
</ul></li>
</ol>

<section anchor="recommendations"><name>Recommendations</name>

<ul spacing="compact">
<li>Algorithm Registry: Use standardized algorithm names aligned with the IANA Named Information Hash Algorithm Registry <xref target="RFC6920"></xref> to avoid ambiguities.</li>
<li>Extensibility: New hash algorithms may be introduced without changing the JSON schema.</li>
<li>Security Note: Do not accept weak or deprecated hash algorithms (e.g., MD5, SHA-1).</li>
</ul>
</section>
</section>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>

<ol>
<li><t><strong>Signature Verification</strong>: Receivers MUST verify the JWT signature before processing any claims. Failure to verify
signatures exposes the system to token forgery attacks. The signature algorithm specified in the JWT header MUST be
validated against an allowlist of permitted algorithms to prevent algorithm substitution attacks.</t>
</li>
<li><t><strong>Algorithm Allowlist</strong>: Implementations MUST maintain an allowlist of acceptable signing algorithms and MUST reject
tokens signed with algorithms not on this list. The <tt>alg</tt> header parameter MUST be checked against this allowlist
before signature verification. Implementations MUST NOT accept the &quot;none&quot; algorithm.</t>
</li>
<li><t><strong>HTTPS Transport</strong>: It is REQUIRED that SWT transmissions occur over HTTPS to ensure the token's
confidentiality and protect against man-in-the-middle attacks.</t>
</li>
<li><t><strong>Replay Protection</strong>: The <tt>jti</tt> claim MUST be checked for uniqueness on the server side to prevent replay attacks.
Each <tt>jti</tt> value MUST only be accepted once within the token's validity period. Implementations SHOULD maintain
a cache or registry of seen <tt>jti</tt> values.</t>
</li>
<li><t><strong>Expiration and Time-based Claims</strong>: Systems MUST validate the <tt>exp</tt>, <tt>nbf</tt>, and <tt>iat</tt> claims to ensure tokens
are used only within their intended validity period. Implementations SHOULD allow for a small clock skew tolerance
(e.g., 60 seconds) when validating time-based claims to account for clock differences between systems.
Token lifetime (<tt>exp - iat</tt>) SHOULD be kept as short as practical for the use case, typically not exceeding
15 minutes for most webhook scenarios.</t>
</li>
<li><t><strong>Key Management</strong>: Symmetric keys used for HMAC algorithms MUST be generated using a cryptographically secure
random number generator and MUST have sufficient entropy (at least 256 bits for HS256). Keys SHOULD be rotated
regularly. For asymmetric algorithms, private keys MUST be protected with appropriate access controls and SHOULD
be stored in hardware security modules (HSMs) or key management systems (KMS) when available.</t>
</li>
<li><t><strong>Hash Algorithm Security</strong>: When validating request body hashes, implementations MUST reject weak or deprecated
hash algorithms (e.g., MD5, SHA-1). Only cryptographically strong hash algorithms (SHA-256 or stronger) SHOULD
be accepted.</t>
</li>
<li><t><strong>Respect Header Limits</strong>: Excessively large JWT tokens SHOULD be avoided to ensure compatibility with HTTP header
size limits imposed by web servers and proxies.</t>
</li>
<li><t><strong>Retry Count Validation</strong>: When the <tt>retry_count</tt> field is present, receivers SHOULD validate that its value is
reasonable to prevent abuse. Implementations MAY enforce maximum retry limits (e.g., rejecting requests with
<tt>retry_count</tt> exceeding a configured threshold) to protect against resource exhaustion attacks. The <tt>retry_count</tt>
value MUST be a non-negative integer. Receivers SHOULD consider implementing exponential backoff expectations and
MAY reject retry attempts that arrive too quickly relative to the <tt>retry_count</tt> value. Additionally, the combination
of <tt>jti</tt> and <tt>retry_count</tt> should be considered together: each retry attempt MUST use a unique <tt>jti</tt> value, as
retries represent distinct delivery attempts even when delivering the same event.</t>
</li>
</ol>
</section>

<section anchor="interoperability-considerations"><name>Interoperability Considerations</name>
<t>SWT's use of standard HTTP POST requests with JWT-based authorization ensures broad compatibility with existing web infrastructure.
The structure is simple to parse and easy to integrate with existing JWT validation libraries.
The separation of token metadata and event data provides flexibility for various payload sizes and content types.</t>
</section>

<section anchor="signing-and-encryption-recommendations"><name>Signing and Encryption Recommendations</name>
<t>To maintain a balance between security and usability,
SWTs are RECOMMENDED to be used as JSON Web Signatures (JWS) <xref target="RFC7515"></xref>, specifically signed JWTs.
This provides data integrity and allows the recipient to verify the token's authenticity.
The following signing algorithms are suggested for SWTs, as they offer a secure yet practical approach:</t>

<ul spacing="compact">
<li>HS256, HS384, and HS512: Symmetric algorithms using HMAC with SHA-256, SHA-384, and SHA-512, respectively. These
algorithms are considered secure and performant for most applications, especially when using shared symmetric keys
between the issuer and the receiver.</li>
</ul>
<t>While these symmetric algorithms are RECOMMENDED for ease of use and efficiency, other supported algorithms, including
asymmetric methods such as RS256 (RSA with SHA-256) or ES256 (ECDSA with SHA-256), MAY also be used if needed based on
security requirements or system constraints.</t>

<section anchor="encrypted-jwt-support-jwe"><name>Encrypted JWT Support (JWE)</name>
<t>In addition to JWS, SWT allows the use of the JSON Web Encryption (JWE) <xref target="RFC7516"></xref> standard if encrypted JWTs are
required to protect sensitive data within the token. JWE adds encryption layers to JWTs, providing confidentiality as
well as integrity protection, which may be appropriate in contexts where tokens contain sensitive information.</t>
</section>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="media-type-registration"><name>Media Type Registration</name>
<t>This specification registers the <tt>application/swt+jwt</tt> media type in the IANA &quot;Media Types&quot; registry in the manner described in <xref target="RFC6838"></xref>.</t>
<t>The following entries should be registered:</t>

<ul spacing="compact">
<li>Type name: application</li>
<li>Subtype name: swt+jwt</li>
<li>Required parameters: n/a</li>
<li>Optional parameters: n/a</li>
<li>Encoding considerations: 8-bit; application/swt+jwt values are encoded as a series of base64url-encoded values (some of which may be the empty string) separated by period ('.') characters</li>
<li>Security considerations: See Security Considerations section of this document</li>
<li>Interoperability considerations: n/a</li>
<li>Published specification: This document</li>
<li>Applications that use this media type: Webhook delivery systems, event notification platforms, and applications requiring secure webhook authentication</li>
<li>Fragment identifier considerations: n/a</li>
<li><t>Additional information:</t>

<ul spacing="compact">
<li>Magic number(s): n/a</li>
<li>File extension(s): n/a</li>
<li>Macintosh file type code(s): n/a</li>
</ul></li>
<li>Person &amp; email address to contact for further information: Stephan Knauer, mail@knauer.consulting</li>
<li>Intended usage: COMMON</li>
<li>Restrictions on usage: none</li>
<li>Author: Stephan Knauer, mail@knauer.consulting</li>
<li>Change controller: IESG</li>
<li>Provisional registration? No</li>
</ul>
</section>

<section anchor="json-web-token-claims-registration"><name>JSON Web Token Claims Registration</name>
<t>This document updates the IANA &quot;JSON Web Token Claims&quot; registry
for JWT Claim Names.
Following the format in <xref target="RFC7519" sectionFormat="of" section="10.1.1"></xref>, the following
should be registered.</t>

<ul spacing="compact">
<li>Claim Name: &quot;webhook&quot;</li>
<li>Claim Description: Webhook</li>
<li>Change Controller: IESG</li>
<li>Specification Document(s): <xref target="webhook-claim-specification"></xref> of this document</li>
</ul>
</section>

<section anchor="webhook-claim-specification"><name>JWT <tt>webhook</tt> claim</name>
<t>The <tt>webhook</tt> claim is a JSON object that describes the event to be triggered and optionally includes metadata about the event data sent in the request body.</t>
<t>It consists of the following fields:</t>

<ul spacing="compact">
<li><tt>event</tt>: A case-sensitive string describing the name of the webhook event. It should be concise and specific (e.g., <tt>&quot;order.created&quot;</tt>).</li>
<li><t><tt>hash</tt> (OPTIONAL): The hash algorithm and the hash digest of the request body payload (hex-encoded) (see <xref target="request-body-integrity"></xref>).</t>

<ul spacing="compact">
<li>This field MUST be present when the request body is non-empty (Content-Length &gt; 0).</li>
<li>This field SHOULD be omitted when the request body is empty (Content-Length = 0).</li>
</ul></li>
<li><t><tt>retry_count</tt> (OPTIONAL): A non-negative integer indicating the delivery attempt number for this webhook event.</t>

<ul spacing="compact">
<li>A value of <tt>0</tt> indicates the initial delivery attempt (no retry).</li>
<li>A value of <tt>1</tt> or greater indicates a retry attempt (e.g., <tt>1</tt> = first retry, <tt>2</tt> = second retry).</li>
<li>This field SHOULD be included when the webhook system implements retry logic for failed deliveries.</li>
<li>Receivers MAY use this value to implement progressive backoff strategies, rate limiting, or to decide whether to accept further retries.</li>
</ul></li>
</ul>
<t>Implementers MAY restrict the set of supported algorithms based on their security posture.</t>
<blockquote><t>Senders and receivers SHOULD agree on supported algorithms in advance.</t>
<t>Although NOT RECOMMENDED, it may be necessary to send non-JSON event data via SWT.
The HTTP <em>Content-Type</em> header SHOULD be set accordingly.</t>
</blockquote>
<section anchor="examples-of-jwt-webhook-claim"><name>Examples of JWT <tt>webhook</tt> claim</name>
<t>Initial delivery attempt:</t>

<sourcecode type="json"><![CDATA["webhook": {
  "event": "issue.opened",
  "hash": "sha-256:04ef96c3bc56b3c4...200a5353",
  "retry_count": 0
}
]]></sourcecode>
<t>Retry attempt:</t>

<sourcecode type="json"><![CDATA["webhook": {
  "event": "issue.opened",
  "hash": "sha-256:04ef96c3bc56b3c4...200a5353",
  "retry_count": 2
}
]]></sourcecode>
</section>
</section>
</section>

<section anchor="validation"><name>Validation</name>
<t>To validate an SWT, the receiving system MUST perform the following checks:</t>

<ol spacing="compact">
<li><strong>JWT Validation</strong>: The token in the <tt>Authorization</tt> header MUST be a valid JWT with all required claims.</li>
<li><strong>Webhook Claim Validation</strong>: The JWT MUST contain a <tt>webhook</tt> claim with an <tt>event</tt> field.</li>
<li><t><strong>Body and Hash Validation</strong>:</t>

<ul spacing="compact">
<li><t><strong>If the request body is non-empty</strong> (Content-Length &gt; 0):</t>

<ul spacing="compact">
<li>The <tt>webhook</tt> claim MUST contain a <tt>hash</tt> field.</li>
<li>The computed hash of the request body MUST match the <tt>hash</tt> value specified in the <tt>webhook</tt> claim using the specified algorithm.</li>
</ul></li>
<li><t><strong>If the request body is empty</strong> (Content-Length = 0):</t>

<ul spacing="compact">
<li>The <tt>webhook</tt> claim MUST NOT contain a <tt>hash</tt> field.</li>
</ul></li>
</ul></li>
</ol>
<t>If any validation check fails, the server SHOULD respond with an appropriate HTTP error code:</t>

<ul spacing="compact">
<li><strong>401 Unauthorized</strong>: If JWT signature verification fails, the token is expired, or authentication credentials are invalid.</li>
<li><strong>403 Forbidden</strong>: If the token is valid but the issuer lacks permission to trigger the webhook or access the resource.</li>
<li><strong>400 Bad Request</strong>: If the request is malformed (e.g., missing required claims, invalid hash format, or hash mismatch).</li>
</ul>

<section anchor="examples-1"><name>Examples</name>

<section anchor="example-1-empty-body-notification-only"><name>Example 1: Empty body (notification only)</name>
<t><strong>Webhook claim:</strong></t>

<sourcecode type="json"><![CDATA[{
  "webhook": {
    "event": "ping"
  },
  "exp": 1733987961,
  "nbf": 1733987661,
  "iat": 1733987661,
  "iss": "swt.example.com",
  "jti": "2020B14D-C365-4BCF-84CD-5D423E0C6687"
}
]]></sourcecode>
<t><strong>POST request:</strong></t>

<sourcecode type="txt"><![CDATA[POST /webhook HTTP/1.1
Content-Length: 0
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Host: example.com
]]></sourcecode>
</section>

<section anchor="example-2-non-empty-body-with-hash"><name>Example 2: Non-empty body with hash</name>
<t><strong>Webhook claim:</strong></t>

<sourcecode type="json"><![CDATA[{
  "webhook": {
    "event": "issue.opened",
    "hash": "sha-256:04ef96c3bc56b3c4...200a5353",
    "retry_count": 0
  },
  "exp": 1733987961,
  "nbf": 1733987661,
  "iat": 1733987661,
  "iss": "swt.example.com",
  "jti": "2020B14D-C365-4BCF-84CD-5D423E0C6687"
}
]]></sourcecode>
<t><strong>POST request:</strong></t>

<sourcecode type="txt"><![CDATA[POST /webhook HTTP/1.1
Content-Length: 6123
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Host: example.com

{
   "action": "opened",
   "issue": {
     "url": "https://api.github.com/repos/octocat/...",
     "number": 1347,
     ...
   },
   "repository" : {
     "id": 1296269,
     "full_name": "octocat/Hello-World",
     "owner": {
       "login": "octocat",
       "id": 1,
       ...
     },
     ...
   },
   "sender": {
     "login": "octocat",
     "id": 1,
     ...
   }
 }
]]></sourcecode>
</section>
</section>
</section>

<section anchor="conclusion"><name>Conclusion</name>
<t>The Secure Webhook Token (SWT) format provides a secure,
interoperable, and efficient solution for webhook authentication.
Its focus on signed payloads, minimal overhead,
and clear transport guidance makes it suitable for modern web service ecosystems.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6838.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6920.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7515.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7516.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7518.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml"/>
</references>
<references><name>Informative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9562.xml"/>
</references>
</references>

</back>

</rfc>
