---
title: "Gatekeeper: Home Assistant"
type: entity
tags: [gatekeepers, developer, advanced, emerging]
created: 2026-08-05
updated: 2026-08-05
sources: ["raw/github_doc-packages-gatekeeper-homeassistant-readme-md.md"]
confidence: high
cfos_snapshot: "2026-08-05"
---

## Overview

The Home Assistant gatekeeper lets a Gadget read state from a connected Home Assistant (HA) instance, call services on devices (lights, thermostats, locks, etc.), edit Lovelace dashboards, render templates, and read history — all mediated through the standard Gadgets approval queue.

## Characteristics

- **Auth**: Home Assistant **long-lived access token (LLAT)** + instance URL, no OAuth flow — chosen because each HA instance has a different URL (no central directory), LLATs don't expire (10-year default lifetime), it's the pattern users already know from other HA tools, and it works for both Nabu Casa Cloud and self-hosted/LAN users. The user pastes URL + LLAT into a form; the gatekeeper validates via `GET /api/` and stores both in a per-user Durable Object.
- **Reachability**: on Cloudflare-hosted deployments, HA must be publicly reachable (Nabu Casa, Cloudflare Tunnel, port-forwarding). On self-hosted (workerd) deployments, LAN addresses like `http://homeassistant.local:8123` or `http://192.168.x.x:8123` work directly — the intended setup for same-network deployments.
- **Five resource granularities**: Whole instance (every area/device/entity/dashboard/service), Area (one room's devices/entities), Label (all entities with a given HA label), Device (one physical device and its entities), Entity (one light/sensor/switch/etc.) — each with its own configurator picker UI.
- **TypeScript API**: bindings expose `HomeAssistantSession` (whole-instance), `Area`, `Label`, `Device`, or `Entity` depending on granularity. Example:
  ```ts
  const areas = await session.listAreas();
  const light = await session.getEntity("light.kitchen");
  await light.turnOn({ brightness: 200 });
  const state = await light.getState();  // reflects simulated post-write state
  const livingRoom = await session.getArea("living_room");
  await livingRoom.callService("light", "turn_off");
  const temp = await session.renderTemplate("{{ states('sensor.outside_temp') | float }}");
  const dashboard = await session.getDashboard("lovelace");
  await dashboard.saveConfig(dashboardConfig);
  ```
- **Approval & simulation**: every read calls `authorizeObservation`, every write goes through `submitAction`; writes do not execute against HA until approved. Until approval, reads reflect a simulated post-action world (e.g. `getState()` shows `"on"` right after `turnOn()`) — but simulation predicts final states only, with no transition timing, and leaves state untouched for unrecognized service calls (custom integrations, scenes, scripts, templates).
- **Not yet implemented (Phase 2)**: caching (every read is a fresh registry fetch) and hooks/push events (`setHook` is a no-op; WebSocket `subscribe_events`/`subscribe_entities` would enable a `HomeAssistantHook`).
- **Implementation notes**: service calls go through HA's WebSocket API (`call_service`), not the REST endpoint, for full target-shape support across area/label/floor targets; every action gets an integer `id` from a per-DO counter, stored under `pending:<id>` for read-time simulation; malformed action bodies fail synchronously with a corrected-call suggestion.

## How to Use

1. In a Gadget's Connections UI, connect a Home Assistant account by pasting the instance URL and a long-lived access token (generate one in HA's own UI).
2. Choose a resource granularity to grant: whole instance, an area, a label, a device, or a single entity, using the matching configurator picker.
3. Use the TypeScript Session API (see `src/types.d.ts` for full method list and `@example` blocks) to read state, call services, render templates, or edit dashboards; writes queue for approval before taking effect on the real HA instance.

## Related Entities

- [[concepts/gatekeepers]]
- [[concepts/writing-a-gatekeeper]]
- [[entities/gatekeeper-spotify]] — comparable approval/simulation model for a consumer device-control API
- [[entities/gatekeepers-catalog]]
