feat(mqtt): controller main-a5e1d98 keeps HA's MQTT entry on its client certificate (REN-953)
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful

mqtt-account-controller (REN-1284) now pushes the CA and the client
certificate of the register account home-assistant into HA's MQTT config
entry via HA's reconfigure flow, only when tls.crt changed and only inside
02:00-05:00 Europe/Berlin. Mounts mqtt-home-assistant-tls and the HA token
(OpenBao apps/home-assistant/mqtt-cert-sync-token, service user MQTT Cert
Sync), sets the HA env and adds Secret mqtt-ha-cert-sync to the Role.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
atlas-bot
2026-10-08 07:02:34 +00:00
co-authored by Claude Opus 5.5
parent 745d96e304
commit 91b8b9ab8b
@@ -85,6 +85,8 @@ subjects:
# that creates, because the name is in the request path).
# mqtt-<name>-tls: delete on revocation, one entry per cert account
# delivered to this namespace. Add the name with the register entry.
# mqtt-ha-cert-sync: sha256 of the client certificate last accepted by
# Home Assistant's MQTT config entry (HA cert sync, REN-953/REN-1284).
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@@ -95,7 +97,7 @@ metadata:
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["mqtt-account-hashes", "mqtt-dynsec-seed"]
resourceNames: ["mqtt-account-hashes", "mqtt-dynsec-seed", "mqtt-ha-cert-sync"]
verbs: ["get", "create", "patch"]
- apiGroups: [""]
resources: ["secrets"]
@@ -252,7 +254,7 @@ spec:
- name: controller
# Woodpecker builds main-<sha> on every merge to main; no sortable
# tag, so bumps are manual (same as ical-proxy).
image: gitea.renner.uno/konairius/mqtt-account-controller:main-a5b299d@sha256:ab1309f53170500b7d67f65b09bb247e1a476250667150597fc3ca62a5f4ba60
image: gitea.renner.uno/konairius/mqtt-account-controller:main-a5e1d98@sha256:6ef95b2a59396f07033d1cd3a2683186a78b519c2e8fd8cd071fc178a1d1c0b7
env:
- name: BROKER_URL
value: ssl://mosquitto.home-assistant.svc.cluster.local:8884
@@ -263,6 +265,22 @@ spec:
value: http://shelly-manager-api.home-assistant.svc.cluster.local
- name: SHELLY_MANAGER_API_KEY_FILE
value: /etc/shelly-manager/api-key
# HA cert sync (REN-953, REN-1284): keeps Home Assistant's MQTT
# config entry on mosquitto:8884 with the CA and client
# certificate of the register account `home-assistant`. After
# each loop the controller compares tls.crt (mounted below) with
# the last certificate HA accepted (Secret mqtt-ha-cert-sync) and,
# only inside 02:00-05:00 Europe/Berlin, runs HA's reconfigure
# flow. HA tests the connection before it saves. Defaults:
# broker mosquitto.home-assistant.svc.cluster.local:8884, cert dir
# /etc/mqtt-home-assistant-tls. Off while HA_MQTT_ENTRY_ID is unset.
- name: HA_MQTT_ENTRY_ID
value: 01KRFXD4046FEBWQ0EX0GNE418
# HA itself (:8123), not the :8124 XFF proxy; same namespace.
- name: HA_URL
value: http://home-assistant-bgp.home-assistant.svc.cluster.local:8123
- name: HA_TOKEN_FILE
value: /etc/ha-token/token
# Not :8080: several :8080 ingress grants in the home-assistant
# default-deny apply to every pod in the namespace.
- name: LISTEN
@@ -293,6 +311,12 @@ spec:
- name: shelly-manager-key
mountPath: /etc/shelly-manager
readOnly: true
- name: ha-mqtt-tls
mountPath: /etc/mqtt-home-assistant-tls
readOnly: true
- name: ha-token
mountPath: /etc/ha-token
readOnly: true
resources:
requests:
cpu: 5m
@@ -315,3 +339,35 @@ spec:
items:
- key: api-key
path: api-key
# Client certificate HA gets (cert-manager renews it in place; not a
# subPath mount, so the next loop sees the new file).
- name: ha-mqtt-tls
secret:
secretName: mqtt-home-assistant-tls
# HA long-lived token of the service user `MQTT Cert Sync`
# (system-admin; config flows need admin). REN-1268.
- name: ha-token
secret:
secretName: mqtt-account-controller-ha-token
---
# HA admin token for the HA cert sync (see the Deployment env). Minted by
# Hermes on a dedicated HA service user, not the owner's account (REN-1268).
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: mqtt-account-controller-ha-token
namespace: home-assistant
labels:
app.kubernetes.io/name: mqtt-account-controller
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: openbao
target:
name: mqtt-account-controller-ha-token
data:
- secretKey: token
remoteRef:
key: apps/home-assistant/mqtt-cert-sync-token
property: token