mdb-engine 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. mdb_engine/README.md +144 -0
  2. mdb_engine/__init__.py +37 -0
  3. mdb_engine/auth/README.md +631 -0
  4. mdb_engine/auth/__init__.py +128 -0
  5. mdb_engine/auth/casbin_factory.py +199 -0
  6. mdb_engine/auth/casbin_models.py +46 -0
  7. mdb_engine/auth/config_defaults.py +71 -0
  8. mdb_engine/auth/config_helpers.py +213 -0
  9. mdb_engine/auth/cookie_utils.py +158 -0
  10. mdb_engine/auth/decorators.py +350 -0
  11. mdb_engine/auth/dependencies.py +747 -0
  12. mdb_engine/auth/helpers.py +64 -0
  13. mdb_engine/auth/integration.py +578 -0
  14. mdb_engine/auth/jwt.py +225 -0
  15. mdb_engine/auth/middleware.py +241 -0
  16. mdb_engine/auth/oso_factory.py +323 -0
  17. mdb_engine/auth/provider.py +570 -0
  18. mdb_engine/auth/restrictions.py +271 -0
  19. mdb_engine/auth/session_manager.py +477 -0
  20. mdb_engine/auth/token_lifecycle.py +213 -0
  21. mdb_engine/auth/token_store.py +289 -0
  22. mdb_engine/auth/users.py +1516 -0
  23. mdb_engine/auth/utils.py +614 -0
  24. mdb_engine/cli/__init__.py +13 -0
  25. mdb_engine/cli/commands/__init__.py +7 -0
  26. mdb_engine/cli/commands/generate.py +105 -0
  27. mdb_engine/cli/commands/migrate.py +83 -0
  28. mdb_engine/cli/commands/show.py +70 -0
  29. mdb_engine/cli/commands/validate.py +63 -0
  30. mdb_engine/cli/main.py +41 -0
  31. mdb_engine/cli/utils.py +92 -0
  32. mdb_engine/config.py +217 -0
  33. mdb_engine/constants.py +160 -0
  34. mdb_engine/core/README.md +542 -0
  35. mdb_engine/core/__init__.py +42 -0
  36. mdb_engine/core/app_registration.py +392 -0
  37. mdb_engine/core/connection.py +243 -0
  38. mdb_engine/core/engine.py +749 -0
  39. mdb_engine/core/index_management.py +162 -0
  40. mdb_engine/core/manifest.py +2793 -0
  41. mdb_engine/core/seeding.py +179 -0
  42. mdb_engine/core/service_initialization.py +355 -0
  43. mdb_engine/core/types.py +413 -0
  44. mdb_engine/database/README.md +522 -0
  45. mdb_engine/database/__init__.py +31 -0
  46. mdb_engine/database/abstraction.py +635 -0
  47. mdb_engine/database/connection.py +387 -0
  48. mdb_engine/database/scoped_wrapper.py +1721 -0
  49. mdb_engine/embeddings/README.md +184 -0
  50. mdb_engine/embeddings/__init__.py +62 -0
  51. mdb_engine/embeddings/dependencies.py +193 -0
  52. mdb_engine/embeddings/service.py +759 -0
  53. mdb_engine/exceptions.py +167 -0
  54. mdb_engine/indexes/README.md +651 -0
  55. mdb_engine/indexes/__init__.py +21 -0
  56. mdb_engine/indexes/helpers.py +145 -0
  57. mdb_engine/indexes/manager.py +895 -0
  58. mdb_engine/memory/README.md +451 -0
  59. mdb_engine/memory/__init__.py +30 -0
  60. mdb_engine/memory/service.py +1285 -0
  61. mdb_engine/observability/README.md +515 -0
  62. mdb_engine/observability/__init__.py +42 -0
  63. mdb_engine/observability/health.py +296 -0
  64. mdb_engine/observability/logging.py +161 -0
  65. mdb_engine/observability/metrics.py +297 -0
  66. mdb_engine/routing/README.md +462 -0
  67. mdb_engine/routing/__init__.py +73 -0
  68. mdb_engine/routing/websockets.py +813 -0
  69. mdb_engine/utils/__init__.py +7 -0
  70. mdb_engine-0.1.6.dist-info/METADATA +213 -0
  71. mdb_engine-0.1.6.dist-info/RECORD +75 -0
  72. mdb_engine-0.1.6.dist-info/WHEEL +5 -0
  73. mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
  74. mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
  75. mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,631 @@
