Skip to main content
The Home Assistant permissions system provides fine-grained access control for users based on their group memberships and policies. The system uses a policy-based approach where permissions are defined in policies attached to groups.

Architecture

Location: homeassistant/auth/permissions/__init__.py The permissions system consists of several key components:
  • Policies: Define what actions are allowed
  • Groups: Collections of users with shared policies
  • Permissions Objects: Evaluate access based on policies
  • Permission Lookup: Provides entity and device metadata for policy evaluation

Permission Classes

AbstractPermissions

Location: homeassistant/auth/permissions/__init__.py:29 Base class for all permission implementations:
Access Keys:
  • "read": View entity state
  • "control": Change entity state
  • "edit": Modify entity configuration

OwnerPermissions

Location: homeassistant/auth/permissions/__init__.py:71 Special permissions object for owners with full access:
Owners have unrestricted access to all resources.

PolicyPermissions

Location: homeassistant/auth/permissions/__init__.py:50 Policy-based permissions for regular users:
Evaluates permissions based on the merged policy from user’s groups.

Policy Structure

Location: homeassistant/auth/permissions/__init__.py:16
Policies are dictionaries with category keys. Currently, only the entities category is supported:

Entity Policy Schema

Location: homeassistant/auth/permissions/entities.py

Policy Selectors

Policies can specify permissions using multiple selectors:

Entity IDs

Direct entity ID matching:

Domains

Match all entities in a domain:

Areas

Match all entities in an area:

Labels

Match all entities with a label:

All Entities

Grant access to all entities:

Permission Lookup

Location: homeassistant/auth/permissions/models.py:14
The PermissionLookup provides access to entity and device registries for resolving area and label memberships during policy evaluation.

System Policies

Location: homeassistant/auth/permissions/system_policies.py Home Assistant defines several built-in system policies:

Admin Policy

Full access to all entities:

User Policy

Read and control access to all entities:

Read-Only Policy

Read-only access to all entities:

Policy Merging

Location: homeassistant/auth/permissions/merge.py When a user belongs to multiple groups, their policies are merged:
Merge strategy:
  1. Start with empty policy (no access)
  2. For each group policy, merge permissions
  3. Use OR logic: if any policy grants a permission, it’s granted
  4. More specific selectors take precedence
Example: User in two groups:
  • Group A: {"domains": {"light": {"read": True}}}
  • Group B: {"entity_ids": {"light.bedroom": {"control": True}}}
Merged policy:

User Permission Access

Location: homeassistant/auth/models.py:82 Users have a cached permissions property:
Important: Call user.invalidate_cache() after modifying groups or policies.

Checking Permissions

Check Entity Access

Check All Entities Access

Owner Check

Admin Check

Location: homeassistant/auth/models.py:92

Policy Compilation

Location: homeassistant/auth/permissions/entities.py For performance, policies are compiled into efficient evaluation functions:
The compiled function:
  1. Checks direct entity ID matches first (fastest)
  2. Checks domain matches
  3. Looks up entity in registry for area/label matching
  4. Falls back to “all” selector

Groups and Policies

Location: homeassistant/auth/auth_store.py

Built-in Groups

Administrators (GROUP_ID_ADMIN: system-admin):
  • Policy: Full access (read, control, edit)
  • For trusted users who manage the system
Users (GROUP_ID_USER: system-users):
  • Policy: Read and control access
  • For regular users
Read Only (GROUP_ID_READ_ONLY: system-read-only):
  • Policy: Read-only access
  • For monitoring/display purposes

Creating Custom Groups

Assigning Users to Groups

Permission Utilities

Location: homeassistant/auth/permissions/util.py

test_all()

WebSocket API Integration

The permissions system integrates with the WebSocket API to filter results:

HTTP API Integration

The HTTP API validates permissions using decorators:

Local-Only Users

Location: homeassistant/auth/models.py:68 Users can be marked as local-only:
Local-only users:
  • Cannot authenticate via cloud connections
  • Restricted to local network access
  • Useful for guest accounts or limited access users

Best Practices

  1. Use groups instead of per-user policies
  2. Start restrictive and grant permissions as needed
  3. Invalidate cache after permission changes:
  4. Check permissions before sensitive operations
  5. Use owner check sparingly - prefer granular permissions
  6. Test policy changes thoroughly before deployment
  7. Document custom policies for maintainability
  8. Use area/label selectors for logical grouping
  9. Avoid excessive entity_ids - use domains when possible
  10. Consider local_only for untrusted users

Performance Considerations

  • Permission checks are cached at the user level
  • Policy compilation happens once per user session
  • Entity function is cached after first use
  • Direct entity ID lookups are fastest
  • Registry lookups (area/label) are slower

Security Notes

  • Owner status cannot be restricted by policies
  • System-generated users have special permission handling
  • Inactive users have no effective permissions
  • Permission changes require cache invalidation
  • Policies use OR logic (permissive merging)

Example: Custom Permission Policy