docs(immich-ssrf): surface NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS hint in error

Homelab/LAN Immich instances trip the SSRF guard (Host 192.168.x resolves
to blocked address).  The fix is to set NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1
in the runtime env — call that out directly in the error message so
operators don't have to dig through source to find it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-22 02:42:22 +03:00
parent 645331d320
commit 58cba88c92
@@ -61,14 +61,15 @@ class ImmichClient:
# SSRF guard — admin-set Immich URLs are loaded from provider config # SSRF guard — admin-set Immich URLs are loaded from provider config
# which can be mutated via PATCH /api/providers or imported via # which can be mutated via PATCH /api/providers or imported via
# prepare-restore, so we revalidate at construction time rather than # prepare-restore, so we revalidate at construction time rather than
# trusting DB state. ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` bypasses # trusting DB state. Homelab deployments pointing at RFC1918 targets
# for dev against localhost Immich. # must set ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` in the runtime env.
if self._url: if self._url:
try: try:
validate_outbound_url(self._url) validate_outbound_url(self._url)
except UnsafeURLError as err: except UnsafeURLError as err:
raise UnsafeURLError( raise UnsafeURLError(
f"Refusing to build ImmichClient for unsafe URL {self._url!r}: {err}" f"Refusing to build ImmichClient for unsafe URL {self._url!r}: {err}. "
"If this is a LAN/homelab Immich, set NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1."
) from err ) from err
@property @property
@@ -81,9 +82,8 @@ class ImmichClient:
@external_domain.setter @external_domain.setter
def external_domain(self, value: str | None) -> None: def external_domain(self, value: str | None) -> None:
# Mirror the constructor's SSRF guard — external_domain is used to # Mirror the constructor's SSRF guard. Set
# build URLs that leak into rendered notifications, but any code path # ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` for LAN/homelab targets.
# that eventually fetches this URL would otherwise bypass the check.
if value: if value:
try: try:
validate_outbound_url(value) validate_outbound_url(value)