Skip to content

Concepts

Webhook Server Wiki Sync edited this page May 8, 2026 · 2 revisions

Concepts

If you've never used a webhook before, this is where to start. Five minutes, no surprises.

What is a webhook?

A webhook is just an HTTP URL that runs something when it gets called. Some other tool — Zerto, GitHub, your monitoring system, a backup job — does an HTTP POST to that URL when an event happens. Whatever's listening on the URL takes that request and does work in response.

Concretely, a Zerto pre-script might do:

Invoke-WebRequest -Method POST -Uri http://webhooks.contoso.local:8080/hook/start-failover `
    -Body (@{ vmName = $env:ZertoVPGName } | ConvertTo-Json) `
    -ContentType application/json

…and the server at webhooks.contoso.local:8080 would receive that POST and run a PowerShell script you wrote.

What does this server give you that you don't already have?

You could write a tiny ASP.NET listener, or run a PowerShell script behind IIS, or hand-craft HttpListener plumbing. People do, all the time. The trade-off is that you then own the listener — auth, retries, logging, restarts, a service wrapper, secret storage, an admin UI. That's where Webhook Server saves you a weekend.

What you get out of the box:

  • A real Windows Service that survives reboots and runs without anyone logged in
  • Per-endpoint authentication: Bearer token, HMAC-signed (GitHub / Stripe / Slack style), or none
  • Per-endpoint IP allowlist (single IPs or CIDR ranges)
  • Run-as identity: the service runs as LocalSystem by default, but each individual hook can run as a domain account, the logged-in user, or whoever — without needing Task Scheduler in the middle
  • Logging (Serilog, daily-rolling files) plus a GUI tail
  • A WPF GUI for adding / editing / testing endpoints. No JSON file editing required.
  • Outbound callbacks: when a hook finishes, the server can POST the result to another URL, signed with HMAC, with retry-and-backoff
  • HTTPS via .pfx or a cert thumbprint from the local cert store
  • Auto-snapshots of your config on every save, with point-in-time restore from the GUI

How the moving parts fit together

+------------------+   named pipe   +-------------------------------+
|   GUI (WPF)      | <------------> |  Windows Service              |
|  add / edit /    |  SYSTEM+admin  |  - Kestrel: hook listener     |
|  view logs       |  ACL'd         |  - Admin pipe server          |
+------------------+                |  - Executor (process runner)  |
                                    |  - Callback dispatcher        |
                                    |  - Serilog file logging       |
                                    +-------------------------------+
                                              |
                                  C:\ProgramData\WebhookServer\
                                  - config.json   (DPAPI-encrypted secrets)
                                  - backups\      (auto-snapshots)
                                  - logs\         (daily rolling)
  • The Windows Service does the actual work: listens for HTTP requests, runs your scripts, writes logs.
  • The GUI is purely a config + monitoring tool. It talks to the service over a named pipe ACL'd to SYSTEM and Administrators. You can launch and close the GUI as you like; the service keeps running.
  • Config + secrets live in C:\ProgramData\WebhookServer\config.json. Secrets (bearer tokens, HMAC keys, run-as passwords, PFX passwords) are DPAPI-encrypted with the LocalMachine scope, so the same machine can decrypt them under any account but they don't travel to other machines.

What's an "endpoint"?

An endpoint is one URL slug (the part after /hook/) plus a configuration: who's allowed to call it, how it's authenticated, what to run when it fires, and what to do with the result. Add as many as you want.

Field What it controls
Slug The URL path. deployhttp://host:8080/hook/deploy
Auth None / Bearer / HMAC. None means anyone who can reach the URL can fire it.
Allowed clients List of IPs or CIDRs allowed to hit this slug. Empty = anyone reachable.
Executor What to run: Windows PowerShell 5.1, PowerShell Core (7+), cmd / .bat, or a path to any .exe
Run As Who the script runs as. See Run As modes.
Data passing How request data reaches the script — JSON to stdin, headers / query as env vars, {{template}} arg expansion
Response mode Sync (the HTTP caller waits for the script to finish and gets its output) or Async (returns 202 immediately, runs in background)
Callback Optional outbound URL the server POSTs to with the run result. Required for async hooks if the original caller wants the result.

What it isn't

  • Not an HTTP server for serving static files or pages. Just hook URLs and a /healthz.
  • Not a queue. No durable persistence of inbound requests; if the service crashes mid-execution that run is lost (the inbound caller will see the connection drop or a timeout).
  • Not multi-tenant. It's one config, one set of endpoints, one machine. Run multiple instances on different ports / different machines if you need separation.
  • Not an internet-facing public-API server out of the box. Lock down with HTTPS + auth + IP allowlist + a reverse proxy if you're going to expose it publicly. See network & security.

Clone this wiki locally