feat(config): let the operator turn off the breach and update checks

Two requests left the server without anything being connected: the
HaveIBeenPwned range query on every password set (registration, change,
admin reset) and the daily GitHub releases request behind the About page
and the admin version tile. Neither could be turned off, which made
"nothing leaves" untrue for an instance that wanted it to be.

PASSWORD_BREACH_CHECK_DISABLED and UPDATE_CHECK_DISABLED (1, true, yes or
on) stop each request. Both stay on by default. The breach check keeps
its fail-open contract: switched off, a password is simply not looked up.
The update route answers status "unknown" with reason "disabled" and
the admin tile says the check is off. The password routes reach the
check only through the switch, and a test holds that import line.

Both are on the compose whitelist, in the env manifest under a new
"Outbound requests" group with IP_GEO_LOOKUP_DISABLED, and documented in
both env examples and the getting-started guide.
This commit is contained in:
Marc-André Bombeck committed 2026-09-26 15:33:34 +02:00
1 parent 228c5c9da6
commit afcb37e76c
21 files changed
+248 -10

No files matched your search

+19
View File
@@ -163,6 +163,25 @@
}
]
},
{
"name": "Outbound requests",
"description": "Switches for the requests HealthLog makes to third parties on its own. All default to on; set any of them to 1, true or yes to turn that request off.",
"required": false,
"variables": [
{
"name": "IP_GEO_LOOKUP_DISABLED",
"purpose": "Stops the online IP-to-location lookup for login events and the monthly MaxMind download. Only the local GeoLite2 databases are used."
},
{
"name": "PASSWORD_BREACH_CHECK_DISABLED",
"purpose": "Stops the HaveIBeenPwned range query made when a password is set. The query carries the first five hex characters of the password's SHA-1, never the password or the full hash."
},
{
"name": "UPDATE_CHECK_DISABLED",
"purpose": "Stops the daily request to the GitHub releases API behind the About page and the admin version tile."
}
]
},
{
"name": "APNs (iOS push)",
"description": "All four core APNS_* vars together. Missing any disables APNs silently \u2014 the v1.4.40 AP-2 gap that motivated this manifest. allOrNone trips the synthetic <all-or-none> required row whenever 1-3 of the 4 are set.",