Capabilities & pass-through
The permission tree decides which entities a token can touch. Capability flags decide whether it can do the high-impact, cross-cutting things at all: restart Home Assistant, control a lock, write an automation, read the logs. They are off by default. ATM defines twenty-two of them; a persona applies a ready-made preset across every capability in one step, and you can override any single one afterward.
How the modes work
Every capability holds one of three modes. Reading a mode in any code path goes through a single helper, so the pass-through interaction is always consistent.
deny
The operation is refused. This is the default for the riskier tiers.
allow
The operation runs, subject to the permission tree and MESA.
confirm
The operation is held as a pending approval until a human approves it in the panel. Honored even under pass-through.
confirm is only meaningful for the write, system, and irreversible capabilities; the read-tier capabilities are deny or allow only.
A pending approval stores the requested action so the admin can review it. For file and configuration.yaml writes, the before/after diff shown for review and the admin API responses are run through a secret redactor: values on sensitive-looking keys (password, api_key, secret, and similar) and any embedded tokens or URL credentials are replaced with <redacted>, while the structure of the change stays visible. The pending record itself keeps the raw tool arguments while the approval is queued, because an approved action has to re-run with the real content; so for write_file and set_yaml_config the unredacted content can exist in .storage/atm during the approval window.
The capability flags
The pass-through column shows what happens under a pass-through token: granted means pass-through turns it on for you, must enable means it stays off until you set it explicitly, even for pass-through tokens. Each row names the capability as it appears in the panel, with its API field id (used by the admin API) beneath.
Read and discovery
| Capability | Enables | Pass-through |
|---|---|---|
Automation tracescap_traces | Automation execution traces via get_automation_traces | granted |
Broadcastcap_broadcast | Announcements via HassBroadcast through assist satellite devices | granted |
Config readcap_config_read | Read HA configuration data and the event-bus listener list, plus the MESA retrieval tools (mesa_query_profiles, mesa_get_profile, mesa_explain_profile, mesa_get_caller_context); see MESA | granted |
Diagnosticscap_diagnostics | get_system_health, check_config, validate_config, get_radio_network, get_radio_device | granted |
Log readcap_log_read | Read HA system log entries (get_logs). ATM's own entries are excluded; tokens, JWTs, and URL credentials are scrubbed. A sensitive grant: logs are free-form text from every integration. | must enable |
Registry readcap_registry_read | Registry enumeration: list_areas, list_floors, list_zones, list_devices, get_device | granted |
Search & discoverycap_search | Discovery and comprehension reads: search_entities, get_overview, describe_area, describe_entity, find_available_actions, get_relationships | granted |
Service response datacap_service_response | Return response data from services that declare a response schema | granted |
Template rendercap_template_render | Render Jinja2 templates in a permission-scoped environment | granted |
Write, system, and irreversible
Every capability in this group must be explicitly enabled, pass-through never grants them, and every one can be set to confirm.
| Capability | Enables | Modes |
|---|---|---|
Automation writecap_automation_write | Create, edit, and delete automations. See the warning below. | deny / allow / confirm |
Backupcap_backup | Create and list backups; restore is never exposed | deny / allow / confirm |
Dashboard writecap_lovelace_write | Create, edit, and delete dashboards | deny / allow / confirm |
Filesystem accesscap_filesystem | Read and write files under www/, themes/, custom_templates/ | deny / allow / confirm |
HA restart / stopcap_restart | homeassistant.restart and homeassistant.stop | deny / allow / confirm |
Helper writecap_helper_write | Create, edit, and delete helpers | deny / allow / confirm |
Integration managementcap_integration_write | Enable and disable integrations | deny / allow / confirm |
Physical controlcap_physical_control | Lock, alarm, cover, and valve mutation services (lock.unlock, alarm_control_panel.alarm_disarm, cover.open_cover, valve.open_valve, and related) | deny / allow / confirm |
Raw YAML editcap_yaml_edit | Edit configuration.yaml directly | deny / allow / confirm |
Registry writecap_registry_write | Edit an entity's registry metadata (name, icon, area) and delete stale registry entries (set_entity, delete_entity) | deny / allow / confirm |
Radio managementcap_radio_write | Manage the Zigbee network via Zigbee2MQTT or ZHA: open it for pairing, re-interview devices, remove devices (permit_zigbee_join, reconfigure_zigbee_device, remove_zigbee_device). ATM assumes the default Zigbee2MQTT base topic (zigbee2mqtt); a Z2M install using a custom base topic is not currently supported. | deny / allow / confirm |
Scene writecap_scene_write | Create, edit, and delete scenes | deny / allow / confirm |
Script writecap_script_write | Create, edit, and delete scripts. See the warning below. | deny / allow / confirm |
Personas
You rarely set capabilities one at a time. A persona is a named preset that fills in the entire matrix at once, and choosing one applies the whole set, not just a label. After applying a persona you can still adjust any single capability; the token then shows as Custom unless the new combination happens to match another preset.
| Persona | What it sets up |
|---|---|
| Read-only observer | Reads state, history, logs, and templates. No actions, no broadcast. |
| Voice assistant | Reads, service calls, and broadcast. Locks, alarms, and covers require admin confirmation. |
| Dashboard designer | Reads and discovers entities and builds Lovelace dashboards. Filesystem access (theme and custom-card assets) requires confirmation. No device control or config authoring. |
| Maintenance / backups | Full reads and diagnostics, creates backups. Restart requires confirmation. No device control, config authoring, or dashboards. |
| Automation builder | Voice assistant plus full discovery and automation, script, scene, and helper CRUD. Restart and physical actions require confirmation. |
| Power user | Full reads and config writes, restart allowed. Physical actions, integrations, dashboards, and backups require confirmation; filesystem and raw YAML stay off. |
| Home administrator | Whole-home control with a safety net: all reads and config writes, with restart, physical actions, integrations, dashboards, backups, filesystem, and raw YAML all requiring confirmation. |
| New user | A safe starting point used by the guided setup: read the home and control granted devices, with locks, alarms, and covers asking for confirmation. |
| Custom | No preset; configure each capability individually. |
Automation and script write
Automation write and Script write are elevated-trust capabilities. Enable them only for clients you fully control.
These flags do not consult the permission tree
The write tools edit automations.yaml and scripts.yaml directly. A client with the flag can write an automation referencing any entity in Home Assistant, regardless of what its tree permits. Setting the automation or script domain to RED or YELLOW does not stop them.
- All or nothing. There is no per-entity scoping for these tools. The flag is on or off.
- Triggered actions run outside ATM. An automation created through ATM is run by Home Assistant's own engine, under its own context. ATM's permission checks do not apply to what a triggered automation does.
- Net effect. A token with a narrow entity scope but this flag enabled could, through a crafted automation, indirectly control entities it cannot reach directly. Treat the flag as broad HA access. See Indirect control risk for the full explanation and an example.
Pass-through mode
Pass-through tokens skip the three-level permission check and have GREEN access to every entity. They are for trusted tools where maintaining a full tree is impractical.
The tree is a cost control, not only an access control
Because pass-through skips the tree, every context-bearing read (get_states, GetLiveContext, the initial snapshot, an unfiltered search) returns all entities. On a large install that is a recurring token and context cost: every discovery call ships the whole house into the model. An ATM scoped token returns only what you granted and can
reduce token burn significantly.
Pass-through does not bypass:
- The
atmdomain blocklist and sensitive-attribute scrubbing - Rate limiting
- Any capability in the write, system, and irreversible group (each must still be enabled)
- Log read
- A capability set to
confirm, which is gated even under pass-through
All other read-tier capabilities are granted by pass-through. Use pass-through only for tools you fully control.
Pass-through and MESA
Pass-through bypasses ATM's per-token tree, but it does not bypass MESA, the per-entity safety layer that always runs last (the MESA page covers it in full). When MESA is active, a pass-through token's writes are still governed by each entity's MESA control_mode. In effect, pass-through hands entity gating to MESA with ATM's per-token permissions out of the way.
In practice this pattern is niche, for two reasons:
- The token and open-read costs above apply in full; every agent sees the entire home.
- MESA gates writes only and is allow-by-default for unprofiled entities, so without extra configuration it is not least-privilege.
MESA can be made fail-closed for writes with deployment defaults and enforced mode, but reads stay open and the context cost remains. For most deployments a scoped token plus MESA is the better combination: the tree scopes what the agent sees (cheap context and read security) and MESA governs write nature on top.