Stabilizing Webhook Development with ngrok Reserved Domains and Edge Auth
Stop updating webhook URLs every time you restart your server. Learn how to use ngrok reserved domains and edge authentication to create a stable, secure local development environment.
08 Jul 2026, 08:51 UTC

The Webhook Restart Problem
Developing webhook receivers is often a cycle of trial and error. You configure a third-party service (like Stripe, GitHub, or Shopify) to send events to a public URL, only to find that every time you restart your local ngrok tunnel, the public URL changes. This forces you to manually update the webhook settings in the external provider's dashboard every few hours, breaking your development flow.
The solution is to move from ephemeral tunnels to a stable endpoint using a reserved domain and securing that endpoint at the edge to prevent unauthorized traffic from hitting your local machine.
Pinning Your Endpoint with Reserved Domains
By default, ngrok generates a random subdomain for every session. To stop this, you can use a reserved domain. A reserved domain is a static address assigned to your account that remains constant regardless of how many times you restart the ngrok agent or move between different local machines.
When you use a reserved domain, the external service's webhook configuration remains valid indefinitely. This allows you to treat your local environment more like a staging server, ensuring that the integration remains intact across reboots and network changes.
Securing the Tunnel at the Edge
Exposing a local port to the public internet creates a security gap. While you could implement authentication inside your application code, ngrok allows you to enforce HTTP Basic Auth at the tunnel edge. This means ngrok's servers challenge the request for credentials before the traffic ever reaches your local network.
This is particularly useful for webhooks because it prevents random scanners or bots from triggering your local logic, while still allowing the authorized webhook provider (or your own manual tests) to pass through.
Worked Example: Stable, Secured Webhook Receiver
Assume you have a local service running on port 8080 and a reserved domain webhook-dev.ngrok-free.app. Instead of using a simple command-line flag, the most reliable way to manage these settings is via the ngrok.yml configuration file.
Configuration Setup
Edit your ngrok configuration file (typically found in ~/.config/ngrok/ngrok.yml on Linux/macOS or %USERPROFILE%/.ngrok2/ngrok.yml on Windows):
tunnels:
webhook-receiver:
proto: http
addr: 8080
domain: webhook-dev.ngrok-free.app
auth: "user:password123"
Running the Tunnel
Run the tunnel using the configuration name. You must run this as a user with permissions to access the config file and network access to port 8080:
ngrok start webhook-receiver
Verifying the Setup
- Check Stability: Restart the tunnel. The public URL should remain
https://webhook-dev.ngrok-free.app. - Test Security: Attempt to visit the URL in a browser without credentials. You should receive an
HTTP 401 Unauthorizedresponse. - Inspect Traffic: Open
http://127.0.0.1:4040in your local browser. This is the ngrok local inspector. When the webhook provider sends a request, you can view the exact headers and JSON payload here without needing to add verbose logging to your application.
Trade-offs and Limitations
While reserved domains and edge auth simplify development, there are critical limitations to consider:
- Tier Restrictions: Reserved custom domains are generally a paid feature. Free tier users are limited to ephemeral URLs unless they use specific limited-time promotional domains.
- TLS Termination: ngrok terminates the TLS (SSL) connection at its edge. The traffic from the ngrok edge to your local port 8080 is typically unencrypted. Do not use this for transmitting highly sensitive production data over untrusted local networks.
- Header Trust: Because ngrok acts as a proxy, your application will see the request coming from the ngrok agent. To find the original sender's IP, you must inspect the
X-Forwarded-Forheader.
Actionable Summary
To stop updating webhook URLs manually, move your configuration into ngrok.yml and assign a reserved domain. Secure the endpoint using the auth parameter to keep your local environment clean of bot traffic, and use the :4040 inspector to debug payloads in real-time. If you are on a free plan and cannot reserve a domain, consider using a tool like a local DNS proxy or upgrading your tier for stability.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.