0
# Authentication & Authorization
1
2
Security framework providing user management, OAuth token handling, multi-factor authentication, and permission-based access control for Home Assistant instances.
3
4
## Capabilities
5
6
### Authentication Manager
7
8
Central authentication system that manages users, tokens, and authentication providers.
9
10
```python { .api }
11
class AuthManager:
12
"""Manage authentication for Home Assistant."""
13
14
def __init__(self, hass: HomeAssistant, store: Store, providers: list,
15
mfa_modules: list):
16
"""Initialize auth manager.
17
18
Args:
19
hass: Home Assistant instance
20
store: Authentication storage
21
providers: Authentication providers
22
mfa_modules: MFA modules
23
"""
24
25
@property
26
def active(self) -> bool:
27
"""Return True if auth is active."""
28
29
@property
30
def support_legacy(self) -> bool:
31
"""Return True if legacy API password is supported."""
32
33
async def async_get_users(self) -> list[User]:
34
"""Get all users.
35
36
Returns:
37
List of users
38
"""
39
40
async def async_get_user(self, user_id: str) -> User:
41
"""Get user by ID.
42
43
Args:
44
user_id: User ID
45
46
Returns:
47
User or None if not found
48
"""
49
50
async def async_get_owner(self) -> User:
51
"""Get owner user.
52
53
Returns:
54
Owner user
55
"""
56
57
async def async_create_system_user(self, name: str, *, group_ids: list[str] = None,
58
local_only: bool = None) -> User:
59
"""Create system user.
60
61
Args:
62
name: User name
63
group_ids: Group IDs
64
local_only: Local only access
65
66
Returns:
67
Created user
68
"""
69
70
async def async_create_user(self, name: str, *, group_ids: list[str] = None,
71
local_only: bool = None) -> User:
72
"""Create user.
73
74
Args:
75
name: User name
76
group_ids: Group IDs
77
local_only: Local only access
78
79
Returns:
80
Created user
81
"""
82
83
async def async_remove_user(self, user: User) -> None:
84
"""Remove user.
85
86
Args:
87
user: User to remove
88
"""
89
90
async def async_update_user(self, user: User, *, name: str = None,
91
is_active: bool = None, group_ids: list[str] = None,
92
local_only: bool = None) -> User:
93
"""Update user.
94
95
Args:
96
user: User to update
97
name: New name
98
is_active: Active status
99
group_ids: Group IDs
100
local_only: Local only access
101
102
Returns:
103
Updated user
104
"""
105
106
async def async_activate_user(self, user: User) -> None:
107
"""Activate user.
108
109
Args:
110
user: User to activate
111
"""
112
113
async def async_deactivate_user(self, user: User) -> None:
114
"""Deactivate user.
115
116
Args:
117
user: User to deactivate
118
"""
119
120
async def async_create_refresh_token(self, user: User, client_id: str = None,
121
client_name: str = None,
122
client_icon: str = None,
123
token_type: str = None,
124
access_token_expiration: timedelta = None) -> RefreshToken:
125
"""Create refresh token.
126
127
Args:
128
user: User for token
129
client_id: Client ID
130
client_name: Client name
131
client_icon: Client icon
132
token_type: Token type
133
access_token_expiration: Access token expiration
134
135
Returns:
136
Created refresh token
137
"""
138
139
async def async_get_refresh_token(self, token_id: str) -> RefreshToken:
140
"""Get refresh token by ID.
141
142
Args:
143
token_id: Token ID
144
145
Returns:
146
Refresh token or None
147
"""
148
149
async def async_get_refresh_token_by_token(self, token: str) -> RefreshToken:
150
"""Get refresh token by token value.
151
152
Args:
153
token: Token value
154
155
Returns:
156
Refresh token or None
157
"""
158
159
async def async_remove_refresh_token(self, refresh_token: RefreshToken) -> None:
160
"""Remove refresh token.
161
162
Args:
163
refresh_token: Token to remove
164
"""
165
166
async def async_validate_access_token(self, token: str) -> AccessToken:
167
"""Validate access token.
168
169
Args:
170
token: Access token
171
172
Returns:
173
Access token object or None if invalid
174
"""
175
176
async def async_create_access_token(self, refresh_token: RefreshToken,
177
remote_ip: str = None) -> str:
178
"""Create access token.
179
180
Args:
181
refresh_token: Refresh token
182
remote_ip: Remote IP address
183
184
Returns:
185
Access token string
186
"""
187
```
188
189
### User Management
190
191
User account management including creation, modification, and permission handling.
192
193
```python { .api }
194
class User:
195
"""User account information."""
196
197
def __init__(self, name: str, perm_lookup: PermissionLookup, id: str = None,
198
is_owner: bool = False, is_active: bool = True,
199
system_generated: bool = False, local_only: bool = False,
200
group_ids: list[str] = None):
201
"""Initialize user.
202
203
Args:
204
name: User name
205
perm_lookup: Permission lookup
206
id: User ID
207
is_owner: Is owner user
208
is_active: Is active user
209
system_generated: Is system generated
210
local_only: Local only access
211
group_ids: Group IDs
212
"""
213
214
@property
215
def id(self) -> str:
216
"""Return user ID."""
217
218
@property
219
def name(self) -> str:
220
"""Return user name."""
221
222
@property
223
def is_owner(self) -> bool:
224
"""Return True if user is owner."""
225
226
@property
227
def is_active(self) -> bool:
228
"""Return True if user is active."""
229
230
@property
231
def system_generated(self) -> bool:
232
"""Return True if user is system generated."""
233
234
@property
235
def local_only(self) -> bool:
236
"""Return True if user has local only access."""
237
238
@property
239
def groups(self) -> list[Group]:
240
"""Return user groups."""
241
242
@property
243
def permissions(self) -> AbstractPermissions:
244
"""Return user permissions."""
245
246
def in_group(self, group_id: str) -> bool:
247
"""Check if user is in group.
248
249
Args:
250
group_id: Group ID
251
252
Returns:
253
True if user is in group
254
"""
255
256
class Group:
257
"""User group for permission management."""
258
259
def __init__(self, name: str, policy: PolicyType, id: str = None):
260
"""Initialize group.
261
262
Args:
263
name: Group name
264
policy: Group policy
265
id: Group ID
266
"""
267
268
@property
269
def id(self) -> str:
270
"""Return group ID."""
271
272
@property
273
def name(self) -> str:
274
"""Return group name."""
275
276
@property
277
def policy(self) -> PolicyType:
278
"""Return group policy."""
279
```
280
281
### Token Management
282
283
OAuth token system for authentication and authorization with refresh and access tokens.
284
285
```python { .api }
286
class RefreshToken:
287
"""Refresh token for OAuth authentication."""
288
289
def __init__(self, user: User, client_id: str, access_token_expiration: timedelta,
290
client_name: str = None, client_icon: str = None,
291
token_type: str = None, id: str = None, jwt_key: str = None,
292
last_used_at: datetime = None, last_used_ip: str = None,
293
credential: Credentials = None, version: str = None):
294
"""Initialize refresh token.
295
296
Args:
297
user: Token user
298
client_id: Client ID
299
access_token_expiration: Access token expiration
300
client_name: Client name
301
client_icon: Client icon
302
token_type: Token type
303
id: Token ID
304
jwt_key: JWT key
305
last_used_at: Last used timestamp
306
last_used_ip: Last used IP
307
credential: Associated credential
308
version: Token version
309
"""
310
311
@property
312
def id(self) -> str:
313
"""Return token ID."""
314
315
@property
316
def user(self) -> User:
317
"""Return token user."""
318
319
@property
320
def client_id(self) -> str:
321
"""Return client ID."""
322
323
@property
324
def client_name(self) -> str:
325
"""Return client name."""
326
327
@property
328
def client_icon(self) -> str:
329
"""Return client icon."""
330
331
@property
332
def token_type(self) -> str:
333
"""Return token type."""
334
335
@property
336
def access_token_expiration(self) -> timedelta:
337
"""Return access token expiration."""
338
339
@property
340
def jwt_key(self) -> str:
341
"""Return JWT key."""
342
343
@property
344
def last_used_at(self) -> datetime:
345
"""Return last used timestamp."""
346
347
@property
348
def last_used_ip(self) -> str:
349
"""Return last used IP."""
350
351
@property
352
def credential(self) -> Credentials:
353
"""Return associated credential."""
354
355
@property
356
def version(self) -> str:
357
"""Return token version."""
358
359
class AccessToken:
360
"""Access token for API authentication."""
361
362
def __init__(self, refresh_token: RefreshToken):
363
"""Initialize access token.
364
365
Args:
366
refresh_token: Associated refresh token
367
"""
368
369
@property
370
def refresh_token(self) -> RefreshToken:
371
"""Return refresh token."""
372
373
@property
374
def scopes(self) -> list[str]:
375
"""Return token scopes."""
376
```
377
378
### Authentication Providers
379
380
Pluggable authentication providers for different authentication methods.
381
382
```python { .api }
383
class AuthProvider:
384
"""Base authentication provider."""
385
386
DEFAULT_TITLE = None
387
388
def __init__(self, hass: HomeAssistant, store: Store, config: dict):
389
"""Initialize auth provider.
390
391
Args:
392
hass: Home Assistant instance
393
store: Provider storage
394
config: Provider configuration
395
"""
396
397
@property
398
def id(self) -> str:
399
"""Return provider ID."""
400
401
@property
402
def name(self) -> str:
403
"""Return provider name."""
404
405
@property
406
def type(self) -> str:
407
"""Return provider type."""
408
409
@property
410
def support_mfa(self) -> bool:
411
"""Return True if provider supports MFA."""
412
413
async def async_login_flow(self, context: dict) -> LoginFlow:
414
"""Return login flow.
415
416
Args:
417
context: Login context
418
419
Returns:
420
Login flow
421
"""
422
423
async def async_get_or_create_credentials(self, flow_result: dict) -> Credentials:
424
"""Get or create credentials from flow result.
425
426
Args:
427
flow_result: Login flow result
428
429
Returns:
430
User credentials
431
"""
432
433
async def async_user_meta_for_credentials(self, credentials: Credentials) -> UserMeta:
434
"""Return user metadata for credentials.
435
436
Args:
437
credentials: User credentials
438
439
Returns:
440
User metadata
441
"""
442
443
class Credentials:
444
"""User credentials from authentication provider."""
445
446
def __init__(self, auth_provider_type: str, auth_provider_id: str,
447
data: dict, id: str = None, is_new: bool = True):
448
"""Initialize credentials.
449
450
Args:
451
auth_provider_type: Provider type
452
auth_provider_id: Provider ID
453
data: Credential data
454
id: Credential ID
455
is_new: Is new credential
456
"""
457
458
@property
459
def id(self) -> str:
460
"""Return credential ID."""
461
462
@property
463
def auth_provider_type(self) -> str:
464
"""Return provider type."""
465
466
@property
467
def auth_provider_id(self) -> str:
468
"""Return provider ID."""
469
470
@property
471
def data(self) -> dict:
472
"""Return credential data."""
473
474
@property
475
def is_new(self) -> bool:
476
"""Return True if credential is new."""
477
```
478
479
### Multi-Factor Authentication
480
481
Multi-factor authentication system with pluggable MFA modules.
482
483
```python { .api }
484
class MfaModule:
485
"""Base multi-factor authentication module."""
486
487
DEFAULT_TITLE = None
488
489
def __init__(self, hass: HomeAssistant, config: dict):
490
"""Initialize MFA module.
491
492
Args:
493
hass: Home Assistant instance
494
config: Module configuration
495
"""
496
497
@property
498
def id(self) -> str:
499
"""Return module ID."""
500
501
@property
502
def name(self) -> str:
503
"""Return module name."""
504
505
async def async_setup_flow(self, user_id: str) -> SetupFlow:
506
"""Return setup flow.
507
508
Args:
509
user_id: User ID
510
511
Returns:
512
Setup flow
513
"""
514
515
async def async_setup_user(self, user_id: str, setup_data: Any) -> str:
516
"""Set up MFA for user.
517
518
Args:
519
user_id: User ID
520
setup_data: Setup data
521
522
Returns:
523
Setup ID
524
"""
525
526
async def async_depose_user(self, user_id: str) -> None:
527
"""Remove MFA for user.
528
529
Args:
530
user_id: User ID
531
"""
532
533
async def async_is_user_setup(self, user_id: str) -> bool:
534
"""Check if user has MFA setup.
535
536
Args:
537
user_id: User ID
538
539
Returns:
540
True if user has MFA setup
541
"""
542
543
async def async_validation_flow(self, user_id: str, context: dict) -> ValidationFlow:
544
"""Return validation flow.
545
546
Args:
547
user_id: User ID
548
context: Validation context
549
550
Returns:
551
Validation flow
552
"""
553
554
async def async_validate(self, user_id: str, data: dict) -> bool:
555
"""Validate MFA.
556
557
Args:
558
user_id: User ID
559
data: Validation data
560
561
Returns:
562
True if validation successful
563
"""
564
```
565
566
## Authentication Constants
567
568
```python { .api }
569
# Token types
570
TOKEN_TYPE_NORMAL = "normal"
571
TOKEN_TYPE_SYSTEM = "system"
572
TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN = "long_lived_access_token"
573
574
# Authentication provider types
575
AUTH_PROVIDER_HOMEASSISTANT = "homeassistant"
576
AUTH_PROVIDER_LEGACY_API_PASSWORD = "legacy_api_password"
577
AUTH_PROVIDER_TRUSTED_NETWORKS = "trusted_networks"
578
AUTH_PROVIDER_COMMAND_LINE = "command_line"
579
580
# MFA module types
581
MFA_MODULE_TOTP = "totp"
582
MFA_MODULE_NOTIFY = "notify"
583
584
# Permission categories
585
CAT_ENTITIES = "entities"
586
CAT_CONFIG_ENTRIES = "config_entries"
587
CAT_AREAS = "areas"
588
CAT_DEVICES = "devices"
589
590
# Permission types
591
POLICY_READ = "read"
592
POLICY_CONTROL = "control"
593
POLICY_EDIT = "edit"
594
POLICY_ADMIN = "admin"
595
596
# Group IDs
597
GROUP_ID_ADMIN = "system-admin"
598
GROUP_ID_USER = "system-users"
599
GROUP_ID_READ_ONLY = "system-read-only"
600
```
601
602
## Types
603
604
```python { .api }
605
from typing import Any, Dict, List, Optional, Union
606
from datetime import datetime, timedelta
607
608
# User types
609
UserType = Dict[str, Any]
610
GroupType = Dict[str, Any]
611
PermissionType = Dict[str, Any]
612
PolicyType = Dict[str, Any]
613
614
# Token types
615
RefreshTokenType = Dict[str, Any]
616
AccessTokenType = str
617
TokenDataType = Dict[str, Any]
618
619
# Authentication types
620
CredentialsType = Dict[str, Any]
621
UserMetaType = Dict[str, Any]
622
LoginFlowType = Any
623
SetupFlowType = Any
624
ValidationFlowType = Any
625
626
# Permission types
627
AbstractPermissions = Any
628
PermissionLookup = Any
629
```