Receiving GitHub Webhooks When Using the ASP.NET Core Developer Certificate
In this detailed post, Steve Gordon shares practical steps for developing and testing GitHub webhooks locally within an ASP.NET Core app, detailing webhook setup, certificate management, and smee.io usage.
Receiving GitHub Webhooks When Using the ASP.NET Core Developer Certificate
Authored by Steve Gordon
Overview
This article is part of the series “A Guide to Developing GitHub Apps on .NET.” Steve Gordon details his experience and methods while experimenting with building a GitHub App using .NET. The focus of this post is on enabling the receipt and local testing of GitHub webhooks in an ASP.NET Core application, specifically how to navigate HTTPS challenges using the self-signed ASP.NET Core developer certificate.
Introduction
For several weeks, I have been working on creating a GitHub App with .NET to realize an integration idea and keep my skills sharp. This real-world scenario utilizes ASP.NET Core features and allows me to “dogfood” my work on OpenTelemetry and .NET app instrumentation at Elastic, discover documentation gaps, and develop helpful guidance.
A primary early goal is supporting GitHub webhook receipt in my ASP.NET Core app. In the next post(s) in this series, I will cover the code for handling webhook requests efficiently and securely via middleware. This post lays essential groundwork, focusing on how to enable local testing of webhook delivery over HTTPS when developing with the ASP.NET Core developer certificate.
GitHub Webhooks Basics
GitHub webhooks notify integrations by sending predetermined payloads to your app’s endpoint whenever specific events occur on GitHub. A GitHub App can subscribe to a wide variety of events. For a full list, see GitHub’s documentation.
Testing webhook delivery in a local, unexposed development environment is challenging. While you can test with fake (mock) payloads, true integration testing requires allowing GitHub to send real requests to your locally running app.
GitHub’s documentation on testing webhooks is recommended for deeper insights. While most steps are detailed there, this post highlights one hurdle: ASP.NET Core’s use of a self-signed HTTPS certificate in development, which can block testing if not addressed.
Note: This guide is written for the Windows OS, though similar steps can be replicated on other operating systems.
Prerequisites
GitHub App Registration
- Register your GitHub App in your account settings.
- Enter your unique smee.io URL as the webhook endpoint.
- Smee.io will forward payloads from GitHub to your localhost application.
Note: For simplicity, the webhook secret is not configured here but should never be omitted in real applications—future posts will cover webhook payload validation.
ASP.NET Core HTTPS Developer Certificate
- By default, the .NET SDK sets up a developer certificate for HTTPS.
- If not, use
dotnet dev-certs
to generate one.
Smee.io URL & smee-client
- Create a new channel on smee.io, generating a unique URL.
- Install the smee client (requires Node.js and NPM).
- The smee client tunnels webhook traffic from GitHub (via smee.io) to your localhost endpoint.
ASP.NET Core Application Scaffold
Start your app and prepare a basic middleware to receive POST requests at your webhook endpoint:
namespace GitHubAppSample;
public class GitHubWebHookMiddleware(RequestDelegate next)
{
private readonly RequestDelegate _next = next;
private const string WebHookPath = "/github/webhook";
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.StartsWithSegments(WebHookPath, StringComparison.Ordinal) &&
context.Request.Method == "POST")
{
// TODO: Handle webhook
}
await _next(context);
}
}
Register the middleware in your pipeline:
app.UseMiddleware<GitHubWebHookMiddleware>();
The HTTPS Challenge
Launch your app and inspect the HTTPS port (from launchSettings.json or console logs). For this example, it’s https://localhost:7192
.
Run the smee client to forward payloads:
smee --url https://smee.io/YOUR_CHANNEL --target https://localhost:7192/github/webhook
At webhook creation, GitHub sends a ping
event. You can view and redeliver events in your smee.io channel.
If your breakpoint isn’t hit and the Smee client logs a Node.js self-signed certificate error (DEPTH_ZERO_SELF_SIGNED_CERT
), it’s because the Node runtime cannot verify your ASP.NET Core developer certificate.
Trusting the ASP.NET Core Developer Certificate for Node.js
- Export the Developer Certificate:
- Open Certificate Manager (
certmgr.msc
). - Find the certificate issued to
localhost
under Personal → Certificates. - Right-click → All Tasks → Export, and follow the wizard. Export as Base-64 encoded X.509 (.CER), without the private key.
- Open Certificate Manager (
- Configure Node.js to Trust the Certificate:
- Temporarily set the environment variable for your terminal session:
$Env:NODE_EXTRA_CA_CERTS = "c:\certs\aspnetcore.cer"
-
Restart the smee client:
smee --url https://smee.io/YOUR_CHANNEL --target https://localhost:7192/github/webhook
- Redeliver the Webhook
- In your smee.io UI, redeliver the ping event. Now, your breakpoint should be triggered, and the Smee client should show successful forwarding. No certificate errors will appear.
Example successful log:
Forwarding https://smee.io/CHANNEL to https://localhost:7192/github/webhook
Connected https://smee.io/CHANNEL
POST https://localhost:7192/github/webhook - 200
Summary
You can deliver GitHub webhook events to your ASP.NET Core app locally via HTTPS using smee.io as a tunnel. The critical step is to export and trust the development certificate for Node.js using the NODE_EXTRA_CA_CERTS
environment variable. This setup enables robust local integration testing before deploying your GitHub App.
Future posts will demonstrate securing and validating webhook endpoints in depth.
Resources
- Testing webhooks from GitHub
- ASP.NET Core developer certificates
- Authenticating a .NET GitHub App using a JSON Web Token (JWT)
- smee.io and smee-client
About the Author
Steve Gordon is a Pluralsight author, 7x Microsoft MVP, and .NET engineer at Elastic (maintaining the .NET APM agent and libraries). He is an active community member, writer, speaker, and OSS contributor, based in Brighton and founder of .NET South East Meetup. Follow Steve on Twitter (X) and via his blog.
This post appeared first on “Steve Gordon’s Blog”. Read the entire article here