1
+ # Authentication & Authorization Module
2
+
3
+ MongoDB-backed authentication and authorization conveniences for MDB_ENGINE applications. The engine provides building blocks (JWT tokens, pluggable authorization providers, session management) without imposing specific authentication flows. Apps implement their own authentication (including OAuth) while leveraging the engine's MongoDB-backed conveniences.
4
+
5
+ ## Philosophy
6
+
7
+ The engine provides **MongoDB-backed conveniences** without imposing solutions:
8
+
9
+ - **Building blocks, not complete solutions**: The engine provides JWT token management, authorization providers (Casbin/OSO), and session management - but apps implement their own authentication flows
10
+ - **MongoDB-first**: All auth data (policies, sessions, tokens) is stored in MongoDB, leveraging the engine's scoping and isolation features
11
+ - **Pluggable authorization**: Choose Casbin (MongoDB-backed RBAC) or OSO (Cloud or library) - both auto-configured from manifest
12
+ - **App-level flexibility**: Apps can implement OAuth, custom auth flows, or use the provided app-level user management utilities
13
+
14
+ ## Features
15
+
16
+ - **JWT Token Management**: Access and refresh token pairs with automatic lifecycle management
17
+ - **Pluggable Authorization**: Support for Casbin (MongoDB-backed) and OSO (Cloud or library) authorization providers
18
+ - **FastAPI Integration**: Ready-to-use dependencies for authentication and authorization
19
+ - **Session Management**: Multi-device session tracking with activity monitoring
20
+ - **Token Blacklisting**: Secure token revocation and expiration handling
21
+ - **App-Level User Management**: Utilities for app-specific user accounts and anonymous sessions
22
+ - **Security Middleware**: Built-in security headers and CSRF protection
23
+ - **Cookie Management**: Secure cookie handling for web applications
24
+
25
+ ## Installation
26
+
27
+ The auth module is part of MDB_ENGINE. No additional installation required, but you may need:
28
+
29
+ ```bash
30
+ pip install pyjwt casbin # For JWT and Casbin support
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ ### Environment Variables
36
+
37
+ ```bash
38
+ # Required: Secret key for JWT signing (must be set, engine will fail to start if missing)
39
+ # Generate a secure key: python -c 'import secrets; print(secrets.token_urlsafe(32))'
40
+ export FLASK_SECRET_KEY="your-secret-key-here"
41
+
42
+ # Optional: Token TTL (seconds)
43
+ export ACCESS_TOKEN_TTL=3600 # Default: 1 hour
44
+ export REFRESH_TOKEN_TTL=2592000 # Default: 30 days
45
+
46
+ # Optional: Session limits
47
+ export MAX_SESSIONS_PER_USER=5
48
+ export SESSION_INACTIVITY_TIMEOUT=86400 # 24 hours
49
+ ```
50
+
51
+ ### Manifest Configuration
52
+
53
+ Configure authentication and authorization in your `manifest.json`. The system automatically creates a Casbin provider with MongoDB-backed policies:
54
+
55
+ ```json
56
+ {
57
+ "slug": "my_app",
58
+ "auth_required": true,
59
+ "auth": {
60
+ "policy": {
61
+ "provider": "casbin",
62
+ "required": true,
63
+ "allow_anonymous": false,
64
+ "authorization": {
65
+ "model": "rbac",
66
+ "policies_collection": "casbin_policies",
67
+ "link_users_roles": true,
68
+ "default_roles": ["user", "admin"]
69
+ }
70
+ },
71
+ "users": {
72
+ "enabled": true,
73
+ "strategy": "app_users"
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ **Key Features:**
80
+ - **Auto-created provider**: Casbin provider is automatically created from manifest (default)
81
+ - **MongoDB-backed**: Policies stored in MongoDB collection (default: `casbin_policies`)
82
+ - **App-level user management**: App-level users automatically get Casbin roles assigned
83
+ - **Zero boilerplate**: Just configure in manifest, everything works automatically
84
+
85
+ **OSO Support**: The engine also supports OSO Cloud and OSO library. Configure `provider: "oso"` in your manifest with OSO Cloud credentials, and the engine will auto-create an OSO adapter just like Casbin.
86
+
87
+ ## Usage
88
+
89
+ ### 1. Unified Auth Setup (Recommended)
90
+
91
+ With the unified auth system, just configure your manifest and call `setup_auth_from_manifest()` - everything is auto-created:
92
+
93
+ ```python
94
+ from mdb_engine.auth import setup_auth_from_manifest
95
+ from fastapi import FastAPI
96
+
97
+ app = FastAPI()
98
+
99
+ @app.on_event("startup")
100
+ async def startup():
101
+ # This automatically:
102
+ # - Creates authorization provider (Casbin or OSO) with MongoDB adapter
103
+ # - Sets up token management
104
+ # - Links app-level users to authorization roles
105
+ # - Configures security middleware
106
+ await setup_auth_from_manifest(app, engine, "my_app")
107
+ ```
108
+
109
+ The authorization provider is automatically available via `get_authz_provider` dependency:
110
+
111
+ ```python
112
+ from mdb_engine.auth import get_authz_provider, get_current_user
113
+ from fastapi import Depends
114
+
115
+ @app.get("/protected")
116
+ async def protected_route(
117
+ user: dict = Depends(get_current_user),
118
+ authz: AuthorizationProvider = Depends(get_authz_provider)
119
+ ):
120
+ # Check permission using auto-created authorization provider (Casbin or OSO)
121
+ has_access = await authz.check(
122
+ subject=user.get("email", "anonymous"),
123
+ resource="my_app",
124
+ action="access"
125
+ )
126
+ if not has_access:
127
+ raise HTTPException(status_code=403, detail="Access denied")
128
+ return {"user_id": user["user_id"]}
129
+ ```
130
+
131
+ ### 2. JWT Token Management
132
+
133
+ #### Generate Token Pairs
134
+
135
+ ```python
136
+ from mdb_engine.auth import generate_token_pair, encode_jwt_token
137
+
138
+ # Generate access + refresh token pair
139
+ access_token, refresh_token = generate_token_pair(
140
+ user_id="user123",
141
+ user_email="user@example.com",
142
+ secret_key=SECRET_KEY
143
+ )
144
+
145
+ # Or encode custom token
146
+ token = encode_jwt_token(
147
+ payload={"user_id": "user123", "role": "admin"},
148
+ secret_key=SECRET_KEY,
149
+ expires_in=3600
150
+ )
151
+ ```
152
+
153
+ #### Decode and Validate Tokens
154
+
155
+ ```python
156
+ from mdb_engine.auth import decode_jwt_token, extract_token_metadata
157
+
158
+ # Decode token
159
+ payload = decode_jwt_token(token, SECRET_KEY)
160
+
161
+ # Extract metadata
162
+ metadata = extract_token_metadata(payload)
163
+ user_id = metadata.get("user_id")
164
+ ```
165
+
166
+ ### 3. FastAPI Dependencies
167
+
168
+ #### Get Current User
169
+
170
+ ```python
171
+ from mdb_engine.auth import get_current_user
172
+ from fastapi import Depends
173
+
174
+ @app.get("/profile")
175
+ async def get_profile(
176
+ user: dict = Depends(get_current_user)
177
+ ):
178
+ if not user:
179
+ raise HTTPException(status_code=401)
180
+ return {"email": user["user_email"]}
181
+ ```
182
+
183
+ #### Require Authentication
184
+
185
+ ```python
186
+ from mdb_engine.auth import require_auth
187
+
188
+ @app.post("/data")
189
+ @require_auth
190
+ async def create_data(
191
+ user: dict = Depends(get_current_user),
192
+ data: dict = None
193
+ ):
194
+ # User is guaranteed to be authenticated here
195
+ return {"created_by": user["user_id"]}
196
+ ```
197
+
198
+ #### Require Admin
199
+
200
+ ```python
201
+ from mdb_engine.auth import require_admin
202
+
203
+ @app.delete("/users/{user_id}")
204
+ async def delete_user(
205
+ user_id: str,
206
+ admin: dict = Depends(require_admin)
207
+ ):
208
+ # Only admins can access this route
209
+ await delete_user_from_db(user_id)
210
+ return {"deleted": user_id}
211
+ ```
212
+
213
+ #### Require Permission
214
+
215
+ ```python
216
+ from mdb_engine.auth import require_permission, get_authz_provider
217
+ from fastapi import Depends
218
+
219
+ @app.post("/documents")
220
+ async def create_document(
221
+ document: dict,
222
+ user: dict = Depends(get_current_user),
223
+ authz: AuthorizationProvider = Depends(get_authz_provider)
224
+ ):
225
+ # Check permission
226
+ has_permission = await require_permission(
227
+ user["user_id"],
228
+ "documents",
229
+ "create",
230
+ authz_provider=authz
231
+ )
232
+
233
+ if not has_permission:
234
+ raise HTTPException(status_code=403, detail="Permission denied")
235
+
236
+ return await create_document_in_db(document)
237
+ ```
238
+
239
+ ### 4. Authorization Providers
240
+
241
+ The engine supports two authorization providers, both auto-configured from manifest:
242
+
243
+ #### Casbin Adapter (Auto-Created from Manifest)
244
+
245
+ **Recommended**: Configure in manifest and let the system auto-create:
246
+
247
+ ```json
248
+ {
249
+ "auth": {
250
+ "policy": {
251
+ "provider": "casbin",
252
+ "authorization": {
253
+ "model": "rbac",
254
+ "policies_collection": "casbin_policies"
255
+ }
256
+ }
257
+ }
258
+ }
259
+ ```
260
+
261
+ The provider is automatically created and available via `get_authz_provider` dependency.
262
+
263
+ **Manual Setup** (if needed):
264
+
265
+ ```python
266
+ from mdb_engine.auth import CasbinAdapter, create_casbin_enforcer
267
+
268
+ # Create enforcer with MongoDB adapter
269
+ enforcer = await create_casbin_enforcer(
270
+ db=engine.get_database(),
271
+ model="rbac",
272
+ policies_collection="casbin_policies"
273
+ )
274
+
275
+ # Create adapter
276
+ authz_provider = CasbinAdapter(enforcer)
277
+
278
+ # Set on app state
279
+ app.state.authz_provider = authz_provider
280
+ ```
281
+
282
+ #### OSO Adapter (Auto-Created from Manifest)
283
+
284
+ **OSO Cloud** (Recommended): Configure in manifest with OSO Cloud credentials:
285
+
286
+ ```json
287
+ {
288
+ "auth": {
289
+ "policy": {
290
+ "provider": "oso",
291
+ "authorization": {
292
+ "api_key": "${OSO_AUTH}",
293
+ "url": "${OSO_URL}",
294
+ "initial_roles": [
295
+ {"user": "admin@example.com", "role": "admin", "resource": "documents"}
296
+ ]
297
+ }
298
+ }
299
+ }
300
+ }
301
+ ```
302
+
303
+ The OSO Cloud provider is automatically created from manifest, just like Casbin.
304
+
305
+ **OSO Library** (Manual Setup):
306
+
307
+ ```python
308
+ from mdb_engine.auth import OsoAdapter
309
+ from oso import Oso
310
+
311
+ # Create OSO instance
312
+ oso = Oso()
313
+ oso.load_file("policy.polar")
314
+
315
+ # Create adapter
316
+ authz_provider = OsoAdapter(oso)
317
+
318
+ # Set on app state
319
+ app.state.authz_provider = authz_provider
320
+
321
+ # Check permission
322
+ allowed = await authz_provider.check(
323
+ subject="user123",
324
+ resource="documents",
325
+ action="read"
326
+ )
327
+ ```
328
+
329
+ ### 5. Session Management
330
+
331
+ ```python
332
+ from mdb_engine.auth import SessionManager
333
+
334
+ # Initialize session manager
335
+ session_mgr = SessionManager(db, collection_name="user_sessions")
336
+ await session_mgr.ensure_indexes()
337
+
338
+ # Create session
339
+ session = await session_mgr.create_session(
340
+ user_id="user123",
341
+ device_id="device456",
342
+ refresh_jti="refresh_token_jti",
343
+ device_info={"ip": "1.2.3.4", "user_agent": "Mozilla/5.0"}
344
+ )
345
+
346
+ # Update session activity
347
+ await session_mgr.update_activity("session_id", "device_id")
348
+
349
+ # Get user sessions
350
+ sessions = await session_mgr.get_user_sessions("user123")
351
+
352
+ # Revoke session
353
+ await session_mgr.revoke_session("session_id")
354
+ ```
355
+
356
+ ### 6. Token Blacklisting
357
+
358
+ ```python
359
+ from mdb_engine.auth import TokenBlacklist
360
+
361
+ # Initialize blacklist
362
+ blacklist = TokenBlacklist(db, collection_name="token_blacklist")
363
+ await blacklist.ensure_indexes()
364
+
365
+ # Blacklist token
366
+ await blacklist.add_token("token_jti", expires_at=datetime.utcnow() + timedelta(hours=1))
367
+
368
+ # Check if token is blacklisted
369
+ is_blacklisted = await blacklist.is_blacklisted("token_jti")
370
+
371
+ # Cleanup expired tokens
372
+ await blacklist.cleanup_expired()
373
+ ```
374
+
375
+ ### 7. Token Lifecycle Management
376
+
377
+ ```python
378
+ from mdb_engine.auth import (
379
+ get_token_expiry_time,
380
+ is_token_expiring_soon,
381
+ should_refresh_token,
382
+ refresh_access_token
383
+ )
384
+
385
+ # Check token expiry
386
+ expiry = get_token_expiry_time(token_payload)
387
+ is_expiring = is_token_expiring_soon(token_payload, threshold_seconds=300)
388
+
389
+ # Refresh token
390
+ if should_refresh_token(refresh_token_payload):
391
+ new_access_token = await refresh_access_token(
392
+ refresh_token=refresh_token,
393
+ secret_key=SECRET_KEY,
394
+ db=db
395
+ )
396
+ ```
397
+
398
+ ### 8. Sub-Authentication (App-Level Users)
399
+
400
+ ```python
401
+ from mdb_engine.auth import (
402
+ create_app_user,
403
+ authenticate_app_user,
404
+ get_app_user,
405
+ get_or_create_anonymous_user
406
+ )
407
+
408
+ # Create app-specific user
409
+ app_user = await create_app_user(
410
+ db=db,
411
+ app_slug="my_app",
412
+ email="user@example.com",
413
+ password="secure_password"
414
+ )
415
+
416
+ # Authenticate app user
417
+ user = await authenticate_app_user(
418
+ db=db,
419
+ app_slug="my_app",
420
+ email="user@example.com",
421
+ password="secure_password"
422
+ )
423
+
424
+ # Get or create anonymous user
425
+ anon_user = await get_or_create_anonymous_user(
426
+ db=db,
427
+ app_slug="my_app",
428
+ device_id="device123"
429
+ )
430
+ ```
431
+
432
+ ### 9. Security Middleware
433
+
434
+ Security middleware is automatically added when using `setup_auth_from_manifest()`. If you need to add it manually:
435
+
436
+ ```python
437
+ from mdb_engine.auth import SecurityMiddleware
438
+
439
+ app.add_middleware(SecurityMiddleware)
440
+ ```
441
+
442
+ ### 10. Cookie Management
443
+
444
+ ```python
445
+ from mdb_engine.auth import (
446
+ set_auth_cookies,
447
+ clear_auth_cookies,
448
+ get_secure_cookie_settings
449
+ )
450
+ from fastapi.responses import Response
451
+
452
+ @app.post("/login")
453
+ async def login(response: Response, credentials: dict):
454
+ # Authenticate user
455
+ user = await authenticate_user(credentials)
456
+
457
+ # Generate tokens
458
+ access_token, refresh_token = generate_token_pair(
459
+ user_id=user["_id"],
460
+ user_email=user["email"],
461
+ secret_key=SECRET_KEY
462
+ )
463
+
464
+ # Set secure cookies
465
+ set_auth_cookies(
466
+ response=response,
467
+ access_token=access_token,
468
+ refresh_token=refresh_token
469
+ )
470
+
471
+ return {"status": "logged_in"}
472
+
473
+ @app.post("/logout")
474
+ async def logout(response: Response):
475
+ clear_auth_cookies(response)
476
+ return {"status": "logged_out"}
477
+ ```
478
+
479
+ ## API Reference
480
+
481
+ ### JWT Functions
482
+
483
+ - `encode_jwt_token(payload, secret_key, expires_in=None)` - Encode JWT token
484
+ - `decode_jwt_token(token, secret_key)` - Decode JWT token
485
+ - `generate_token_pair(user_id, user_email, secret_key)` - Generate access + refresh token pair
486
+ - `extract_token_metadata(payload)` - Extract metadata from token payload
487
+
488
+ ### FastAPI Dependencies
489
+
490
+ - `get_current_user(request, token=None)` - Get current authenticated user
491
+ - `require_admin(request)` - Require admin role
492
+ - `require_admin_or_developer(request)` - Require admin or developer role
493
+ - `require_permission(subject, resource, action, authz_provider)` - Check permission
494
+ - `get_authz_provider(request)` - Get authorization provider
495
+ - `get_token_blacklist(request)` - Get token blacklist
496
+ - `get_session_manager(request)` - Get session manager
497
+
498
+ ### Authorization Providers
499
+
500
+ - `AuthorizationProvider` - Protocol interface for authorization providers
501
+ - `CasbinAdapter(enforcer)` - Casbin authorization adapter
502
+ - `OsoAdapter(oso)` - OSO authorization adapter
503
+
504
+ ### Session Management
505
+
506
+ - `SessionManager(db, collection_name)` - Session manager class
507
+ - `create_session(user_id, device_id, refresh_jti, device_info)` - Create new session
508
+ - `update_activity(session_id, device_id)` - Update session activity
509
+ - `get_user_sessions(user_id)` - Get all sessions for user
510
+ - `revoke_session(session_id)` - Revoke a session
511
+ - `revoke_all_user_sessions(user_id)` - Revoke all user sessions
512
+
513
+ ### Token Management
514
+
515
+ - `TokenBlacklist(db, collection_name)` - Token blacklist class
516
+ - `add_token(jti, expires_at)` - Blacklist a token
517
+ - `is_blacklisted(jti)` - Check if token is blacklisted
518
+ - `cleanup_expired()` - Remove expired tokens
519
+
520
+ ### Token Lifecycle
521
+
522
+ - `get_token_expiry_time(payload)` - Get token expiry time
523
+ - `is_token_expiring_soon(payload, threshold_seconds)` - Check if token expires soon
524
+ - `should_refresh_token(payload)` - Check if token should be refreshed
525
+ - `refresh_access_token(refresh_token, secret_key, db)` - Refresh access token
526
+ - `get_token_age(payload)` - Get token age in seconds
527
+ - `get_time_until_expiry(payload)` - Get time until expiry
528
+
529
+ ### Sub-Authentication
530
+
531
+ - `create_app_user(db, app_slug, email, password, **kwargs)` - Create app user
532
+ - `authenticate_app_user(db, app_slug, email, password)` - Authenticate app user
533
+ - `get_app_user(db, app_slug, user_id)` - Get app-level user
534
+ - `get_or_create_anonymous_user(db, app_slug, device_id)` - Get/create anonymous user
535
+ - `get_or_create_demo_user(db, app_slug, device_id)` - Get/create demo user
536
+
537
+ ### Utilities
538
+
539
+ - `login_user(db, email, password, response)` - Login user and set cookies
540
+ - `register_user(db, email, password, **kwargs)` - Register new user
541
+ - `logout_user(response)` - Logout user and clear cookies
542
+ - `validate_password_strength(password)` - Validate password strength
543
+
544
+ ## Decorators
545
+
546
+ ### `@require_auth`
547
+
548
+ Require authentication for a route:
549
+
550
+ ```python
551
+ from mdb_engine.auth import require_auth
552
+
553
+ @app.post("/data")
554
+ @require_auth
555
+ async def create_data(user: dict = Depends(get_current_user)):
556
+ return {"created_by": user["user_id"]}
557
+ ```
558
+
559
+ ### `@token_security`
560
+
561
+ Add token security checks:
562
+
563
+ ```python
564
+ from mdb_engine.auth import token_security
565
+
566
+ @app.post("/sensitive")
567
+ @token_security
568
+ async def sensitive_operation(user: dict = Depends(get_current_user)):
569
+ return {"data": "sensitive"}
570
+ ```
571
+
572
+ ### `@rate_limit_auth`
573
+
574
+ Rate limit authentication endpoints:
575
+
576
+ ```python
577
+ from mdb_engine.auth import rate_limit_auth
578
+
579
+ @app.post("/login")
580
+ @rate_limit_auth(max_attempts=5, window_seconds=300)
581
+ async def login(credentials: dict):
582
+ return await authenticate(credentials)
583
+ ```
584
+
585
+ ## Best Practices
586
+
587
+ 1. **Always use HTTPS in production** - JWT tokens should only be transmitted over HTTPS
588
+ 2. **Set strong SECRET_KEY (Required)** - The engine requires `FLASK_SECRET_KEY` to be set. Use a cryptographically secure random key (minimum 32 characters). The engine will fail to start if this is not configured.
589
+ 3. **Use token blacklisting** - Implement token revocation for logout and security
590
+ 4. **Monitor sessions** - Track active sessions and clean up inactive ones
591
+ 5. **Implement refresh tokens** - Use refresh tokens for long-lived sessions
592
+ 6. **Validate permissions** - Always check permissions before sensitive operations
593
+ 7. **Use secure cookies** - Enable HttpOnly, Secure, and SameSite flags
594
+ 8. **Handle token expiration** - Implement automatic token refresh
595
+ 9. **Log authentication events** - Track login, logout, and permission failures
596
+ 10. **Use sub-authentication** - Isolate app-level users for multi-tenant applications
597
+
598
+ ## Security Considerations
599
+
600
+ - **Token Storage**: Store tokens in secure, HttpOnly cookies (not localStorage)
601
+ - **CSRF Protection**: Use SameSite cookies and CSRF tokens for state-changing operations
602
+ - **Password Hashing**: Always hash passwords using bcrypt or similar
603
+ - **Rate Limiting**: Implement rate limiting on authentication endpoints
604
+ - **Token Expiration**: Use short-lived access tokens (1 hour) and longer refresh tokens (30 days)
605
+ - **Token Blacklisting**: Implement token blacklisting for immediate revocation
606
+ - **Session Management**: Limit concurrent sessions per user
607
+ - **Device Tracking**: Track devices for security monitoring
608
+
609
+ ## Integration with MongoDBEngine
610
+
611
+ The auth module integrates seamlessly with MongoDBEngine:
612
+
613
+ ```python
614
+ from mdb_engine import MongoDBEngine
615
+ from mdb_engine.auth import setup_auth_from_manifest
616
+
617
+ engine = MongoDBEngine(mongo_uri="...", db_name="...")
618
+ await engine.initialize()
619
+
620
+ manifest = await engine.load_manifest("manifest.json")
621
+ await engine.register_app(manifest)
622
+
623
+ # Setup auth from manifest
624
+ await setup_auth_from_manifest(engine, manifest)
625
+ ```
626
+
627
+ ## Related Modules
628
+
629
+ - **`core/`** - MongoDBEngine integration
630
+ - **`database/`** - Database access for user storage
631
+ - **`observability/`** - Logging and metrics for auth events