Bump mqtt-account-controller to main-4adc9a6 (shelly-manager#93 client),
give it the shelly-manager API key and URL, and register shelly-5 (Plus i4)
as the first auth: password account. The legacy user shellies stays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent runs mostly execute in the paperclip pod, not in a sandbox (REN-1001:
TCP timeout to :8884 from paperclip-b65cc7768). Adds the egress rule in
paperclip-egress and the paperclip pod as a source in mosquitto-agent-ingress.
:8884 only; it requires an mqtt-ca client certificate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Register entry agents-read (read open3e/#, zigbee2mqtt/#, homeassistant/#),
delivered to the paperclip namespace; agent kubectl identities may get that
one Secret; dedicated CNPs open agent sandbox pods -> mosquitto :8884.
Nothing restarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HA keeps MQTT client certificates only as PEMs inside its config entry, so a
renewal could not reach it. A ghostunnel client sidecar listens on
127.0.0.1:11883 and forwards to mosquitto :8884 with the home-assistant
certificate, reloading it on renewal. HA's config entry is pointed there in a
separate HA-side step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Register entry for Home Assistant (ACL readwrite # as the legacy user
homeassistant, different name so it cannot shadow that login) and its Secret
on the controller's revocation list. Nothing restarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
evcc gets broker URL and the PEMs of the register account evcc-client by
env (EVCC_MQTT_*), which override the mqtt block of evcc.yaml in OpenBao.
Reloader restarts evcc when cert-manager renews the certificate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Register entry evcc-client (deliver evcc, ACL as the legacy user evcc), a
controller Role/RoleBinding in the evcc namespace for its Certificate and
Secret, and :8884 next to :1883 in both evcc<->mosquitto network policies.
Nothing restarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Z2M, discovery-guard and interview-watch use the certificate of the
register account zigbee2mqtt-bridge on the mTLS listener :8884 instead of
the legacy password. Z2M gets server/ca/cert/key by env because its
configuration.yaml on the PVC is never re-seeded. The init container no
longer renders mqtt_password. The legacy broker user stays until a later
broker roll.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the register entry for Zigbee2MQTT (same ACL as the legacy user
zigbee2mqtt, different name so it cannot shadow the running password login)
and its Secret to the controller's revocation list. Nothing restarts; the
controller picks the register up live and issues mqtt-zigbee2mqtt-bridge-tls
before the Z2M switch lands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the register account mosquitto-probe (auth: cert, readwrite health/#),
mounts its certificate into the broker and switches the liveness/readiness
probes to the mTLS listener :8884. Removes the legacy password user health
from passwd, acl, env and the Reloader annotation. The ExternalSecret and
rotator stay until the REN-802 cleanup step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review 1473: shelly-manager signs in whoever X-authentik-username names when
the peer is in the pod CIDR, so opening :8080 to agent pods let any run sign
in with a forged header and no API key.
Agents now get an nginx sidecar on ${POD_IP}:8081 (Service
shelly-manager-api) that drops X-authentik-username and X-Forwarded-User
before proxying to :8080. Both agent CNPs move from 8080 to 8081, so :8080
stays outpost-only and every agent call needs the API key.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Egress from paperclip-renner agent pods and a dedicated ingress CNP on
shelly-manager, container port 8080 (socket-LB). All agents: sandbox pods
carry no per-agent label; the API key gates calls.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The REN-902 build denies publishClientReceive by default and grants receive
per read ACL. On its first loop it rewrites the Secret mqtt-dynsec-seed with
that default. The seed must be rewritten before the production broker loads
it (homelab #1159). Still points at the test broker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
REN-802 step 2. The production mosquitto loads the Dynamic Security plugin
and gets a mutual-TLS listener :8884 (server certificate from mqtt-ca).
mqtt-account-controller now manages this broker instead of the test broker.
The nine legacy users keep password_file and acl_file unchanged.
The Dynamic Security default denies publishClientReceive: with acl_file in
the chain, mosquitto 2.0 does not gate SUBSCRIBE, so a receive default of
allow would let every Dynamic Security client read every topic.
The image policy stays on 2.0.x, because 2.1 changes the plugin chain.
The obsolete delete grant on mqtt-test-revoke-tls is dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The controller must delete Certificate mqtt-test-revoke, Secret
mqtt-test-revoke-tls and the dynsec client and role acct-test-revoke on its
next loop. Only the register ConfigMap changes; nothing restarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
REN-802 step 1. Adds:
- infrastructure/post-crds/mqtt-ca.yaml: private MQTT CA (self-signed root
in cert-manager ns) and ClusterIssuer mqtt-ca.
- apps/home-assistant/mosquitto-dynsec-test.yaml: throwaway mosquitto 2.0.22
with the dynsec plugin, mTLS listener (require_certificate,
use_identity_as_username), initContainer that loads Secret
mqtt-dynsec-seed or a static base file. ClusterIP only; not labelled
mosquitto, so prod Services and the world-ingress policy do not select it.
- apps/home-assistant/mqtt-account-controller.yaml: ServiceAccount, RBAC
(cluster-wide list certificates; certificates in home-assistant; secrets
by resourceName only), controller client cert CN mqtt-account-controller,
Deployment main-47213ef pointed at the test broker.
- apps/home-assistant/mqtt-accounts.yaml: register with two cert test
accounts, delivered as ConfigMap mqtt-accounts.
The production broker is not changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The kubernetes sandbox plugin's release and destroy hooks returned void,
so no lease got a termination receipt and every cancelled pod run left
its card waiting on remote_cleanup. Return state destroyed once the
Sandbox CR / Job (and pod) reads 404, within 20 s; otherwise no receipt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The kubernetes sandbox plugin returns no termination receipt, so the
leases of cancelled runs e08976cd (REN-837) and 144ae3bf (REN-825) were
released without one and the queued owner comments wait on
remote_cleanup forever. The controller log shows both Sandbox CRs
deleted. Write the missing receipt for exactly those leases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The quarterly rotation on 2026-12-01 would change the broker password while
the ESP32 gateway keeps the old one, taking it offline.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One-shot Job that sends three read commands on open3e/cmnd to edge-1's
running open3e (read-json + read-raw on 0x6c3, one read-json on 0x6e0)
and prints the replies for Loki. No write mode, no config change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>