mdb-engine 0.1.6__py3-none-any.whl → 0.1.7__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/__init__.py +38 -6
  2. mdb_engine/auth/README.md +534 -11
  3. mdb_engine/auth/__init__.py +129 -28
  4. mdb_engine/auth/audit.py +592 -0
  5. mdb_engine/auth/casbin_factory.py +10 -14
  6. mdb_engine/auth/config_helpers.py +7 -6
  7. mdb_engine/auth/cookie_utils.py +3 -7
  8. mdb_engine/auth/csrf.py +373 -0
  9. mdb_engine/auth/decorators.py +3 -10
  10. mdb_engine/auth/dependencies.py +37 -45
  11. mdb_engine/auth/helpers.py +3 -3
  12. mdb_engine/auth/integration.py +30 -73
  13. mdb_engine/auth/jwt.py +2 -6
  14. mdb_engine/auth/middleware.py +77 -34
  15. mdb_engine/auth/oso_factory.py +16 -36
  16. mdb_engine/auth/provider.py +17 -38
  17. mdb_engine/auth/rate_limiter.py +504 -0
  18. mdb_engine/auth/restrictions.py +8 -24
  19. mdb_engine/auth/session_manager.py +14 -29
  20. mdb_engine/auth/shared_middleware.py +600 -0
  21. mdb_engine/auth/shared_users.py +759 -0
  22. mdb_engine/auth/token_store.py +14 -28
  23. mdb_engine/auth/users.py +54 -113
  24. mdb_engine/auth/utils.py +213 -15
  25. mdb_engine/cli/commands/generate.py +545 -9
  26. mdb_engine/cli/commands/validate.py +3 -7
  27. mdb_engine/cli/utils.py +3 -3
  28. mdb_engine/config.py +7 -21
  29. mdb_engine/constants.py +65 -0
  30. mdb_engine/core/README.md +117 -6
  31. mdb_engine/core/__init__.py +39 -7
  32. mdb_engine/core/app_registration.py +22 -41
  33. mdb_engine/core/app_secrets.py +290 -0
  34. mdb_engine/core/connection.py +18 -9
  35. mdb_engine/core/encryption.py +223 -0
  36. mdb_engine/core/engine.py +758 -95
  37. mdb_engine/core/index_management.py +12 -16
  38. mdb_engine/core/manifest.py +424 -135
  39. mdb_engine/core/ray_integration.py +435 -0
  40. mdb_engine/core/seeding.py +10 -18
  41. mdb_engine/core/service_initialization.py +12 -23
  42. mdb_engine/core/types.py +2 -5
  43. mdb_engine/database/README.md +112 -16
  44. mdb_engine/database/__init__.py +17 -6
  45. mdb_engine/database/abstraction.py +25 -37
  46. mdb_engine/database/connection.py +11 -18
  47. mdb_engine/database/query_validator.py +367 -0
  48. mdb_engine/database/resource_limiter.py +204 -0
  49. mdb_engine/database/scoped_wrapper.py +713 -196
  50. mdb_engine/embeddings/__init__.py +17 -9
  51. mdb_engine/embeddings/dependencies.py +1 -3
  52. mdb_engine/embeddings/service.py +11 -25
  53. mdb_engine/exceptions.py +92 -0
  54. mdb_engine/indexes/README.md +30 -13
  55. mdb_engine/indexes/__init__.py +1 -0
  56. mdb_engine/indexes/helpers.py +1 -1
  57. mdb_engine/indexes/manager.py +50 -114
  58. mdb_engine/memory/README.md +2 -2
  59. mdb_engine/memory/__init__.py +1 -2
  60. mdb_engine/memory/service.py +30 -87
  61. mdb_engine/observability/README.md +4 -2
  62. mdb_engine/observability/__init__.py +26 -9
  63. mdb_engine/observability/health.py +8 -9
  64. mdb_engine/observability/metrics.py +32 -12
  65. mdb_engine/routing/README.md +1 -1
  66. mdb_engine/routing/__init__.py +1 -3
  67. mdb_engine/routing/websockets.py +25 -60
  68. mdb_engine-0.1.7.dist-info/METADATA +285 -0
  69. mdb_engine-0.1.7.dist-info/RECORD +85 -0
  70. mdb_engine-0.1.6.dist-info/METADATA +0 -213
  71. mdb_engine-0.1.6.dist-info/RECORD +0 -75
  72. {mdb_engine-0.1.6.dist-info → mdb_engine-0.1.7.dist-info}/WHEEL +0 -0
  73. {mdb_engine-0.1.6.dist-info → mdb_engine-0.1.7.dist-info}/entry_points.txt +0 -0
  74. {mdb_engine-0.1.6.dist-info → mdb_engine-0.1.7.dist-info}/licenses/LICENSE +0 -0
  75. {mdb_engine-0.1.6.dist-info → mdb_engine-0.1.7.dist-info}/top_level.txt +0 -0
