The HTML operator page served the same clients/ledger/queue/review data as
the authenticated JSON summary, but with no auth at all. The loopback
requirement it relied on existed only as prose (page note + docstring); it
was never enforced by mount_dashboard, which does not own the app and
cannot constrain the bind address.
Put /dashboard behind the same _guard as /api/dashboard/summary:
- no X-API-Key -> 401, no billing data
- no configured key -> 503 (fail-closed)
- valid key -> 200 HTML (unchanged rendering)
Also drop the now-false 'loopback-only' security claims from the page note
and the mount_dashboard docstring, and update the tests:
- test_dashboard_page_open_and_html now sends a valid key
- new test_dashboard_page_guard_blocks_anonymous_access: no key -> 401,
body contains no client data (mutation check: fails if guard removed)
- new test_dashboard_wrong_key_same_length_rejected: wrong same-length
key -> 401 on HTML page too
- test_summary_fail_closed_without_configured_key now asserts the HTML
page also fails closed (503), not open
- test_dashboard_mounts_onto_existing_app sends a valid key
/api/dashboard/summary behaviour unchanged. Suite: 160 passed, 1 skipped
(before: 158 passed, 1 skipped).