Live
Software
Smart Home
HACS
Updated: Sep 2026

Talos: HA Security
Scanner

A Home Assistant integration that maps where the home's data comes from and where it goes. It cross-references what Home Assistant declares about its own devices with what the DNS resolver actually observed them doing, and keeps the two apart everywhere except one place. It also answers the question nobody asks: what stops working when the uplink drops, and which vendor takes the largest share of the house with it.

v1.25.0
Current version

What it is

Talos looks at a smart home and answers two questions Home Assistant cannot put to itself: where the data comes from and where it goes, and what keeps working when the uplink drops.

It reads what Home Assistant declares about its own devices, cross-references it with what the DNS resolver actually observed those devices doing, and reports both sides with the evidence attached to every row.

The reason, in one sentence

The iot_class in an integration’s manifest says how Home Assistant talks to a device, and says nothing about how that device talks to the internet.

A Shelly on local_push can have Shelly Cloud enabled in parallel, and Home Assistant will never know: from where it stands the device is local, because local is the way it talks to it. Those are two different facts, and Talos keeps them separate everywhere, crossing them in exactly one place: the matrix.

Why “Talos”

In Greek mythology Talos is the bronze automaton that circled Crete three times a day, watching who approached the shore and what they carried. He did not attack the island’s own people and he did not guess: he watched, and he reported.

That is precisely what this integration does, and it is also why it refuses to call a heuristic on metadata a vulnerability.

The quadrant that matters

The matrix crosses the two sides, and one of the four quadrants is the only red thing in the interface: declared local to Home Assistant, yet caught phoning home.

It is not a generic alert, it is a contradiction between two independent sources: on one side what the integration claims about itself, on the other the DNS queries that device actually made. The other three cells are consistent and stay grey.

What is in the panel

View What it answers
Connection map A force layout in the manner of Obsidian’s graph view, drawn with no library: every device close to its hub, every hub close to its integration. Declared data only, so it works with no AdGuard configured
Declared/observed matrix The red quadrant above
Offline autonomy Entities and integrations that hold up with the uplink down, grouped by vendor, so a single vendor outage can be costed
External exposure Devices seen reaching outside, with query volume, vendor, and whether AdGuard filtered any of it
Flows graph In columns, where the point of the picture is the arcs that bypass Home Assistant entirely
Routes Every row reads left to right: what is talking, the legs that carry its data, and what is at the far end. Where the sentence breaks it says so, instead of leaving a branch that ends at nothing
Posture checks Severity and remediation, with four possible outcomes: passed, verified in part, finding, could not run
Diagnostics A measurement taken now, never scheduled and kept out of the scan, with add-ons and system resources where the Supervisor is there to ask

The project’s two honesties

Checks that could not run do not become passes. They are counted separately and declared, and since v1.21 there is a fourth outcome, verified in part, for a check that ran without seeing everything: green would claim everything was seen, grey that nothing was looked at, and neither is true. A partial never counts among the passes, and the total stays checkable by hand.

The zero check. Talos lists the hosts holding a DHCP lease that never query the resolver. Those are the tool’s own blind spots: devices it can say nothing about, because its observed source never sees them. Declaring them is more useful than pretending the picture is complete.

How a scan works

Five steps, by default every fifteen minutes.

1. Read the declared side. The registries are read in process. The canonical unit is the config entry, not the device: mobile_app, weather and TTS own entities without owning any device, and they are among the most cloud-bound things in a typical install.

Two things are read off the entry. The first is the address it connects to, which is the only way to tell two brokers apart: with EMQX and Mosquitto both installed the domain says mqtt for both, and only the entry says which one the devices actually arrive through. Nothing else is read, because the same dictionary holds usernames, passwords and tokens, and none of them belong in a document meant to be exported. The second is the entry state: one in setup_retry is serving nothing, so its entities are counted as unavailable rather than local. Working offline and not working at all are not the same result.

2. Poll AdGuard Home. The query log is a rolling buffer, not a queryable history, so Talos walks it newest first with the older_than cursor and stops at the cursor the previous poll left. Totals live in a dedicated SQLite file, never in the recorder database, because AdGuard’s retention rolls over and a device that resolved a domain four thousand times last week would otherwise read as a handful today.

A radio is a conduit too. A Zigbee lamp exchanges data with its coordinator constantly and never touches IP: it owns no address, appears in no query log, and used to be missing from every view built on conduits. The graph showed the part of the house that talks to the internet and left out the part that does not, which said the branch was not there rather than that it never leaves the hub. Now every device hanging off another carries a declared conduit to it, with the transport as the protocol, ending at a local_hub and stopping there: what the hub does next is the hub’s own conduit.

3. Join the two sides. The device registry knows MACs, the query log knows IPs, and something has to hold both. DHCP leases are the usual route, but there is another already inside Home Assistant: a router-based device tracker (AsusWRT, UniFi, Fritz, OPNsense) publishing an ip.

What it does not do, declared

Everything is read-only. No port scanning, no active probing, no traffic inspection, no CVE matching.

That is not a shortcoming, it is the same choice as the name: a tool that watches and reports should not turn a guess about metadata into a security verdict.

The outputs

Nine summary entities and one problem binary sensor, not one entity per device: an analysis integration that doubles the entity registry makes the house it is measuring worse.

Then a self-contained HTML export, with no scripts and no external assets, to archive or hand to someone else, and a separate command line running the same pipeline out of band against a remote instance.

The domain list and the check list live in data files, so they extend without touching code, and setup finds the AdGuard Home endpoint on its own, from the official integration or the add-on, pre-filling the form with whatever actually answered.

Access

The panel is admin only. Distributed via HACS, it requires Home Assistant 2024.6 or newer.

Licence

MIT.