From b2f5315e09032b67cabd05ecfeeb39ee10f3bec3 Mon Sep 17 00:00:00 2001 From: Peter Kay <59865048+dougle03@users.noreply.github.com> Date: Thu, 12 Nov 2026 16:04:09 +0000 Subject: [PATCH] Validate MQTT TLS options before startup (#24951) * Validate MQTT TLS verification options before client startup * Test MQTT configuration recovery with authentication available * Cover both MQTT TLS verification values in safe-mode recovery * Use a documentation address in MQTT regression tests * Skip MQTT TLS validation when MQTT is disabled * Simplify MQTT TLS validation regression coverage --------- Co-authored-by: Peter Kay --- frigate/config/mqtt.py | 10 ++++++++++ frigate/test/test_mqtt_tls.py | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 frigate/test/test_mqtt_tls.py diff --git a/frigate/config/mqtt.py b/frigate/config/mqtt.py index 5815a99f6f..ec7216298e 100644 --- a/frigate/config/mqtt.py +++ b/frigate/config/mqtt.py @@ -84,3 +84,13 @@ class MqttConfig(FrigateBaseModel): if (self.user is None) != (self.password is None): raise ValueError("Password must be provided with username.") return self + + @model_validator(mode="after") + def tls_insecure_requires_tls(self) -> Self: + """Reject TLS verification settings without TLS when MQTT is enabled.""" + if self.enabled and self.tls_insecure is not None and self.tls_ca_certs is None: + raise ValueError( + "tls_insecure requires tls_ca_certs. Remove tls_insecure for plaintext " + "MQTT, or set tls_ca_certs to a CA certificate path to enable TLS." + ) + return self diff --git a/frigate/test/test_mqtt_tls.py b/frigate/test/test_mqtt_tls.py new file mode 100644 index 0000000000..517450857d --- /dev/null +++ b/frigate/test/test_mqtt_tls.py @@ -0,0 +1,24 @@ +"""Tests for MQTT TLS configuration validation.""" + +import unittest +from contextlib import nullcontext + +from pydantic import ValidationError + +from frigate.config import MqttConfig + + +class TestMqttTls(unittest.TestCase): + def test_tls_insecure_requires_tls_only_when_enabled(self) -> None: + """Require TLS for either explicit verification flag only if MQTT is enabled.""" + for enabled in (True, False): + for insecure in (True, False): + expected = ( + self.assertRaisesRegex( + ValidationError, "tls_insecure requires tls_ca_certs" + ) + if enabled + else nullcontext() + ) + with self.subTest(enabled=enabled, tls_insecure=insecure), expected: + MqttConfig(enabled=enabled, tls_insecure=insecure)