# WebhookSigner

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.webhooksigner/
> Summary: WebhookSigner: Produces and verifies the HMAC-SHA256 signature of webhook requests.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Core.dll</code></div>

Produces and verifies the HMAC-SHA256 signature of webhook requests.

```csharp
public static class WebhookSigner
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.webhooksigner/">WebhookSigner</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone">object.MemberwiseClone()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

The signature is computed from the string: `{timestamp}.{body}`. The
timestamp is **included** in the signature; otherwise a
captured request could be replayed forever.

When verifying the signature, the recipient must also check that the
timestamp is within its own tolerance. Tracon cannot enforce this; it
is documented in the README.

## Fields

### <a id="Tracon_WebhookSigner_DeliveryHeader"></a> DeliveryHeader

The header that carries the delivery identity. Used to distinguish duplicate deliveries.

```csharp
public const string DeliveryHeader = "X-Tracon-Delivery"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WebhookSigner_EventHeader"></a> EventHeader

The header that carries the event name.

```csharp
public const string EventHeader = "X-Tracon-Event"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WebhookSigner_SignatureHeader"></a> SignatureHeader

The header that carries the signature.

```csharp
public const string SignatureHeader = "X-Tracon-Signature"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WebhookSigner_TimestampHeader"></a> TimestampHeader

The header that carries the timestamp, in Unix seconds.

```csharp
public const string TimestampHeader = "X-Tracon-Timestamp"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Methods

### <a id="Tracon_WebhookSigner_IsReservedHeader_System_String_"></a> IsReservedHeader\(string?\)

Reports whether a header name is one Tracon sets itself.

```csharp
public static bool IsReservedHeader(string? name)
```

#### Parameters

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)?

The header name to check.

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) if the name is reserved.

#### Remarks

A subscription's extra headers are administrator input. Letting one of
them carry a reserved name would append a second value to a header the
recipient verifies, which the recipient cannot resolve.

### <a id="Tracon_WebhookSigner_Sign_System_String_System_DateTimeOffset_System_String_"></a> Sign\(string, DateTimeOffset, string\)

Produces a signature for a body and timestamp.

```csharp
public static string Sign(string body, DateTimeOffset timestamp, string secret)
```

#### Parameters

`body` [string](https://learn.microsoft.com/dotnet/api/system.string)

The JSON body to send.

`timestamp` [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)

The request's timestamp.

`secret` [string](https://learn.microsoft.com/dotnet/api/system.string)

The signing secret.

#### Returns

 [string](https://learn.microsoft.com/dotnet/api/system.string)

The signature, in the form `sha256=<hex>`.

#### Exceptions

 [ArgumentException](https://learn.microsoft.com/dotnet/api/system.argumentexception)

`secret` is empty.

### <a id="Tracon_WebhookSigner_Verify_System_String_System_DateTimeOffset_System_String_System_String_"></a> Verify\(string, DateTimeOffset, string, string?\)

Verifies a signature.

```csharp
public static bool Verify(string body, DateTimeOffset timestamp, string secret, string? signature)
```

#### Parameters

`body` [string](https://learn.microsoft.com/dotnet/api/system.string)

The received body.

`timestamp` [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)

The timestamp in the request.

`secret` [string](https://learn.microsoft.com/dotnet/api/system.string)

The signing secret.

`signature` [string](https://learn.microsoft.com/dotnet/api/system.string)?

The signature in the request.

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) if the signature is valid.

#### Remarks

The comparison is constant-time, using
`CryptographicOperations.FixedTimeEquals`:
an ordinary string comparison would let the signature be guessed byte
by byte from the time taken until the first differing byte.
