boma/roles/reverse_proxy/VERIFY.md
sjat cb8f924d4b docs(reverse_proxy): service-role SECURITY/VERIFY/ACCESS records (O12)
reverse_proxy is the first built+applied service role; add the per-service
records CLAUDE.md/ADR-002/008/017/021 require. Add access__*/backup__* data to
defaults as the source of truth (ADR-021/022). reverse_proxy is stateless (ACME
certs re-issue via HTTP-01), so it declares backup__state: false with a reason
rather than a BACKUP.md (ADR-022 convention).

The access__*/backup__* cross-role field names intentionally don't carry the
reverse_proxy__ prefix, so each is marked `# noqa: var-naming[no-role-prefix]`
(ansible-lint has no per-prefix allowlist; rule stays enabled elsewhere).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 19:06:23 +02:00

44 lines
2.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Verify — reverse_proxy (Caddy)
`reverse_proxy` has no application UI of its own — it is the TLS terminator and router.
"Working" is verified at the HTTP/TLS layer (what `/verify-service` can drive with a
browser/HTTP client against the public hostnames it serves), not via an app login.
## Critical user journeys
1. **HTTPS serves with a valid cert** — request `https://<a host in
reverse_proxy__routes>` (e.g. `https://test.askari.wingu.me`) → 200 with a valid
Let's Encrypt certificate (trusted chain, CN/SAN matches the host, not expired).
2. **HTTP redirects to HTTPS** — request `http://<host>` → 308/301 redirect to the
`https://` URL (Caddy's automatic-HTTPS redirect).
3. **A `respond` route returns its static body** — the test vhost returns its configured
string with 200.
4. **An `upstream` route proxies through** — once a real upstream is registered (M4b
NetBird), `https://<host>` reaches the upstream's response, not a Caddy error page.
5. **An unknown host is not served a valid cert** — a hostname not in
`reverse_proxy__routes` does not get a certificate / is not routed (no accidental
catch-all).
## What good looks like
- The browser padlock shows a valid Let's Encrypt certificate for the requested host;
the SAN matches and the chain is trusted.
- `http://` visibly becomes `https://` in the address bar.
- The expected body (static `respond` text, or the upstream's page) renders.
## Not browser-verifiable
- Certificate *renewal* (60-day cadence) — confirm out of band via `docker logs caddy`
/ Loki, not a single browser session.
- Behaviour when port 80 is blocked (HTTP-01 would fail) — an infrastructure/firewall
check, route to the manual handoff.
- The deferred DNS-01 path for mesh/LAN-only services (Phase 2, ADR-024) — not yet live.
## Test data
Provisioned in the **staging** deploy (no Authentik user needed — there is no SSO on the
proxy itself):
- At least one `reverse_proxy__routes` entry with a public DNS A-record pointing at the
staging host, so HTTP-01 can complete. A static `respond` route is enough for journeys
13 and 5.