Documentation: install/upgrade/uninstall guides + recipes incl. Zerto

Adds a docs/ folder under the repo root with full operator documentation
aimed at sysadmins (not webhook developers). The Zerto pre/post script
recipe is the canonical "why does this exist" walkthrough; the GitHub
HMAC, AD password reset, and UI-on-desktop recipes round out common
patterns.

Pages:
- README.md (index)
- concepts.md (5-minute "what is a webhook" explainer)
- installation.md (interactive + silent install)
- upgrading.md (single-click upgrade flow + edge cases)
- uninstalling.md (clean removal + wiping ProgramData)
- runas-modes.md (Service / InteractiveUser / SpecificUser decision flow)
- service-account-and-ad.md (gMSA setup, delegated rights)
- network-and-security.md (bind addresses, allowlists, HTTPS, secret storage)
- troubleshooting.md (symptom -> first check, common errors)
- recipes/zerto-pre-post-scripts.md (canonical use case)
- recipes/github-style-hmac.md (GitHub / Stripe-shaped webhooks)
- recipes/ad-password-reset.md (gMSA-backed self-service reset)
- recipes/ui-on-desktop.md (InteractiveUser pattern)

Top-level README.md restructured to point at docs/ as the source of
truth, dropping the duplicated installation snippets.

Installer ships docs/ alongside the binaries so they're available
offline at C:\Program Files\WebhookServer\docs\. GUI Help menu gains
a "Documentation" item that opens the docs site in a browser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 10:34:47 -04:00
parent 7d94535d5d
commit c49a2a12cb
17 changed files with 1477 additions and 87 deletions
+68
View File
@@ -0,0 +1,68 @@
# Recipe: Pop UI on the user's desktop
The classic "fire a hook from your phone, see a calculator window appear on your PC." Useful for:
- Triggering interactive installers / wizards
- Opening browser tabs to specific dashboards on demand
- Playing a sound / showing a toast notification
- Demos and party tricks
## Why this is non-trivial on Windows
The Webhook Server service runs as `LocalSystem` in **session 0**. Anything launched normally from a Service-mode endpoint also lands in session 0, which has no visible desktop — UI runs but nobody sees it. To put a window on the desktop of whoever is logged in at the keyboard, the service has to:
1. Find the active console session ID (`WTSGetActiveConsoleSessionId`)
2. Get a primary token for the user in that session (`WTSQueryUserToken`)
3. Spawn the new process with `CreateProcessAsUser` against that token, targeting `winsta0\default`
Webhook Server does all of this for you when the endpoint's **Run as** is set to **InteractiveUser**.
## Configure the endpoint
| Section | Setting | Value |
|---|---|---|
| Identity | Slug | `calc` |
| Identity | Description | "Pop calculator on the logged-in user's desktop" |
| Auth | Mode | None / Bearer — your call |
| Allowed clients | | restrict; this is interactive UI |
| Executor | Type | **Executable** |
| Executor | Executable path | `C:\Windows\System32\calc.exe` |
| Run as | Identity | **InteractiveUser** |
| Response | Mode | **Async** *(calc never exits on its own; sync would 30-second-timeout-kill it every time)* |
| Response | Fail on non-zero exit | unticked |
Save. Hit `http://localhost:8080/hook/calc` from anywhere — calc.exe pops up on your desktop.
## Limits
- **Service must run as LocalSystem.** Only SYSTEM has the `SeTcbPrivilege` required for `WTSQueryUserToken`. If you switched the service to a gMSA (e.g. for AD-write hooks), this mode stops working. Run two instances of Webhook Server on different ports if you need both.
- **Someone must be logged in** at the console. If the desktop is at the lock screen with no user signed in, the hook fails with `No active console session - is anyone logged in at the keyboard?`.
- **RDP sessions complicate things.** `WTSGetActiveConsoleSessionId` always returns the *console* session, not RDP sessions. If only RDP users are connected and no one is at the physical keyboard, this mode fails. (A separate API, `WTSQueryUserToken` against an enumerated session ID, can target RDP — that'd be a v0.x feature request.)
- **Multiple users logged in via fast-user-switching** — the hook lands in whichever session is currently active (the foreground desktop), not all of them.
## Variations
### Notification toast instead of a window
Use a PowerShell script that emits a Windows 10/11 toast via `BurntToast` (third-party module) or the built-in WinRT API:
```powershell
# requires: Install-Module BurntToast
New-BurntToastNotification -Text 'Webhook fired',$($input | Out-String)
```
Configure the endpoint as InteractiveUser + WindowsPowerShell + inline command. The toast appears as the logged-in user — same as if they fired it themselves.
### Open a URL in the user's default browser
```powershell
Start-Process ($input | ConvertFrom-Json).url
```
Body: `{ "url": "https://contoso.servicenow.com/incident/123" }`
This opens the URL in whatever the user has set as default. Handy for "page on-call → they reply on their phone with a link → URL opens on their workstation when they sit down."
### Run a setup wizard / installer that needs UI
Some installers refuse to run silently or have steps that require human input. Wrap them as InteractiveUser hooks so the operator can trigger them from a help-desk console without having to RDP in.