I build and lock down ESPHome automation scenes the same way I build servers. No glamour. No cloud dependency. Start with a clear threat model. Decide what data you will expose and what must stay local. Pick one control channel for scene triggers and stick to it, either Home Assistant API or MQTT with TLS, not both unless you have a good reason.
Begin with the device-level security settings. Change default WiFi credentials and give each device a unique password. Put devices on a separate IoT network or VLAN and clamp that network with firewall rules so it cannot reach your main network. Use secrets.yaml for passwords and keys in your ESPHome configs, never hard-code them. Set an OTA password and an API password in the YAML. If you use MQTT, run it with TLS and client authentication. Make sure broker ports are not open to the internet. Disable mDNS on devices that do not need local discovery. Turn off any telemetry or cloud integrations on the device side. For small, specific examples: add api: password: “long-random-string” and ota: password: “another-long-string” to the device YAML, and reference those secrets from secrets.yaml. Use static IPs or DHCP reservations so firewall rules and monitoring are reliable.
Design automation scenes with failure and privacy in mind. I build scenes in Home Assistant and trigger them from ESPHome devices with the API or MQTT commands. Keep scene state machine logic in the controller, not on the ESP device, unless the scene must run without the controller present. For light scenes, store the intended brightness and colour in Home Assistant scenes and expose only switches or buttons from ESPHome. For battery-powered or offline-capable devices, put the fallback behaviour into the ESP YAML: set a safe default on boot with on_boot then publish a retained status so the controller knows the device state. Avoid sending raw sensor streams, images or audio from devices unless the local network is locked down and that data is encrypted in transit and at rest.
Monitoring and management reduce risk more than a single lock. Add an uptime sensor and a last-seen timestamp to each ESPHome device. Use the native status sensors so you can alert on flapping devices. Keep OTA on but limit it to the IoT network and require the OTA password. Log to local systems, not external cloud services. If a device starts failing OTA frequently, the issue is usually WiFi or power. Try a higher quality power supply, shorten data lines, and give the ESP32/ESP8266 a stable 3.3V rail. For flaky WiFi, move the access point closer or add a mesh node. For persistent failures, compile with a watchdog restart handler so the device reboots into a known state rather than getting stuck.
Privacy configurations and network security tools matter. Run a local DNS blocker like Pi-hole to limit outbound telemetry domains. Use firewall rules to block device-initiated connections to unknown endpoints. Set MQTT message retention to minimal, and avoid publishing sensitive tokens as retained messages. Consider client certificates for broker auth if you want stronger guarantees than passwords. Keep the ESPHome toolchain and firmware up to date and subscribe to release notes for security fixes. I treat each device like a critical host: strong credentials, limited network access, and monitored health.
Takeaways: treat scene triggers as control-plane traffic and keep them on a segmented network; use secrets.yaml and per-device passwords; prefer local controllers and TLS for MQTT; add health sensors and watchdogs for recoverability; minimise data sent off the local network. Do these and our smart home will stay useful without becoming an open door.