Maintenance Manager for Envoy®
Flip a switch, your apps show a maintenance page. Flip it back, they're live. Their routes never notice.
A self-contained Helm chart that puts web apps behind maintenance pages, interstitials and banners on any Kubernetes® cluster running Envoy Gateway ≥ 1.8, without touching the apps or their HTTPRoutes.
- Hands off your routes. It only reads HTTPRoutes, so it works where a platform owns and regenerates them.
- Zero overhead at rest. No window armed, no extra hop: Envoy never calls it.
- Fail-open. If it is down, slow or misconfigured, traffic flows as if it was never there.
- Plays nice with platform auth. Its policy merges into Gateway-level SecurityPolicies instead of replacing them.
- No database. State lives in three custom resources.
How it works
You describe three things, usually in the built-in editor:
- a MaintenanceService: which HTTPRoutes make up an app (a label selector);
- a MaintenancePage: what users see (an HTML template and texts per language);
- a MaintenanceWindow: when, and what happens, as phases.
| Phase | What users get |
|---|---|
banner | The app, plus a header it can show as a banner. |
interstitial | Your page once per session, then the app. |
block | A 503 with your page, or application/problem+json for APIs, plus Retry-After. |
Fifteen minutes before a window starts, it attaches one SecurityPolicy per app namespace to the matching routes, so Envoy asks it about every request. After the window, it removes it.
Install
Every release lists its chart and image digests, with these commands ready to paste. Check it was built here, then install it by digest:
gh attestation verify oci://ghcr.io/prosperity-solutions/charts/maintenance-manager@sha256:<chart digest> \
--repo prosperity-solutions/maintenance-manager \
--signer-workflow prosperity-solutions/maintenance-manager/.github/workflows/ci.yml \
--source-ref refs/heads/main --deny-self-hosted-runners
helm install mm oci://ghcr.io/prosperity-solutions/charts/maintenance-manager@sha256:<chart digest> \
-n maintenance-manager --create-namespace --set editor.password=<at least 12 characters>
Then open the editor NEW!
kubectl -n maintenance-manager port-forward svc/maintenance-manager 8080
# http://localhost:8080, user admin, the password from editor.password
A dashboard shows which windows are armed, which routes they cover, and whether Envoy accepted the policy. Start next phase now is one click.
Tell users in the app
A single file, no dependencies, under 4 KB gzipped. It shows a banner before maintenance, covers the page during a block, and reloads the tab when it ends:
<script src="/static/maintenance-manager.js" data-dismiss="click" defer></script>
Self-host it from the release assets. It works under a strict CSP and Trusted Types.
Good to know
The 60-second drain
Attaching or removing a policy makes Envoy drain the listener: open connections close gracefully over 60 seconds and reconnect. That happens when a window arms and disarms, not during maintenance.
Letting your team through
Set a bypass token and send it as a header with a browser extension. No bypass links and no cookies, so the token never lands in URLs or logs.
If something breaks
Envoy lets traffic through. And a window can always be stopped from the command line:
kubectl -n maintenance-manager patch mmw <window> --type=merge -p '{"spec":{"enabled":false}}'
All the details are in the README.
You are visitor number 000503 (Retry-After: never)