Permissions
Every token carries a permission tree of domains, devices, and entities. Each node holds one of four states, and a two-pass resolver turns the tree into a single decision for any entity a request touches.
The four states
Each node in the tree is set to one of four states. Color is never the only signal; the panel always pairs the color with a word.
| State | Read | Write | What it means |
|---|---|---|---|
| GREY | inherits | inherits | No opinion. The node inherits from its parent. This is the default for every node; all-grey means no access. |
| YELLOW | yes | no | Read-only. The token can read state but cannot call services that change it. |
| GREEN | yes | yes | Read and write. The token can read state and call services. |
| RED | no | no | Hard deny. Blocks this node and everything beneath it. No child can override it. |
The permission tree
Domains sit at the top, devices nest underneath, and entities are the leaves. You rarely set every node. The usual pattern is to set a whole domain or device to YELLOW or GREEN, leave the children at GREY so they inherit, then use RED to carve out exceptions.
How a permission is resolved
When a request arrives for an entity, ATM walks the ancestor chain (entity, then device, then domain) twice.
Why two passes
Splitting the RED scan from the grant lookup is what makes a RED override absolute. A single pass that stopped at the first grant could let a GREEN child slip past a RED ancestor. Pass 2 closes that gap.
Worked examples
Read every light, control only the living room
Full access to lights, except the guest bedroom
Block one noisy sensor inside a permitted device
Indirect control risk
Three domains carry a risk that is easy to overlook: automation, script, and scene. The permission tree marks them with a ! badge.
WRITE on these domains reaches past the tree
Granting GREEN to an automation, script, or scene lets a client trigger it, and the triggered actions run under Home Assistant's full context, not ATM's. A token with RED on a door but WRITE on automation.* can still unlock that door through a triggered automation.
Granting YELLOW to these domains is safe: it allows reading whether an automation is enabled or a scene exists, without the ability to trigger anything.
The same reach applies to authoring caps and to MESA. A token with cap_automation_write or cap_script_write can persist an automation or script whose embedded service actions are not re-gated by ATM's capability checks or MESA when the automation later fires, because a stored automation runs under Home Assistant natively, outside ATM's request path. So an entity that MESA marks read_only or prohibited can still be actuated by an authored automation that references it. Authoring caps are therefore broad HA write access by nature, and ATM cannot soundly static-analyze an automation's runtime targets (they may be templated or computed). The mitigation is to set authoring caps to Confirm where this matters, so an admin reviews the authored configuration, including its actions, before it persists.
For the triggering half of this risk, MESA can gate the orchestrator entity itself: a confirm profile on the automation or script routes an agent's trigger through the approval gate, whatever the actions inside do. The MESA tab's Suggested profiles section finds exactly these cases for you, unprofiled automations, scripts, and scenes whose declared actions reach risky devices, and offers the profile in one click.
What ATM always blocks
These apply to every token, including pass-through tokens, and are not configurable.
- atm domain
- All internal ATM sensors are permanently blocked and invisible. A client cannot read its own telemetry through ATM.
- secrets
- Attributes that can leak credentials (
access_token,entity_picture,stream_url,still_image_url) are stripped from every state response.
Working in the panel
The panel has tools that make scoping faster than clicking every node: bulk select by area or label, an effective-permission emulator that runs the two-pass resolver for any entity, a sortable summary of every node set to something other than GREY, and per-entity hints (token-local or global) that clarify what an entity is for the connected AI. These all live in the Panel guide.