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:
"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:
PolicyPermissions
Location:homeassistant/auth/permissions/__init__.py:50
Policy-based permissions for regular users:
Policy Structure
Location:homeassistant/auth/permissions/__init__.py:16
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
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:
- Start with empty policy (no access)
- For each group policy, merge permissions
- Use OR logic: if any policy grants a permission, it’s granted
- More specific selectors take precedence
- Group A:
{"domains": {"light": {"read": True}}} - Group B:
{"entity_ids": {"light.bedroom": {"control": True}}}
User Permission Access
Location:homeassistant/auth/models.py:82
Users have a cached permissions property:
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:
- Checks direct entity ID matches first (fastest)
- Checks domain matches
- Looks up entity in registry for area/label matching
- 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
system-users):
- Policy: Read and control access
- For regular users
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:
- Cannot authenticate via cloud connections
- Restricted to local network access
- Useful for guest accounts or limited access users
Best Practices
- Use groups instead of per-user policies
- Start restrictive and grant permissions as needed
- Invalidate cache after permission changes:
- Check permissions before sensitive operations
- Use owner check sparingly - prefer granular permissions
- Test policy changes thoroughly before deployment
- Document custom policies for maintainability
- Use area/label selectors for logical grouping
- Avoid excessive entity_ids - use domains when possible
- 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
Related Components
- Authentication Overview - Core auth concepts
- Authentication Providers - User authentication
- WebSocket API - Permission-aware API