Document the TouchHub setup runbook

This commit is contained in:
2026-09-20 19:44:30 -04:00
parent 43ad44ee48
commit 7b5ea2b29e
2 changed files with 68 additions and 0 deletions
+58
View File
@@ -155,6 +155,64 @@ Sensors the automations read: `sensor.nestquest_<child>_quests_due_today`
`..._quests_completed_today`, and
`binary_sensor.nestquest_<child>_present_today`.
## TouchHub setup
Run these steps in order to display the NestQuest panel on a TouchHub
wall device. The panel is an HA Lovelace dashboard, so the kiosk browser
is simply a Home Assistant client.
1. **Allow the panel to be framed.** The NestQuest Lovelace panel card
embeds a Home Assistant iframe, which Home Assistant blocks by default.
Add the following to `configuration.yaml` and save it:
```yaml
http:
use_x_frame_options: false
```
2. **Restart Home Assistant.** Use *Settings → System → Restart* and pick
**Restart Home Assistant** (a full restart, not a YAML reload) — the
`http:` setting is only applied at startup.
3. **Create a dedicated kiosk user.** In *Settings → People → Users*, add
a new user for the wall device. Make it **non-admin**, and do **not**
add it to the NestQuest admin allowlist. This is the account the panel
runs as, and it should have no authority beyond viewing the dashboard.
4. **Build a dashboard with only the NestQuest panel card.** Create a new
Lovelace dashboard that contains nothing but the NestQuest panel card.
Keep the surface minimal — no other cards, no admin controls.
5. **Point TouchHub at it.** In the TouchHub launcher, add the **Home
Assistant Lovelace** app to the dock and paste the dashboard URL from
step 4. TouchHub loads that URL in its kiosk browser.
6. **Log the kiosk session in.** Sign in on the device as the dedicated
kiosk user from step 3, and leave that session logged in.
### The clickjacking trade-off
`use_x_frame_options: false` removes the `X-Frame-Options` response
header, which is what stops Home Assistant from being embedded in a frame
on another site. Disabling it is what lets the panel card iframe Home
Assistant — but it also lets **any** page frame Home Assistant, so a
malicious site could render the HA UI invisibly and trick a logged-in
user into clicking controls they did not mean to click. That is
clickjacking.
This is an accepted, scoped risk for a wall display, and it is contained
by how the kiosk account and dashboard are set up. Two mitigations:
- The kiosk user is non-admin and is **not in the NestQuest admin
allowlist**, so even a hijacked click cannot reach admin-only
operations or other parts of Home Assistant.
- The dashboard **contains only the NestQuest panel card**, so there are
no unrelated controls on screen for a clickjacking overlay to weaponise.
A third, optional hardening is to keep the kiosk browser on a trusted
device and network, and to leave the kiosk session logged in only on that
device.
## Developer Setup and Testing
This project uses [`uv`](https://github.com/astral-sh/uv) for fast Python package and dependency management.
+10
View File
@@ -163,3 +163,13 @@ def test_frontend_and_www_have_no_cdn_font_references() -> None:
text = path.read_text(encoding="utf-8", errors="ignore")
for marker in CDN_MARKERS:
assert marker not in text, f"{path}: {marker}"
def test_readme_documents_the_touchhub_setup_runbook() -> None:
readme = " ".join(
(REPO_ROOT / "README.md").read_text(encoding="utf-8").split()
)
for required in ("use_x_frame_options", "TouchHub", "kiosk", "clickjacking"):
assert required in readme, required
assert "not in the NestQuest admin allowlist" in readme
assert "contains only the NestQuest panel card" in readme