mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-14 21:06:28 +00:00
Add permissions (#118)
* Add permissions * Mention owner and explain merging
This commit is contained in:
parent
06fc1e7361
commit
887f701a76
@ -25,21 +25,26 @@ Each person is a user in the system. To log in as a specific user, authenticate
|
|||||||
|
|
||||||
### Owner
|
### 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
|
## 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.
|
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 types
|
||||||
|
|
||||||
Refresh token has 3 different types:
|
There are three different types of refresh tokens:
|
||||||
- *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.
|
- *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*: 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.
|
- *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.
|
||||||
|
91
docs/auth_permissions.md
Normal file
91
docs/auth_permissions.md
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -48,6 +48,9 @@
|
|||||||
"title": "Authentication",
|
"title": "Authentication",
|
||||||
"sidebar_label": "Introduction"
|
"sidebar_label": "Introduction"
|
||||||
},
|
},
|
||||||
|
"auth_permissions": {
|
||||||
|
"title": "Permissions"
|
||||||
|
},
|
||||||
"config_entries_config_flow_handler": {
|
"config_entries_config_flow_handler": {
|
||||||
"title": "Config Flow Handlers"
|
"title": "Config Flow Handlers"
|
||||||
},
|
},
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
],
|
],
|
||||||
"Authentication": [
|
"Authentication": [
|
||||||
"auth_index",
|
"auth_index",
|
||||||
|
"auth_permissions",
|
||||||
"auth_api",
|
"auth_api",
|
||||||
"auth_auth_provider",
|
"auth_auth_provider",
|
||||||
"auth_auth_module"
|
"auth_auth_module"
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Loading…
x
Reference in New Issue
Block a user