Repository navigation
ServiceHub 4.2.0 — dead-letter recovery for Azure, AWS and GCP, with a demo that works
LatestServiceHub shows what is sitting in your dead-letter queues across Azure Service Bus, AWS SQS/SNS and GCP Pub/Sub, tells you why each message failed, and previews a replay before anything is sent back.
4.2.0 headline: the demo now works. Open it, replay a message, approve a held one, switch on an Auto Replay rule, press Emergency stop. All on made-up data, no cloud account, nothing leaves your browser.
4.2.0 builds on 4.1.0 (a from-scratch rewrite with no upgrade path from 4.0.0). Replay on Production namespaces is still blocked on purpose.
Try it in your browser, nothing to install: https://debdevops.github.io/servicehub/ (the same demo, made-up data, no server).
Try it in two minutes
export SERVICEHUB_ENCRYPTION_KEY="$(openssl rand -hex 32)" # keep it: it protects the cloud credentials you store
docker run -d --name servicehub --restart unless-stopped \
-p 127.0.0.1:8080:8080 -v servicehub-data:/data \
-e SECURITY__ENCRYPTIONKEY="$SERVICEHUB_ENCRYPTION_KEY" \
ghcr.io/debdevops/servicehub:4.2.0Open http://localhost:8080 and press Demo in the Home header. The image is public (no sign-in to pull), linux/amd64 and linux/arm64; MIT licensed. The commands need a bash shell and openssl (on Windows, a WSL 2 terminal). Full guide (update, back up, stop, remove, troubleshoot): Run ServiceHub with Docker.
Or run it from source, without Docker
For macOS, Linux, or a WSL 2 terminal on Windows. You need only bash, curl (or wget), tar, git and an internet connection. ./run.sh downloads the .NET 10 SDK and Node.js for you if they are missing (into ~/.servicehub/tools, no sudo, nothing system-wide; both downloads are checksum-verified).
git clone https://github.com/debdevops/servicehub.git
cd servicehub
./run.shThe first start takes a few minutes while it downloads and builds. When you see ✔ ServiceHub is ready, open http://localhost:3000 and press Demo. Press Ctrl-C to stop everything it started. If port 3000 or 5153 is busy it picks the next free one and tells you. This mode is for trying and developing (it uses a throw-away encryption key); data lives in services/api/src/ServiceHub.Api/data/. Already have .NET 10 and Node 22 installed and want nothing downloaded? Use ./run.sh --no-install. Prerequisites and troubleshooting: Local setup guide.
Upgrading from 4.1.0
Back up first (Settings → Backup). 4.2.0 adds one database migration (0015_A_DlqObserverLiveSince, a nullable column), applied when it starts. There is no upgrade from 4.0.0; run it beside 4.0.0 and connect your clouds again.
If you call the API directly: creating, switching, changing, deleting and generating Auto Replay rules now answer
428 intent_requiredunless you send theX-ServiceHub-Intentheader (create-rule,switch-rule,update-rule,delete-rule,generate-rules). The app already sends it, so nothing changes on screen.
What's new
- A demo that works.
/demoopens all three clouds together: six namespaces, about 750 dead letters, 14 days of history and 300+ ledger entries, with the same five failure stories on every cloud. Replay, bulk replay, purge, approve and decline, Auto Replay rules, pause, emergency stop and Look now all work; each says "Demo — nothing was sent". Reset demo starts over. - It stays honest. Azure replays end verified or came back; AWS and Google end verification required and their rules ask a person, exactly as the real clouds behave.
- Show me around. A 13-stop guided tour that drives the real screens, from a failed message to Connections. Skippable, restartable from the banner.
- Exit demo mode is one click from the logo, top-left.
- A demo-only build and a GitHub Pages workflow for a public demo page (no server, connects to nothing; Pages is not switched on yet).
- Open the trace. A message's trace ID (
traceparent, Service BusDiagnostic-Id, AWS X-Ray) links to your own tracing tool, set in Settings → Preferences. Nothing is stored on the server. - Auto Replay stops when the latest results turn bad. If 2 of a failure's last 10 verified replays did not hold, it goes back to a person, and carries on by itself once newer replays hold. It can only make Auto Replay more careful.
- Failures are told apart by their error message, so two different failures on one queue no longer share trust. Existing groups that don't split keep their identity, trust and rules.
- Confirming a fix on AWS and Google Cloud (off until you switch it on). A complete view of the cloud's dead-letter queue lets a replay read recovered or came back instead of verification required. A view either saw everything or the replay stays verification required; there is no confidence score. Per namespace in Settings → Connections.
- An MCP server (
tools/mcp/): read-only, ten fixed GET addresses, no tool that replays, purges or approves. - Deploy in your own cloud (
infra/): Terraform for Azure, AWS and Google Cloud with a private VM, no open port, key in the cloud's secret store, daily snapshots. Not yet run against a real account.
Fixed
- An interrupted replay could be sent again. It now becomes outcome unknown, blocks any other attempt on that message, shows in the bell and Needs your attention, and an Approver closes it by recording what they found. Nothing is retried on its own.
- Auto Replay rules could be changed by a bare request (see the
428note above). - A stuck agent stayed stuck after a network connection died during sleep; a cycle is now abandoned after 10 minutes and the agent runs again.
- AWS: the whole-queue check never worked on a real queue. Found and fixed against real SQS.
- Auto Replay rules only worked in the namespace they were made in after failures were grouped by error message; they now follow the owner's signature across namespaces.
- Keyboard scrolling of long message bodies, two low-contrast texts, the favicon 404, a duplicate-key warning in the Google Cloud guide, and flaky integration tests.
Everything is in the CHANGELOG.
Before you connect a real cloud
- No sign-in. Whoever can reach the port is the server's owner, an Administrator. Keep it on
localhost, a private network, or behind an authenticating reverse proxy. See SECURITY.md. - It stores part of each message. The first 500 characters of the body, the properties and a hash are kept in the local SQLite file in plain text (credentials and webhook URLs are encrypted). Protect the data folder and backups like the messages themselves.
- Azure needs a Manage-level policy to list queues and count messages; make a dedicated policy. Replay uses Send.
- One instance per data folder. A second instance on the same folder exits on purpose. No high availability.
- Replay All Messages replays everything in the chosen scope, not just what the filters show. Its preview says how many, and Stop now leaves unsent messages untouched.
What was verified, and what was not
- The container image was built by this tag's release workflow, pulled with no login, and run from a clean data folder.
- Run live against real AWS and Google Cloud on 2026-10-09: on AWS a replay that failed again read came back and a cured one read recovered; an interrupted scan gave its messages back within five minutes; on Google Cloud the recovery marker survives dead-lettering and a replay that failed again read came back.
- Not observed: a cured replay on Google Cloud, 1,000+ and 5,000-message queues, a second reader on AWS.
- Not run against a real account: the
infra/deploy modules. - Role-based access is enforced and tested in CI; it was not exercised live. Real Slack/Teams delivery has not been exercised against a live workspace.
- CI on the release commit (
cd2a1cfb): 1,569 backend tests (1,373 unit, 196 integration; 1 skipped), 711 frontend tests (1 skipped) and 97 browser accessibility tests, all passing.
Feedback
Tried it and something was confusing, or broke on first run? Open an issue or start a discussion.