-
Notifications
You must be signed in to change notification settings - Fork 0
Concepts
If you've never used a webhook before, this is where to start. Five minutes, no surprises.
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.
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
LocalSystemby 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
.pfxor a cert thumbprint from the local cert store - Auto-snapshots of your config on every save, with point-in-time restore from the GUI
+------------------+ 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
SYSTEMandAdministrators. 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 theLocalMachinescope, so the same machine can decrypt them under any account but they don't travel to other machines.
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. deploy → http://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. |
-
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.