kailash 0.3.2__py3-none-any.whl → 0.4.1__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 (151) hide show
  1. kailash/__init__.py +33 -1
  2. kailash/access_control/__init__.py +129 -0
  3. kailash/access_control/managers.py +461 -0
  4. kailash/access_control/rule_evaluators.py +467 -0
  5. kailash/access_control_abac.py +825 -0
  6. kailash/config/__init__.py +27 -0
  7. kailash/config/database_config.py +359 -0
  8. kailash/database/__init__.py +28 -0
  9. kailash/database/execution_pipeline.py +499 -0
  10. kailash/middleware/__init__.py +306 -0
  11. kailash/middleware/auth/__init__.py +33 -0
  12. kailash/middleware/auth/access_control.py +436 -0
  13. kailash/middleware/auth/auth_manager.py +422 -0
  14. kailash/middleware/auth/jwt_auth.py +477 -0
  15. kailash/middleware/auth/kailash_jwt_auth.py +616 -0
  16. kailash/middleware/communication/__init__.py +37 -0
  17. kailash/middleware/communication/ai_chat.py +989 -0
  18. kailash/middleware/communication/api_gateway.py +802 -0
  19. kailash/middleware/communication/events.py +470 -0
  20. kailash/middleware/communication/realtime.py +710 -0
  21. kailash/middleware/core/__init__.py +21 -0
  22. kailash/middleware/core/agent_ui.py +890 -0
  23. kailash/middleware/core/schema.py +643 -0
  24. kailash/middleware/core/workflows.py +396 -0
  25. kailash/middleware/database/__init__.py +63 -0
  26. kailash/middleware/database/base.py +113 -0
  27. kailash/middleware/database/base_models.py +525 -0
  28. kailash/middleware/database/enums.py +106 -0
  29. kailash/middleware/database/migrations.py +12 -0
  30. kailash/{api/database.py → middleware/database/models.py} +183 -291
  31. kailash/middleware/database/repositories.py +685 -0
  32. kailash/middleware/database/session_manager.py +19 -0
  33. kailash/middleware/mcp/__init__.py +38 -0
  34. kailash/middleware/mcp/client_integration.py +585 -0
  35. kailash/middleware/mcp/enhanced_server.py +576 -0
  36. kailash/nodes/__init__.py +27 -3
  37. kailash/nodes/admin/__init__.py +42 -0
  38. kailash/nodes/admin/audit_log.py +794 -0
  39. kailash/nodes/admin/permission_check.py +864 -0
  40. kailash/nodes/admin/role_management.py +823 -0
  41. kailash/nodes/admin/security_event.py +1523 -0
  42. kailash/nodes/admin/user_management.py +944 -0
  43. kailash/nodes/ai/a2a.py +24 -7
  44. kailash/nodes/ai/ai_providers.py +248 -40
  45. kailash/nodes/ai/embedding_generator.py +11 -11
  46. kailash/nodes/ai/intelligent_agent_orchestrator.py +99 -11
  47. kailash/nodes/ai/llm_agent.py +436 -5
  48. kailash/nodes/ai/self_organizing.py +85 -10
  49. kailash/nodes/ai/vision_utils.py +148 -0
  50. kailash/nodes/alerts/__init__.py +26 -0
  51. kailash/nodes/alerts/base.py +234 -0
  52. kailash/nodes/alerts/discord.py +499 -0
  53. kailash/nodes/api/auth.py +287 -6
  54. kailash/nodes/api/rest.py +151 -0
  55. kailash/nodes/auth/__init__.py +17 -0
  56. kailash/nodes/auth/directory_integration.py +1228 -0
  57. kailash/nodes/auth/enterprise_auth_provider.py +1328 -0
  58. kailash/nodes/auth/mfa.py +2338 -0
  59. kailash/nodes/auth/risk_assessment.py +872 -0
  60. kailash/nodes/auth/session_management.py +1093 -0
  61. kailash/nodes/auth/sso.py +1040 -0
  62. kailash/nodes/base.py +344 -13
  63. kailash/nodes/base_cycle_aware.py +4 -2
  64. kailash/nodes/base_with_acl.py +1 -1
  65. kailash/nodes/code/python.py +283 -10
  66. kailash/nodes/compliance/__init__.py +9 -0
  67. kailash/nodes/compliance/data_retention.py +1888 -0
  68. kailash/nodes/compliance/gdpr.py +2004 -0
  69. kailash/nodes/data/__init__.py +22 -2
  70. kailash/nodes/data/async_connection.py +469 -0
  71. kailash/nodes/data/async_sql.py +757 -0
  72. kailash/nodes/data/async_vector.py +598 -0
  73. kailash/nodes/data/readers.py +767 -0
  74. kailash/nodes/data/retrieval.py +360 -1
  75. kailash/nodes/data/sharepoint_graph.py +397 -21
  76. kailash/nodes/data/sql.py +94 -5
  77. kailash/nodes/data/streaming.py +68 -8
  78. kailash/nodes/data/vector_db.py +54 -4
  79. kailash/nodes/enterprise/__init__.py +13 -0
  80. kailash/nodes/enterprise/batch_processor.py +741 -0
  81. kailash/nodes/enterprise/data_lineage.py +497 -0
  82. kailash/nodes/logic/convergence.py +31 -9
  83. kailash/nodes/logic/operations.py +14 -3
  84. kailash/nodes/mixins/__init__.py +8 -0
  85. kailash/nodes/mixins/event_emitter.py +201 -0
  86. kailash/nodes/mixins/mcp.py +9 -4
  87. kailash/nodes/mixins/security.py +165 -0
  88. kailash/nodes/monitoring/__init__.py +7 -0
  89. kailash/nodes/monitoring/performance_benchmark.py +2497 -0
  90. kailash/nodes/rag/__init__.py +284 -0
  91. kailash/nodes/rag/advanced.py +1615 -0
  92. kailash/nodes/rag/agentic.py +773 -0
  93. kailash/nodes/rag/conversational.py +999 -0
  94. kailash/nodes/rag/evaluation.py +875 -0
  95. kailash/nodes/rag/federated.py +1188 -0
  96. kailash/nodes/rag/graph.py +721 -0
  97. kailash/nodes/rag/multimodal.py +671 -0
  98. kailash/nodes/rag/optimized.py +933 -0
  99. kailash/nodes/rag/privacy.py +1059 -0
  100. kailash/nodes/rag/query_processing.py +1335 -0
  101. kailash/nodes/rag/realtime.py +764 -0
  102. kailash/nodes/rag/registry.py +547 -0
  103. kailash/nodes/rag/router.py +837 -0
  104. kailash/nodes/rag/similarity.py +1854 -0
  105. kailash/nodes/rag/strategies.py +566 -0
  106. kailash/nodes/rag/workflows.py +575 -0
  107. kailash/nodes/security/__init__.py +19 -0
  108. kailash/nodes/security/abac_evaluator.py +1411 -0
  109. kailash/nodes/security/audit_log.py +103 -0
  110. kailash/nodes/security/behavior_analysis.py +1893 -0
  111. kailash/nodes/security/credential_manager.py +401 -0
  112. kailash/nodes/security/rotating_credentials.py +760 -0
  113. kailash/nodes/security/security_event.py +133 -0
  114. kailash/nodes/security/threat_detection.py +1103 -0
  115. kailash/nodes/testing/__init__.py +9 -0
  116. kailash/nodes/testing/credential_testing.py +499 -0
  117. kailash/nodes/transform/__init__.py +10 -2
  118. kailash/nodes/transform/chunkers.py +592 -1
  119. kailash/nodes/transform/processors.py +484 -14
  120. kailash/nodes/validation.py +321 -0
  121. kailash/runtime/access_controlled.py +1 -1
  122. kailash/runtime/async_local.py +41 -7
  123. kailash/runtime/docker.py +1 -1
  124. kailash/runtime/local.py +474 -55
  125. kailash/runtime/parallel.py +1 -1
  126. kailash/runtime/parallel_cyclic.py +1 -1
  127. kailash/runtime/testing.py +210 -2
  128. kailash/security.py +1 -1
  129. kailash/utils/migrations/__init__.py +25 -0
  130. kailash/utils/migrations/generator.py +433 -0
  131. kailash/utils/migrations/models.py +231 -0
  132. kailash/utils/migrations/runner.py +489 -0
  133. kailash/utils/secure_logging.py +342 -0
  134. kailash/workflow/__init__.py +16 -0
  135. kailash/workflow/cyclic_runner.py +3 -4
  136. kailash/workflow/graph.py +70 -2
  137. kailash/workflow/resilience.py +249 -0
  138. kailash/workflow/templates.py +726 -0
  139. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/METADATA +256 -20
  140. kailash-0.4.1.dist-info/RECORD +227 -0
  141. kailash/api/__init__.py +0 -17
  142. kailash/api/__main__.py +0 -6
  143. kailash/api/studio_secure.py +0 -893
  144. kailash/mcp/__main__.py +0 -13
  145. kailash/mcp/server_new.py +0 -336
  146. kailash/mcp/servers/__init__.py +0 -12
  147. kailash-0.3.2.dist-info/RECORD +0 -136
  148. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/WHEEL +0 -0
  149. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/entry_points.txt +0 -0
  150. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/licenses/LICENSE +0 -0
  151. {kailash-0.3.2.dist-info → kailash-0.4.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,422 @@
1
+ """
2
+ SDK-based Authentication Manager for Kailash Middleware
3
+
4
+ This module provides authentication management using SDK security nodes
5
+ instead of manual JWT handling and custom implementations.
6
+
7
+ Moved from middleware/auth.py to resolve directory/file confusion.
8
+ """
9
+
10
+ import logging
11
+ import secrets
12
+ from datetime import datetime, timedelta, timezone
13
+ from enum import Enum
14
+ from typing import Any, Dict, List, Optional, Tuple
15
+
16
+ import jwt
17
+ from fastapi import Depends, HTTPException, Request
18
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
19
+
20
+ from ...nodes.admin import PermissionCheckNode
21
+ from ...nodes.data import AsyncSQLDatabaseNode
22
+ from ...nodes.security import (
23
+ AuditLogNode,
24
+ CredentialManagerNode,
25
+ RotatingCredentialNode,
26
+ SecurityEventNode,
27
+ )
28
+ from ...nodes.transform import DataTransformer
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ class AuthLevel(Enum):
34
+ """Authentication levels for different security requirements."""
35
+
36
+ PUBLIC = "public"
37
+ BASIC = "basic"
38
+ STANDARD = "standard"
39
+ ADMIN = "admin"
40
+ SUPER_ADMIN = "super_admin"
41
+
42
+
43
+ class MiddlewareAuthManager:
44
+ """
45
+ Authentication manager using SDK security nodes.
46
+
47
+ Provides:
48
+ - JWT token management with CredentialManagerNode
49
+ - API key rotation with RotatingCredentialNode
50
+ - Permission checking with PermissionCheckNode
51
+ - Security event logging with SecurityEventNode
52
+ - Audit trail with AuditLogNode
53
+
54
+ This replaces manual JWT handling with SDK components for better
55
+ security, performance, and consistency.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ secret_key: str = None,
61
+ token_expiry_hours: int = 24,
62
+ enable_api_keys: bool = True,
63
+ enable_audit: bool = True,
64
+ database_url: str = None,
65
+ ):
66
+ """
67
+ Initialize SDK Auth Manager.
68
+
69
+ Args:
70
+ secret_key: Secret key for JWT signing (will use CredentialManager)
71
+ token_expiry_hours: Token expiration time in hours
72
+ enable_api_keys: Enable API key authentication
73
+ enable_audit: Enable audit logging
74
+ database_url: Database URL for persistence
75
+ """
76
+ self.token_expiry_hours = token_expiry_hours
77
+ self.enable_api_keys = enable_api_keys
78
+ self.enable_audit = enable_audit
79
+
80
+ # Initialize SDK security nodes
81
+ self._initialize_security_nodes(secret_key, database_url)
82
+
83
+ # FastAPI security scheme
84
+ self.bearer_scheme = HTTPBearer(auto_error=False)
85
+
86
+ def _initialize_security_nodes(self, secret_key: str, database_url: str):
87
+ """Initialize all SDK security nodes."""
88
+
89
+ # Store the secret key in memory for JWT operations
90
+ self.secret_key = secret_key
91
+
92
+ # Credential manager for fetching other credentials (not for JWT secret)
93
+ # In production, JWT secret would come from environment or vault
94
+ self.credential_manager = CredentialManagerNode(
95
+ credential_name="api_credentials",
96
+ credential_type="api_key",
97
+ name="jwt_credential_manager",
98
+ )
99
+
100
+ # Rotating credentials for API keys
101
+ if self.enable_api_keys:
102
+ self.api_key_manager = RotatingCredentialNode(
103
+ name="api_key_rotator"
104
+ # Note: RotatingCredentialNode doesn't require credential_name or rotation_interval_days in __init__
105
+ # These are passed during execution
106
+ )
107
+
108
+ # Permission checker
109
+ self.permission_checker = PermissionCheckNode(
110
+ name="middleware_permission_checker"
111
+ )
112
+
113
+ # Security event logger
114
+ self.security_logger = SecurityEventNode(name="middleware_security_events")
115
+
116
+ # Audit logger
117
+ if self.enable_audit:
118
+ self.audit_logger = AuditLogNode(name="middleware_audit")
119
+
120
+ # Data transformer for token operations
121
+ self.token_transformer = DataTransformer(name="token_transformer")
122
+
123
+ # Database node for user storage
124
+ if database_url:
125
+ self.db_node = AsyncSQLDatabaseNode(
126
+ name="auth_database", connection_string=database_url
127
+ )
128
+
129
+ async def create_access_token(
130
+ self,
131
+ user_id: str,
132
+ permissions: List[str] = None,
133
+ metadata: Dict[str, Any] = None,
134
+ ) -> str:
135
+ """
136
+ Create JWT access token using SDK nodes.
137
+
138
+ Args:
139
+ user_id: User identifier
140
+ permissions: List of permissions
141
+ metadata: Additional metadata
142
+
143
+ Returns:
144
+ JWT token string
145
+ """
146
+ # Create token payload
147
+ payload = {
148
+ "user_id": user_id,
149
+ "permissions": permissions or [],
150
+ "metadata": metadata or {},
151
+ "exp": datetime.now(timezone.utc)
152
+ + timedelta(hours=self.token_expiry_hours),
153
+ "iat": datetime.now(timezone.utc),
154
+ }
155
+
156
+ # Create JWT token
157
+ # In production, this would use a more sophisticated approach
158
+ # For now, we'll use the JWT library directly
159
+ try:
160
+ token = jwt.encode(payload, self.secret_key, algorithm="HS256")
161
+ token_result = {"token": token}
162
+ except Exception as e:
163
+ raise HTTPException(
164
+ status_code=500, detail=f"Failed to create token: {str(e)}"
165
+ )
166
+
167
+ # Log token creation
168
+ if self.enable_audit:
169
+ self.audit_logger.execute(
170
+ user_id=user_id,
171
+ action="create_token",
172
+ resource_type="jwt_token",
173
+ resource_id=user_id,
174
+ details={"permissions": permissions},
175
+ )
176
+
177
+ return token_result.get("token")
178
+
179
+ async def verify_token(self, token: str) -> Dict[str, Any]:
180
+ """
181
+ Verify and decode JWT token using SDK nodes.
182
+
183
+ Args:
184
+ token: JWT token string
185
+
186
+ Returns:
187
+ Decoded token payload
188
+
189
+ Raises:
190
+ HTTPException: If token is invalid
191
+ """
192
+ try:
193
+ # Verify JWT token
194
+ payload = jwt.decode(token, self.secret_key, algorithms=["HS256"])
195
+
196
+ # Check expiration
197
+ if payload.get("exp", 0) < datetime.now(timezone.utc).timestamp():
198
+ raise HTTPException(status_code=401, detail="Token has expired")
199
+
200
+ return payload
201
+
202
+ except Exception as e:
203
+ # Log security event
204
+ self.security_logger.execute(
205
+ event_type="token_verification_failed",
206
+ severity="warning",
207
+ details={"error": str(e)},
208
+ )
209
+ raise HTTPException(status_code=401, detail="Invalid authentication token")
210
+
211
+ async def create_api_key(
212
+ self, user_id: str, key_name: str, permissions: List[str] = None
213
+ ) -> str:
214
+ """
215
+ Create API key using RotatingCredentialNode.
216
+
217
+ Args:
218
+ user_id: User identifier
219
+ key_name: Name for the API key
220
+ permissions: List of permissions
221
+
222
+ Returns:
223
+ API key string
224
+ """
225
+ if not self.enable_api_keys:
226
+ raise HTTPException(status_code=400, detail="API keys are disabled")
227
+
228
+ # Generate a secure API key
229
+ api_key = f"sk_{secrets.token_urlsafe(32)}"
230
+
231
+ # Store API key metadata using credential manager
232
+ result = self.credential_manager.run(
233
+ operation="store_credential",
234
+ credential_name=api_key,
235
+ credential_data={
236
+ "user_id": user_id,
237
+ "key_name": key_name,
238
+ "permissions": permissions or [],
239
+ "created_at": datetime.now(timezone.utc).isoformat(),
240
+ "api_key": api_key,
241
+ },
242
+ )
243
+
244
+ if not result.get("success", False):
245
+ raise HTTPException(status_code=500, detail="Failed to create API key")
246
+
247
+ # Audit log
248
+ if self.enable_audit:
249
+ self.audit_logger.execute(
250
+ user_id=user_id,
251
+ action="create_api_key",
252
+ resource_type="api_key",
253
+ resource_id=key_name,
254
+ details={"permissions": permissions},
255
+ )
256
+
257
+ return api_key
258
+
259
+ async def verify_api_key(self, api_key: str) -> Dict[str, Any]:
260
+ """
261
+ Verify API key using SDK nodes.
262
+
263
+ Args:
264
+ api_key: API key string
265
+
266
+ Returns:
267
+ API key metadata including user_id and permissions
268
+
269
+ Raises:
270
+ HTTPException: If API key is invalid
271
+ """
272
+ if not self.enable_api_keys:
273
+ raise HTTPException(status_code=400, detail="API keys are disabled")
274
+
275
+ try:
276
+ # Verify using credential manager since rotating credential node doesn't have verify
277
+ result = self.credential_manager.run(
278
+ operation="get_credential", credential_name=api_key
279
+ )
280
+
281
+ if not result.get("success", False):
282
+ raise HTTPException(status_code=401, detail="Invalid API key")
283
+
284
+ credential_data = result.get("credential", {})
285
+ return credential_data.get("metadata", {})
286
+
287
+ except HTTPException:
288
+ raise
289
+ except Exception as e:
290
+ # Log security event
291
+ self.security_logger.execute(
292
+ event_type="api_key_verification_failed",
293
+ severity="warning",
294
+ details={"error": str(e)},
295
+ )
296
+ raise HTTPException(status_code=401, detail="Invalid API key")
297
+
298
+ async def check_permission(
299
+ self, user_id: str, permission: str, resource: Dict[str, Any] = None
300
+ ) -> bool:
301
+ """
302
+ Check user permission using PermissionCheckNode.
303
+
304
+ Args:
305
+ user_id: User identifier
306
+ permission: Permission to check
307
+ resource: Optional resource context
308
+
309
+ Returns:
310
+ True if permission is granted
311
+ """
312
+ result = self.permission_checker.run(
313
+ user_context={"user_id": user_id},
314
+ permission=permission,
315
+ resource=resource or {},
316
+ )
317
+
318
+ granted = result.get("authorized", False)
319
+
320
+ # Audit permission check
321
+ if self.enable_audit:
322
+ self.audit_logger.execute(
323
+ user_id=user_id,
324
+ action="check_permission",
325
+ resource_type="permission",
326
+ resource_id=permission,
327
+ details={"granted": granted, "resource": resource},
328
+ )
329
+
330
+ return granted
331
+
332
+ def get_current_user_dependency(self, required_permissions: List[str] = None):
333
+ """
334
+ Create FastAPI dependency for user authentication.
335
+
336
+ Args:
337
+ required_permissions: List of required permissions
338
+
339
+ Returns:
340
+ FastAPI dependency function
341
+ """
342
+
343
+ async def verify_user(
344
+ request: Request,
345
+ credentials: HTTPAuthorizationCredentials = Depends(self.bearer_scheme),
346
+ ) -> Dict[str, Any]:
347
+ """Verify user from request."""
348
+
349
+ # Try bearer token first
350
+ if credentials and credentials.credentials:
351
+ try:
352
+ payload = await self.verify_token(credentials.credentials)
353
+ user_id = payload.get("user_id")
354
+
355
+ # Check permissions if required
356
+ if required_permissions:
357
+ user_permissions = payload.get("permissions", [])
358
+ for perm in required_permissions:
359
+ if perm not in user_permissions:
360
+ # Check using permission node
361
+ if not await self.check_permission(user_id, perm):
362
+ raise HTTPException(
363
+ status_code=403,
364
+ detail=f"Missing required permission: {perm}",
365
+ )
366
+
367
+ return {
368
+ "user_id": user_id,
369
+ "permissions": payload.get("permissions", []),
370
+ "metadata": payload.get("metadata", {}),
371
+ }
372
+ except HTTPException:
373
+ pass
374
+
375
+ # Try API key from header
376
+ api_key = request.headers.get("X-API-Key")
377
+ if api_key:
378
+ try:
379
+ metadata = await self.verify_api_key(api_key)
380
+ user_id = metadata.get("user_id")
381
+
382
+ # Check permissions
383
+ if required_permissions:
384
+ key_permissions = metadata.get("permissions", [])
385
+ for perm in required_permissions:
386
+ if perm not in key_permissions:
387
+ if not await self.check_permission(user_id, perm):
388
+ raise HTTPException(
389
+ status_code=403,
390
+ detail=f"Missing required permission: {perm}",
391
+ )
392
+
393
+ return {
394
+ "user_id": user_id,
395
+ "permissions": metadata.get("permissions", []),
396
+ "metadata": metadata,
397
+ }
398
+ except HTTPException:
399
+ pass
400
+
401
+ # No valid authentication
402
+ raise HTTPException(status_code=401, detail="Not authenticated")
403
+
404
+ return verify_user
405
+
406
+
407
+ # Convenience function for creating auth dependencies
408
+ def require_auth(permissions: List[str] = None):
409
+ """
410
+ Create authentication dependency with required permissions.
411
+
412
+ Args:
413
+ permissions: List of required permissions
414
+
415
+ Returns:
416
+ FastAPI dependency
417
+ """
418
+ # This would use a global auth manager instance
419
+ # In practice, this would be configured at app startup
420
+ raise NotImplementedError(
421
+ "Use auth_manager.get_current_user_dependency(permissions) instead"
422
+ )