mdb_engine/__init__.py CHANGED
@@ -3,29 +3,61 @@ MDB_ENGINE - MongoDB Engine
3
3
 
4
4
  Enterprise-grade engine for building applications
5
5
  with automatic database scoping, authentication, and resource management.
6
+
7
+ Usage:
8
+ # Simple usage
9
+ from mdb_engine import MongoDBEngine
10
+ engine = MongoDBEngine(mongo_uri=..., db_name=...)
11
+ await engine.initialize()
12
+ db = engine.get_scoped_db("my_app")
13
+
14
+ # With FastAPI integration
15
+ app = engine.create_app(slug="my_app", manifest=Path("manifest.json"))
16
+
17
+ # With Ray support (optional)
18
+ engine = MongoDBEngine(..., enable_ray=True)
6
19
  """
7
20
 
8
21
  # Authentication
9
22
  from .auth import AuthorizationProvider, get_current_user, require_admin
23
+
24
+ # Optional Ray integration
10
25
  # Core MongoDB Engine
11
- from .core import ManifestParser, ManifestValidator, MongoDBEngine
26
+ from .core import (
27
+ RAY_AVAILABLE,
28
+ AppRayActor,
29
+ ManifestParser,
30
+ ManifestValidator,
31
+ MongoDBEngine,
32
+ get_ray_actor_handle,
33
+ ray_actor_decorator,
34
+ )
35
+
12
36
  # Database layer
13
- from .database import AppDB, ScopedMongoWrapper, get_shared_mongo_client
37
+ from .database import AppDB, ScopedMongoWrapper
38
+
14
39
  # Index management
15
- from .indexes import (AsyncAtlasIndexManager, AutoIndexManager,
16
- run_index_creation_for_collection)
40
+ from .indexes import (
41
+ AsyncAtlasIndexManager,
42
+ AutoIndexManager,
43
+ run_index_creation_for_collection,
44
+ )
17
45
 
18
46
  __version__ = "0.1.6"
19
47
 
20
48
  __all__ = [
21
- # Core
49
+ # Core (includes FastAPI integration and optional Ray)
22
50
  "MongoDBEngine",
23
51
  "ManifestValidator",
24
52
  "ManifestParser",
53
+ # Ray Integration (optional - only active if Ray installed)
54
+ "RAY_AVAILABLE",
55
+ "AppRayActor",
56
+ "get_ray_actor_handle",
57
+ "ray_actor_decorator",
25
58
  # Database
26
59
  "ScopedMongoWrapper",
27
60
  "AppDB",
28
- "get_shared_mongo_client",
29
61
  # Auth
30
62
  "AuthorizationProvider",
31
63
  "get_current_user",
mdb_engine/auth/README.md CHANGED
@@ -10,6 +10,76 @@ The engine provides **MongoDB-backed conveniences** without imposing solutions:
10
10
  - **MongoDB-first**: All auth data (policies, sessions, tokens) is stored in MongoDB, leveraging the engine's scoping and isolation features
11
11
  - **Pluggable authorization**: Choose Casbin (MongoDB-backed RBAC) or OSO (Cloud or library) - both auto-configured from manifest
12
12
  - **App-level flexibility**: Apps can implement OAuth, custom auth flows, or use the provided app-level user management utilities
13
+ - **Two auth modes**: Choose between per-app isolation (`mode: "app"`) or shared user pool with SSO (`mode: "shared"`)
14
+
15
+ ## Auth Modes
16
+
17
+ MDB_ENGINE supports two authentication modes, configured in manifest.json:
18
+
19
+ ### Per-App Auth (`mode: "app"`) - Default
20
+
21
+ Each app has isolated authentication. Users, tokens, and sessions are specific to each app.
22
+
23
+ ```json
24
+ {
25
+ "auth": {
26
+ "mode": "app",
27
+ "token_required": true
28
+ }
29
+ }
30
+ ```
31
+
32
+ **When to use:**
33
+ - Apps are independent
34
+ - Each app manages its own users
35
+ - No need for SSO between apps
36
+
37
+ ### Shared Auth (`mode: "shared"`) - SSO
38
+
39
+ All apps share a central user pool. Users authenticate once and can access any app (subject to role requirements).
40
+
41
+ ```json
42
+ {
43
+ "auth": {
44
+ "mode": "shared",
45
+ "roles": ["viewer", "editor", "admin"],
46
+ "default_role": "viewer",
47
+ "require_role": "viewer",
48
+ "public_routes": ["/health", "/api/public"]
49
+ }
50
+ }
51
+ ```
52
+
53
+ **When to use:**
54
+ - Building a platform with multiple related apps
55
+ - You want Single Sign-On (SSO)
56
+ - You need per-app role management
57
+ - Apps should share user identity
58
+
59
+ **Shared auth fields:**
60
+ | Field | Description |
61
+ |-------|-------------|
62
+ | `roles` | Available roles for this app |
63
+ | `default_role` | Role assigned to new users |
64
+ | `require_role` | Minimum role required to access app |
65
+ | `public_routes` | Routes that don't require authentication |
66
+
67
+ **How it works:**
68
+ 1. Users are stored in `_mdb_engine_shared_users` collection
69
+ 2. JWT tokens work across all apps (SSO)
70
+ 3. `SharedAuthMiddleware` is auto-configured by `engine.create_app()`
71
+ 4. User info is available via `request.state.user`
72
+
73
+ ```python
74
+ # Accessing user in shared auth mode
75
+ @app.get("/protected")
76
+ async def protected(request: Request):
77
+ user = request.state.user # Populated by middleware
78
+ roles = request.state.user_roles
79
+ return {"email": user["email"], "roles": roles}
80
+ ```
81
+
82
+ See `examples/multi_app_shared/` for a complete SSO example.
13
83
 
14
84
  ## Features
15
85
 
@@ -265,11 +335,12 @@ The provider is automatically created and available via `get_authz_provider` dep
265
335
  ```python
266
336
  from mdb_engine.auth import CasbinAdapter, create_casbin_enforcer
267
337
 
268
- # Create enforcer with MongoDB adapter
338
+ # Create enforcer with MongoDB adapter (uses scoped database)
339
+ db = engine.get_scoped_db("my_app")
269
340
  enforcer = await create_casbin_enforcer(
270
- db=engine.get_database(),
341
+ db=db,
271
342
  model="rbac",
272
- policies_collection="casbin_policies"
343
+ policies_collection="casbin_policies" # Will be app-scoped
273
344
  )
274
345
 
275
346
  # Create adapter
@@ -534,12 +605,70 @@ async def logout(response: Response):
534
605
  - `get_or_create_anonymous_user(db, app_slug, device_id)` - Get/create anonymous user
535
606
  - `get_or_create_demo_user(db, app_slug, device_id)` - Get/create demo user
536
607
 
608
+ ### Shared Auth (SSO)
609
+
610
+ - `SharedUserPool(mongo_db, jwt_secret, jwt_public_key, jwt_algorithm, ...)` - Shared user pool for SSO
611
+ - `create_user(email, password, app_roles)` - Create user in shared pool
612
+ - `authenticate(email, password, ip_address, fingerprint, session_binding)` - Authenticate with session binding
613
+ - `validate_token(token)` - Validate JWT and get user (checks blacklist)
614
+ - `revoke_token(token, reason)` - Revoke token by adding JTI to blacklist
615
+ - `revoke_all_user_tokens(user_id, reason)` - Revoke all user tokens
616
+ - `update_user_roles(email, app_slug, roles)` - Update user's roles for an app
617
+ - `user_has_role(user, app_slug, role)` - Check if user has role
618
+ - `get_secure_cookie_config(request)` - Get secure cookie settings
619
+ - `jwt_algorithm` - Property: configured algorithm (HS256, RS256, ES256)
620
+ - `is_asymmetric` - Property: True if using asymmetric algorithm
621
+ - `JWTSecretError` - Raised when JWT secret is missing
622
+ - `JWTKeyError` - Raised when JWT key configuration is invalid
623
+ - `SharedAuthMiddleware` - ASGI middleware for shared auth (supports session binding)
624
+ - `create_shared_auth_middleware(pool, slug, manifest_auth)` - Factory for configured middleware
625
+ - `create_shared_auth_middleware_lazy(slug, manifest_auth)` - Lazy factory for engine integration
626
+
627
+ ### Rate Limiting
628
+
629
+ - `AuthRateLimitMiddleware(app, limits, store)` - ASGI rate limiting middleware
630
+ - `RateLimit(max_attempts, window_seconds)` - Rate limit configuration
631
+ - `InMemoryRateLimitStore` - In-memory storage for rate limiting
632
+ - `MongoDBRateLimitStore(db)` - MongoDB-backed distributed rate limiting
633
+ - `create_rate_limit_middleware(manifest_auth, store)` - Factory from manifest config
634
+ - `@rate_limit(max_attempts, window_seconds)` - Decorator for individual endpoints
635
+
636
+ ### Audit Logging
637
+
638
+ - `AuthAuditLog(mongo_db, retention_days=90)` - Audit logger for auth events
639
+ - `log_event(action, success, user_email, ip_address, details)` - Log any event
640
+ - `log_login_success(email, ip_address, ...)` - Log successful login
641
+ - `log_login_failed(email, reason, ip_address, ...)` - Log failed login
642
+ - `log_logout(email, ip_address, ...)` - Log logout
643
+ - `log_register(email, ip_address, ...)` - Log registration
644
+ - `log_role_change(email, app_slug, old_roles, new_roles, ...)` - Log role change
645
+ - `log_token_revoked(email, reason, ...)` - Log token revocation
646
+ - `get_recent_events(hours, action, success)` - Query recent events
647
+ - `get_failed_logins(email, ip_address, hours)` - Query failed logins
648
+ - `get_security_summary(hours)` - Get security statistics
649
+ - `AuthAction` - Enum of audit action types
650
+
651
+ ### CSRF Protection
652
+
653
+ - `CSRFMiddleware(app, secret, exempt_routes, ...)` - CSRF protection middleware
654
+ - `create_csrf_middleware(manifest_auth)` - Factory from manifest config
655
+ - `generate_csrf_token(secret)` - Generate CSRF token
656
+ - `validate_csrf_token(token, secret, max_age)` - Validate CSRF token
657
+ - `get_csrf_token(request)` - FastAPI dependency for getting CSRF token
658
+
659
+ ### Password Policy
660
+
661
+ - `validate_password_strength(password, config)` - Validate password strength
662
+ - `validate_password_strength_async(password, config, check_breaches)` - Async validation with breach check
663
+ - `calculate_password_entropy(password)` - Calculate entropy in bits
664
+ - `is_common_password(password)` - Check against common password list
665
+ - `check_password_breach(password)` - Check against HaveIBeenPwned (async)
666
+
537
667
  ### Utilities
538
668
 
539
669
  - `login_user(db, email, password, response)` - Login user and set cookies
540
670
  - `register_user(db, email, password, **kwargs)` - Register new user
541
671
  - `logout_user(response)` - Logout user and clear cookies
542
- - `validate_password_strength(password)` - Validate password strength
543
672
 
544
673
  ## Decorators
545
674
 
@@ -595,16 +724,410 @@ async def login(credentials: dict):
595
724
  9. **Log authentication events** - Track login, logout, and permission failures
596
725
  10. **Use sub-authentication** - Isolate app-level users for multi-tenant applications
597
726
 
727
+ ## Enterprise Security Features
728
+
729
+ MDB_ENGINE auth includes enterprise-grade security features for production deployments.
730
+
731
+ ### JWT Secret Validation (Fail-Fast)
732
+
733
+ The `SharedUserPool` now **requires** a JWT secret - it will fail at startup if not configured:
734
+
735
+ ```python
736
+ from mdb_engine.auth import SharedUserPool, JWTSecretError
737
+
738
+ # Production: Requires MDB_ENGINE_JWT_SECRET env var or explicit secret
739
+ try:
740
+ pool = SharedUserPool(db) # Will raise JWTSecretError if no secret
741
+ except JWTSecretError:
742
+ print("Set MDB_ENGINE_JWT_SECRET environment variable!")
743
+
744
+ # Development: Use allow_insecure_dev for local testing (NOT for production!)
745
+ pool = SharedUserPool(db, allow_insecure_dev=True) # Auto-generates ephemeral secret
746
+ ```
747
+
748
+ **Generate a secure secret:**
749
+ ```bash
750
+ python -c "import secrets; print(secrets.token_urlsafe(32))"
751
+ ```
752
+
753
+ ### Token Revocation (JTI)
754
+
755
+ Tokens now include a unique JWT ID (JTI) that enables server-side revocation:
756
+
757
+ ```python
758
+ # Revoke a specific token (e.g., on logout)
759
+ await user_pool.revoke_token(token, reason="logout")
760
+
761
+ # Token is now blacklisted and will fail validation
762
+ user = await user_pool.validate_token(token) # Returns None
763
+
764
+ # Revoke all user tokens (e.g., password change)
765
+ await user_pool.revoke_all_user_tokens(user_id, reason="password_change")
766
+ ```
767
+
768
+ **How it works:**
769
+ - Each token contains a `jti` (JWT ID) claim
770
+ - `revoke_token()` adds the JTI to a blacklist collection
771
+ - `validate_token()` checks the blacklist before accepting the token
772
+ - Blacklist entries auto-expire via MongoDB TTL index
773
+
774
+ ### Rate Limiting
775
+
776
+ Protect auth endpoints from brute-force attacks with built-in rate limiting:
777
+
778
+ **Manifest Configuration:**
779
+ ```json
780
+ {
781
+ "auth": {
782
+ "mode": "shared",
783
+ "rate_limits": {
784
+ "/login": {"max_attempts": 5, "window_seconds": 300},
785
+ "/register": {"max_attempts": 3, "window_seconds": 3600}
786
+ }
787
+ }
788
+ }
789
+ ```
790
+
791
+ **Programmatic Usage:**
792
+ ```python
793
+ from mdb_engine.auth import AuthRateLimitMiddleware, RateLimit, rate_limit
794
+
795
+ # Via middleware (auto-configured by engine.create_app())
796
+ app.add_middleware(
797
+ AuthRateLimitMiddleware,
798
+ limits={"/login": RateLimit(max_attempts=5, window_seconds=300)}
799
+ )
800
+
801
+ # Via decorator
802
+ @app.post("/login")
803
+ @rate_limit(max_attempts=5, window_seconds=300)
804
+ async def login(request: Request):
805
+ ...
806
+ ```
807
+
808
+ **Features:**
809
+ - IP + email tracking for granular rate limiting
810
+ - Sliding window algorithm
811
+ - In-memory (single instance) or MongoDB (distributed) storage
812
+ - 429 responses with `Retry-After` header
813
+ - Automatic reset on successful login
814
+
815
+ ### Audit Logging
816
+
817
+ Comprehensive audit trail for authentication events:
818
+
819
+ **Manifest Configuration:**
820
+ ```json
821
+ {
822
+ "auth": {
823
+ "audit": {
824
+ "enabled": true,
825
+ "retention_days": 90
826
+ }
827
+ }
828
+ }
829
+ ```
830
+
831
+ **Programmatic Usage:**
832
+ ```python
833
+ from mdb_engine.auth import AuthAuditLog, AuthAction
834
+
835
+ audit = AuthAuditLog(db, retention_days=90)
836
+ await audit.ensure_indexes()
837
+
838
+ # Log authentication events
839
+ await audit.log_login_success(email="user@example.com", ip_address="192.168.1.1")
840
+ await audit.log_login_failed(email="user@example.com", reason="invalid_password")
841
+ await audit.log_logout(email="user@example.com")
842
+ await audit.log_register(email="new@example.com")
843
+ await audit.log_role_change(email="user@example.com", app_slug="my_app",
844
+ old_roles=["viewer"], new_roles=["editor"])
845
+
846
+ # Query audit logs
847
+ failed_logins = await audit.get_failed_logins(email="user@example.com", hours=24)
848
+ user_activity = await audit.get_user_activity(email="user@example.com", hours=168)
849
+ summary = await audit.get_security_summary(hours=24)
850
+ ```
851
+
852
+ **Audit Actions:**
853
+ | Action | Description |
854
+ |--------|-------------|
855
+ | `login_success` | Successful login |
856
+ | `login_failed` | Failed login attempt |
857
+ | `logout` | User logout |
858
+ | `register` | New user registration |
859
+ | `token_revoked` | Token was revoked |
860
+ | `role_granted` | User received new role |
861
+ | `role_revoked` | User role was removed |
862
+ | `rate_limit_exceeded` | Rate limit was hit |
863
+
864
+ ### Secure Cookies
865
+
866
+ Auto-configured secure cookie settings based on environment:
867
+
868
+ ```python
869
+ # Get secure cookie config (auto-detects HTTPS/production)
870
+ cookie_config = user_pool.get_secure_cookie_config(request)
871
+ response.set_cookie(value=token, **cookie_config)
872
+ ```
873
+
874
+ **Cookie settings by environment:**
875
+ | Setting | Development | Production |
876
+ |---------|-------------|------------|
877
+ | `httponly` | True | True |
878
+ | `secure` | False | True |
879
+ | `samesite` | lax | strict |
880
+
881
+ ### Security Checklist
882
+
883
+ Before deploying to production:
884
+
885
+ - [ ] `MDB_ENGINE_JWT_SECRET` is set to a secure, unique value
886
+ - [ ] Rate limiting is configured for `/login` and `/register`
887
+ - [ ] Audit logging is enabled
888
+ - [ ] HTTPS is enforced (cookie `secure` flag)
889
+ - [ ] Token expiry is appropriately short (default: 24h)
890
+ - [ ] Logout endpoints call `revoke_token()`
891
+
892
+ ## Advanced Security Features
893
+
894
+ ### CSRF Protection
895
+
896
+ CSRF protection is **auto-enabled for shared auth mode**. The middleware uses the double-submit cookie pattern.
897
+
898
+ **Manifest Configuration:**
899
+ ```json
900
+ {
901
+ "auth": {
902
+ "mode": "shared",
903
+ "csrf_protection": true
904
+ }
905
+ }
906
+ ```
907
+
908
+ **Advanced Configuration:**
909
+ ```json
910
+ {
911
+ "auth": {
912
+ "csrf_protection": {
913
+ "enabled": true,
914
+ "exempt_routes": ["/api/*"],
915
+ "rotate_tokens": false,
916
+ "token_ttl": 3600
917
+ }
918
+ }
919
+ }
920
+ ```
921
+
922
+ **How it works:**
923
+ 1. GET requests receive a CSRF token in a cookie
924
+ 2. POST/PUT/DELETE must include the token in `X-CSRF-Token` header
925
+ 3. Token is validated using constant-time comparison
926
+ 4. SameSite=Lax cookies provide additional protection
927
+
928
+ **Frontend Integration:**
929
+ ```javascript
930
+ // Read token from cookie
931
+ const csrfToken = document.cookie
932
+ .split('; ')
933
+ .find(row => row.startsWith('csrf_token='))
934
+ ?.split('=')[1];
935
+
936
+ // Include in requests
937
+ fetch('/api/submit', {
938
+ method: 'POST',
939
+ headers: {'X-CSRF-Token': csrfToken}
940
+ });
941
+ ```
942
+
943
+ ### HSTS (HTTP Strict Transport Security)
944
+
945
+ HSTS forces HTTPS connections in production, protecting against protocol downgrade attacks.
946
+
947
+ **Manifest Configuration:**
948
+ ```json
949
+ {
950
+ "auth": {
951
+ "security": {
952
+ "hsts": {
953
+ "enabled": true,
954
+ "max_age": 31536000,
955
+ "include_subdomains": true,
956
+ "preload": false
957
+ }
958
+ }
959
+ }
960
+ }
961
+ ```
962
+
963
+ **Header Output:**
964
+ ```
965
+ Strict-Transport-Security: max-age=31536000; includeSubDomains
966
+ ```
967
+
968
+ **Note:** Only enable `preload` if you're ready for permanent HTTPS commitment.
969
+
970
+ ### JWT Algorithm Support
971
+
972
+ MDB_ENGINE supports multiple JWT signing algorithms for different security requirements.
973
+
974
+ | Algorithm | Type | Key | Use Case |
975
+ |-----------|------|-----|----------|
976
+ | HS256 | Symmetric | Shared secret | Default, simple deployments |
977
+ | RS256 | Asymmetric | RSA key pair | Microservices, token verification by multiple parties |
978
+ | ES256 | Asymmetric | ECDSA key pair | Modern alternative to RSA, smaller keys |
979
+
980
+ **Manifest Configuration:**
981
+ ```json
982
+ {
983
+ "auth": {
984
+ "jwt": {
985
+ "algorithm": "RS256",
986
+ "token_expiry_hours": 24
987
+ }
988
+ }
989
+ }
990
+ ```
991
+
992
+ **Environment Variables:**
993
+ ```bash
994
+ # For HS256 (symmetric)
995
+ export MDB_ENGINE_JWT_SECRET="your-secret-key"
996
+
997
+ # For RS256/ES256 (asymmetric)
998
+ export MDB_ENGINE_JWT_SECRET="-----BEGIN RSA PRIVATE KEY-----..."
999
+ export MDB_ENGINE_JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----..."
1000
+ ```
1001
+
1002
+ **Programmatic Usage:**
1003
+ ```python
1004
+ pool = SharedUserPool(
1005
+ db,
1006
+ jwt_secret=private_key,
1007
+ jwt_public_key=public_key,
1008
+ jwt_algorithm="RS256"
1009
+ )
1010
+
1011
+ # Check algorithm
1012
+ print(pool.jwt_algorithm) # "RS256"
1013
+ print(pool.is_asymmetric) # True
1014
+ ```
1015
+
1016
+ ### Password Policy
1017
+
1018
+ Configurable password strength requirements with entropy calculation and breach detection.
1019
+
1020
+ **Manifest Configuration:**
1021
+ ```json
1022
+ {
1023
+ "auth": {
1024
+ "password_policy": {
1025
+ "min_length": 12,
1026
+ "min_entropy_bits": 50,
1027
+ "require_uppercase": true,
1028
+ "require_lowercase": true,
1029
+ "require_numbers": true,
1030
+ "require_special": false,
1031
+ "check_common_passwords": true,
1032
+ "check_breaches": false
1033
+ }
1034
+ }
1035
+ }
1036
+ ```
1037
+
1038
+ **Programmatic Usage:**
1039
+ ```python
1040
+ from mdb_engine.auth import (
1041
+ validate_password_strength,
1042
+ validate_password_strength_async,
1043
+ calculate_password_entropy,
1044
+ is_common_password,
1045
+ )
1046
+
1047
+ # Synchronous validation
1048
+ is_valid, errors = validate_password_strength(
1049
+ "MyPassword123",
1050
+ config=manifest.get("auth", {}).get("password_policy", {})
1051
+ )
1052
+
1053
+ # Async validation with breach check
1054
+ is_valid, errors = await validate_password_strength_async(
1055
+ "MyPassword123",
1056
+ config=config,
1057
+ check_breaches=True # Queries HaveIBeenPwned
1058
+ )
1059
+
1060
+ # Calculate entropy
1061
+ entropy = calculate_password_entropy("MyP@ssw0rd!")
1062
+ print(f"Entropy: {entropy} bits") # ~65 bits
1063
+
1064
+ # Check common passwords
1065
+ if is_common_password("password123"):
1066
+ print("Password is too common!")
1067
+ ```
1068
+
1069
+ **Entropy Guidelines:**
1070
+ | Entropy (bits) | Strength | Example |
1071
+ |----------------|----------|---------|
1072
+ | < 28 | Very Weak | "password" |
1073
+ | 28-35 | Weak | "Password1" |
1074
+ | 36-59 | Fair | "P@ssw0rd" |
1075
+ | 60-127 | Strong | "MyS3cur3P@ss!" |
1076
+ | 128+ | Very Strong | Random 20+ char |
1077
+
1078
+ ### Session Binding
1079
+
1080
+ Tie sessions to client characteristics to prevent session hijacking.
1081
+
1082
+ **Manifest Configuration:**
1083
+ ```json
1084
+ {
1085
+ "auth": {
1086
+ "session_binding": {
1087
+ "bind_ip": false,
1088
+ "bind_fingerprint": true,
1089
+ "allow_ip_change_with_reauth": true
1090
+ }
1091
+ }
1092
+ }
1093
+ ```
1094
+
1095
+ | Setting | Default | Description |
1096
+ |---------|---------|-------------|
1097
+ | `bind_ip` | false | Strict: reject if client IP changes |
1098
+ | `bind_fingerprint` | true | Soft: log warning if fingerprint changes |
1099
+ | `allow_ip_change_with_reauth` | true | Allow IP change if user re-authenticates |
1100
+
1101
+ **How it works:**
1102
+ 1. On login, IP and/or fingerprint are embedded in JWT claims
1103
+ 2. Middleware validates these claims on each request
1104
+ 3. IP binding = strict (rejects on mismatch)
1105
+ 4. Fingerprint binding = soft (logs warning, useful for security monitoring)
1106
+
1107
+ **Token Claims:**
1108
+ ```json
1109
+ {
1110
+ "sub": "user123",
1111
+ "email": "user@example.com",
1112
+ "ip": "192.168.1.100",
1113
+ "fp": "sha256-of-browser-fingerprint",
1114
+ "jti": "unique-token-id",
1115
+ "exp": 1234567890
1116
+ }
1117
+ ```
1118
+
598
1119
  ## Security Considerations
599
1120
 
600
1121
  - **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
1122
+ - **CSRF Protection**: Auto-enabled for shared auth mode with double-submit cookie pattern
1123
+ - **Password Hashing**: Always hash passwords using bcrypt (built-in)
1124
+ - **Password Policy**: Enforce entropy requirements and check common passwords
1125
+ - **Rate Limiting**: Configure via manifest for `/login` and `/register`
1126
+ - **Token Expiration**: Use short-lived access tokens (default: 24h)
1127
+ - **Token Blacklisting**: Revoke tokens on logout via JTI
1128
+ - **Session Binding**: Bind sessions to IP/fingerprint for hijacking protection
1129
+ - **HSTS**: Force HTTPS in production
1130
+ - **Audit Logging**: Track all auth events for forensics
608
1131
 
609
1132
  ## Integration with MongoDBEngine
610
1133