Soenneker.Webhooks.Signing
4.0.2
Prefix Reserved
See the version list below for details.
dotnet add package Soenneker.Webhooks.Signing --version 4.0.2
NuGet\Install-Package Soenneker.Webhooks.Signing -Version 4.0.2
<PackageReference Include="Soenneker.Webhooks.Signing" Version="4.0.2" />
<PackageVersion Include="Soenneker.Webhooks.Signing" Version="4.0.2" />
<PackageReference Include="Soenneker.Webhooks.Signing" />
paket add Soenneker.Webhooks.Signing --version 4.0.2
#r "nuget: Soenneker.Webhooks.Signing, 4.0.2"
#:package Soenneker.Webhooks.Signing@4.0.2
#addin nuget:?package=Soenneker.Webhooks.Signing&version=4.0.2
#tool nuget:?package=Soenneker.Webhooks.Signing&version=4.0.2
Soenneker.Webhooks.Signing
A .NET utility for securely signing outgoing webhooks using the Standard Webhooks specification.
Implements the symmetric HMAC-SHA256 signing scheme from the Standard Webhooks specification.
Installation
dotnet add package Soenneker.Webhooks.Signing
Usage
Register the utility with dependency injection:
services.AddWebhooksSigningUtilAsSingleton();
Generate a Standard Webhooks secret once and store it securely:
string secret = signingUtil.GenerateSecret();
// whsec_<base64-encoded 32-byte key>
Pass an object to Create. It is serialized once with JsonUtil.SerializeToUtf8Bytes, and the
returned byte array is the exact payload that was signed:
const string webhookId = "msg_2KWPBgLlAfxdpx2AI54pPJ85f4W";
DateTimeOffset attemptTime = DateTimeOffset.UtcNow;
var webhook = new
{
Type = "contact.created",
Data = new { Id = "abc" }
};
SignedWebhook signed = signingUtil.Create(
webhookId,
attemptTime,
webhook,
secret);
foreach ((string name, string value) in signed.Headers.ToDictionary())
request.Headers.TryAddWithoutValidation(name, value);
request.Content = new ByteArrayContent(signed.Payload);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json")
{
CharSet = "utf-8"
};
The generated headers follow the Standard Webhooks symmetric signature scheme:
webhook-id: msg_2KWPBgLlAfxdpx2AI54pPJ85f4W
webhook-timestamp: 1674087231
webhook-signature: v1,<base64 HMAC-SHA256 signature>
For zero-downtime secret rotation, pass all active secrets to Create. The resulting
webhook-signature header contains the signatures separated by spaces:
SignedWebhook signed = signingUtil.Create(
webhookId,
attemptTime,
webhook,
[currentSecret, previousSecret]);
String and byte overloads are also available when the payload is already serialized. Payload bytes are signed exactly; do not parse and reserialize the body between signing and sending:
string signature = signingUtil.Sign(webhookId, unixTimestamp, payloadBytes, secret);
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Soenneker.Extensions.Arrays.Bytes (>= 4.0.61)
- Soenneker.Extensions.String (>= 4.0.707)
- Soenneker.Utils.Json (>= 4.0.2601)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.