diff --git a/docs/auth_index.md b/docs/auth_index.md index 37fd942b..1e1fbea7 100644 --- a/docs/auth_index.md +++ b/docs/auth_index.md @@ -25,21 +25,26 @@ Each person is a user in the system. To log in as a specific user, authenticate ### Owner -The first user to log in to Home Assistant will be marked as the owner. This user is able to manage users. +The user that is created during onboarding will be marked as "owner". The owner is able to manage other users and will always have access to all permissions. -## Clients +## Groups -Clients are applications that users use to access the Home Assistant API. Each client has a client identifier and a redirect uri. The redirect uri is used to redirect the user after it has successfully authorized. +Users are a member of one or more groups. Group membership is how a user is granted permissions. + +## Permission Policy + +This is the permission policy that describes to which resources a group has access. For more information about permissions and policies, see [Permissions](auth_permissions.md). ## Access and refresh tokens -The client will be provided with an authorization code when a user successfully authorizes with Home Assistant. This code can be used to retrieve an access and a refresh token. The access token will have a limited lifetime while refresh tokens will remain valid until a user deletes it. +Applications that want to access Home Assistant will ask the user to start an authorization flow. The flow results in an authorization code when a user successfully authorizes the application with Home Assistant. This code can be used to retrieve an access and a refresh token. The access token will have a limited lifetime while refresh tokens will remain valid until a user deletes it. The access token is used to access the Home Assistant APIs. The refresh token is used to retrieve a new valid access token. ### Refresh token types -Refresh token has 3 different types: -- *Normal*: is generated by a success log in request, and will be sent to user and possessed by user. -- *System*: can only be generated by system user. -- *Long-lived Access Token*: such refresh token is generated by user, but will not delivery to user, however the access token generated by this refresh token will send to user. +There are three different types of refresh tokens: + +- *Normal*: These are the tokens that are generated when a user authorizes an application. The application will hold on to these tokens on behalf of the user. +- *Long-lived Access Token*: These are refresh tokens that back a long lived access token. They are created internally and never exposed to the user. +- *System*: These tokens are limited to be generated and used by system users like Hass.io. They are never exposed to the user. diff --git a/docs/auth_permissions.md b/docs/auth_permissions.md new file mode 100644 index 00000000..c8363901 --- /dev/null +++ b/docs/auth_permissions.md @@ -0,0 +1,91 @@ +--- +title: "Permissions" +--- + +> This is an experimental feature that is not enabled or enforced yet + +Permissions limit the things a user has access to or can control. Permissions are attached to groups, of which a user can be a member. The combined permissions of all groups a user is a member of decides what a user can and cannot see or control. + +Permissions do not apply to the user that is flagged as "owner". This user will always have access to everything. + +## General permission structure + +Policies are dictionaries that at the root level consist of different categories of permissions. In the current implementation this is limited to just entities. + +```python +{ + "entities": … +} +``` + +Each category can further split into subcategories that describe parts of that category. + +```python +{ + "entities": { + "domains": …, + "entity_ids": … + } +} +``` + +If a category is ommitted, the user will not have permission to that category. + +When defining a policy, any dictionary value at any place can be replaced with `True` or `None`. `True` means that permission is granted and `None` means use default, which is deny access. + +## Entities + +Entity permissions can be set on a per entity and per domain basis using the subcategories `entity_ids` and `domains`. Granting access to an entity means a user will be able to read the state and control it. + +If an entity is specified in both the `entity_ids` and `domains` subcategory, the `entity_ids` result will be used, unless it is `None`. In the following example, the user will have access to all light entities except for `light.kitchen`. + +```python +{ + "entities": { + "domains": { + "light": True + }, + "entity_ids": { + "light.kitchen": False + } + } +} +``` + +## Merging policies + +If a user is a member of multiple groups, the groups permission policies will be combined into a single policy at runtime. When merging policies, we will look at each level of the dictionary and compare the values for each source using the following methodology: + +1. If any of the values is `True`, the merged value becomes `True`. +2. If any value is a dictionary, the merged value becomes a dictionary created by recursively checking each value using this methodology. +3. If all values are `None`, the merged value becomes `None`. + +Let's look at an example: + +```python +{ + "entities": { + "entity_ids": { + "light.kitchen": True + } + } +} +``` + +```python +{ + "entities": { + "entity_ids": True + } +} +``` + +Once merged becomes + +```python +{ + "entities": { + "entity_ids": True + } +} +``` diff --git a/website/i18n/en.json b/website/i18n/en.json index 63aca45c..118ef449 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -48,6 +48,9 @@ "title": "Authentication", "sidebar_label": "Introduction" }, + "auth_permissions": { + "title": "Permissions" + }, "config_entries_config_flow_handler": { "title": "Config Flow Handlers" }, diff --git a/website/sidebars.json b/website/sidebars.json index 1a77b797..6447f591 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -25,6 +25,7 @@ ], "Authentication": [ "auth_index", + "auth_permissions", "auth_api", "auth_auth_provider", "auth_auth_module" diff --git a/website/static/img/en/auth/architecture.png b/website/static/img/en/auth/architecture.png index 7e2febcf..e68619f1 100644 Binary files a/website/static/img/en/auth/architecture.png and b/website/static/img/en/auth/architecture.png differ