Skip to main content

Clave maestra LUX

LUX_MASTER_KEY_HEX es la clave de la que se derivan las claves por dispositivo y la K de broadcast del protocolo LUX. Hay que aprovisionarla a mano en cada instancia: es compartida con el firmware, así que no puede autogenerarse — una clave inventada por el servidor no coincidiría con la que llevan los dispositivos.

Cómo se pone

En .env.secrets de la raíz del repo:

GLOBAL_LUX_MASTER_KEY_HEX=<32 caracteres hex>

La plantilla de things_extensions la lee de ahí (LUX_MASTER_KEY_HEX=${GLOBAL_LUX_MASTER_KEY_HEX}). Después:

./infra env generate processing/things_extensions
./infra release <host> processing/things_extensions --remote-build

Formato: exactamente 32 caracteres hexadecimales (16 bytes). lux_mac.master_key() rechaza cualquier otra longitud.

Por qué falla en silencio

Con la clave vacía, master_key() devuelve None y device_key_for() también: la derivación de claves simplemente no ocurre, sin error ni aviso en los logs. No hay ningún síntoma que apunte a la causa, así que conviene comprobarla explícitamente:

docker exec things-extensions python -c \
"from app.bridge.processing.protocols.lux_mac import master_key; \
k=master_key(); print('OK', len(k), 'bytes') if k else print('VACIA')"

Y quedó vacía de entrada por un detalle del generador de entornos: generate-env.sh solo trata como secreto lo que termina en PASSWORD, SECRET, TOKEN, API_KEY, ENCRYPTION_KEY y similares. LUX_MASTER_KEY_HEX termina en _HEX, así que no se resolvía, ni se autogeneraba, ni se preguntaba: se copiaba el vacío de la plantilla. Su vecina BRIDGE_WEBHOOK_TOKEN sí se rellenó sola precisamente por terminar en TOKEN.

Si aparece otra clave con nombre acabado en _HEX, _B64 o parecido, va a caer en la misma trampa. O se le pone el alias ${GLOBAL_...} en su plantilla, como aquí, o se extiende el patrón de is_sensitive_key.

Relacionado: [[mosquitto-legacy-accounts]] — el otro caso de credencial que hay que aprovisionar a mano y que nadie reproduce sola.