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.

StateReadWriteWhat it means
GREY inheritsinherits No opinion. The node inherits from its parent. This is the default for every node; all-grey means no access.
YELLOW yesno Read-only. The token can read state but cannot call services that change it.
GREEN yesyes Read and write. The token can read state and call services.
RED nono 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.

Children inherit their parent's grant until something more specific overrides it. RED always wins, even over a GREEN parent.

How a permission is resolved

When a request arrives for an entity, ATM walks the ancestor chain (entity, then device, then domain) twice.

Two-pass resolution: a RED scan, then the nearest non-grey grant Request for an entity PASS 1 Any ancestor set to RED? yes DENY no PASS 2 Nearest non-grey grant GREEN WRITE nearest YELLOW READ nearest NONE NO ACCESS all grey
Pass 1 scans the whole ancestor chain for RED and denies on the first one it finds. Only if the chain is clear does Pass 2 look for the nearest non-grey grant. To the caller, NO ACCESS and DENY are indistinguishable.

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

YELLOWlightevery lightREAD
GREENlight.living_roomescalatesWRITE

Full access to lights, except the guest bedroom

GREENlightall writableWRITE
REDguest bedroom deviceRED winsDENY

Block one noisy sensor inside a permitted device

GREENmedia devicewritableWRITE
REDsensor.signal_strengthexcludedDENY

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.