miso-client 0.1.0__py3-none-any.whl → 0.4.0__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.

Potentially problematic release.


This version of miso-client might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: miso-client
3
- Version: 0.1.0
3
+ Version: 0.4.0
4
4
  Summary: Python client SDK for AI Fabrix authentication, authorization, and logging
5
5
  Home-page: https://github.com/aifabrix/miso-client-python
6
6
  Author: AI Fabrix Team
@@ -80,10 +80,13 @@ The **AI Fabrix Miso Client SDK** provides authentication, authorization, and lo
80
80
  ### 📊 Compliance & Audit
81
81
 
82
82
  **ISO 27001 Compliance**
83
- - Comprehensive audit trails for all user actions
83
+ - Comprehensive audit trails for all user actions and HTTP requests
84
+ - Automatic data masking for all sensitive information in logs
85
+ - HTTP request/response audit logging with masked sensitive data
84
86
  - Data access logging and monitoring
85
87
  - Security event tracking
86
88
  - Accountability and non-repudiation
89
+ - Configurable sensitive fields via JSON configuration
87
90
 
88
91
  **Regulatory Compliance**
89
92
  - GDPR-ready data protection
@@ -134,9 +137,13 @@ The **AI Fabrix Miso Client SDK** provides authentication, authorization, and lo
134
137
 
135
138
  **Observability**
136
139
  - Centralized logging with correlation IDs
140
+ - Automatic HTTP request/response audit logging (ISO 27001 compliant)
141
+ - Debug logging with detailed request/response information (when `log_level='debug'`)
137
142
  - Performance tracking and metrics
138
143
  - Error tracking and debugging
139
144
  - Health monitoring
145
+ - Automatic data masking for sensitive information in logs
146
+ - Configurable sensitive fields via JSON configuration
140
147
 
141
148
  ---
142
149
 
@@ -262,7 +269,7 @@ if is_admin:
262
269
 
263
270
  ### Step 5: Activate Logging
264
271
 
265
- **What happens:** Application logs are sent to the Miso Controller with client token authentication.
272
+ **What happens:** Application logs are sent to the Miso Controller with client token authentication. All HTTP requests are automatically audited with ISO 27001 compliant data masking.
266
273
 
267
274
  ```python
268
275
  from miso_client import MisoClient, load_config
@@ -278,10 +285,17 @@ user = await client.get_user(token)
278
285
  await client.log.info('User accessed dashboard', {'userId': user.id if user else None})
279
286
  await client.log.error('Operation failed', {'error': str(err)})
280
287
  await client.log.warn('Unusual activity', {'details': '...'})
288
+
289
+ # HTTP requests are automatically audited
290
+ # All sensitive data is automatically masked before logging
291
+ result = await client.http_client.get('/api/users')
292
+ # This automatically creates an audit log: http.request.GET with masked sensitive data
281
293
  ```
282
294
 
283
295
  **What happens to logs?** They're sent to the Miso Controller for centralized monitoring and analysis. Client token is automatically included.
284
296
 
297
+ **ISO 27001 Compliance:** All HTTP requests are automatically audited with sensitive data masked. Set `log_level='debug'` to enable detailed request/response logging (all sensitive data is still masked).
298
+
285
299
  → [Complete logging example](examples/step-5-logging.py)
286
300
  → [Logging Reference](docs/api-reference.md#logger-service)
287
301
 
@@ -366,6 +380,40 @@ ENCRYPTION_KEY=your-32-byte-encryption-key
366
380
 
367
381
  ---
368
382
 
383
+ ### Testing with API Key
384
+
385
+ **What happens:** When `API_KEY` is set in your `.env` file, you can authenticate requests using the API key as a bearer token, bypassing OAuth2 authentication. This is useful for testing without setting up Keycloak.
386
+
387
+ ```python
388
+ from miso_client import MisoClient, load_config
389
+
390
+ client = MisoClient(load_config())
391
+ await client.initialize()
392
+
393
+ # Use API_KEY as bearer token (for testing only)
394
+ api_key_token = "your-api-key-from-env"
395
+ is_valid = await client.validate_token(api_key_token)
396
+ # Returns True if token matches API_KEY from .env
397
+
398
+ user = await client.get_user(api_key_token)
399
+ # Returns None (API key auth doesn't provide user info)
400
+ ```
401
+
402
+ **Configuration:**
403
+
404
+ ```bash
405
+ # Add to .env for testing
406
+ API_KEY=your-test-api-key-here
407
+ ```
408
+
409
+ **Important:**
410
+ - API_KEY authentication bypasses OAuth2 validation completely
411
+ - User information methods (`get_user()`, `get_user_info()`) return `None` when using API_KEY
412
+ - Token validation returns `True` if the bearer token matches the configured `API_KEY`
413
+ - This feature is intended for testing and development only
414
+
415
+ ---
416
+
369
417
  ## 🔧 Configuration
370
418
 
371
419
  ```python
@@ -380,6 +428,8 @@ config = MisoClientConfig(
380
428
  port=6379,
381
429
  ),
382
430
  log_level="info", # Optional: 'debug' | 'info' | 'warn' | 'error'
431
+ # Set to 'debug' for detailed HTTP request/response logging
432
+ api_key="your-test-api-key", # Optional: API key for testing (bypasses OAuth2)
383
433
  cache={ # Optional: Cache TTL settings
384
434
  "role_ttl": 900, # Role cache TTL (default: 900s)
385
435
  "permission_ttl": 900, # Permission cache TTL (default: 900s)
@@ -389,6 +439,18 @@ config = MisoClientConfig(
389
439
 
390
440
  **Recommended:** Use `load_config()` to load from `.env` file automatically.
391
441
 
442
+ **ISO 27001 Data Masking Configuration:**
443
+
444
+ Sensitive fields are configured via `miso_client/utils/sensitive_fields_config.json`. You can customize this by:
445
+
446
+ 1. Setting `MISO_SENSITIVE_FIELDS_CONFIG` environment variable to point to a custom JSON file
447
+ 2. Using `DataMasker.set_config_path()` to set a custom path programmatically
448
+
449
+ The default configuration includes ISO 27001 compliant sensitive fields:
450
+ - Authentication: password, token, secret, key, auth, authorization
451
+ - PII: ssn, creditcard, cc, cvv, pin, otp
452
+ - Security: apikey, accesstoken, refreshtoken, privatekey, secretkey, cookie, session
453
+
392
454
  → [Complete Configuration Reference](docs/configuration.md)
393
455
 
394
456
  ---
@@ -413,6 +475,28 @@ The SDK consists of five core services:
413
475
  - **LoggerService** - Centralized logging with API key authentication
414
476
  - **RedisService** - Caching and queue management (optional)
415
477
 
478
+ ### HTTP Client Architecture
479
+
480
+ The SDK uses a two-layer HTTP client architecture for ISO 27001 compliance:
481
+
482
+ - **InternalHttpClient** - Core HTTP functionality with automatic client token management (internal)
483
+ - **HttpClient** - Public wrapper that adds automatic ISO 27001 compliant audit and debug logging
484
+
485
+ **Features:**
486
+ - Automatic audit logging for all HTTP requests (`http.request.{METHOD}`)
487
+ - Debug logging when `log_level === 'debug'` with detailed request/response information
488
+ - Automatic data masking using `DataMasker` before logging (ISO 27001 compliant)
489
+ - Sensitive endpoints (`/api/logs`, `/api/auth/token`) are excluded from audit logging to prevent infinite loops
490
+ - All sensitive data (headers, bodies, query params) is automatically masked before logging
491
+
492
+ **ISO 27001 Compliance:**
493
+ - All request headers are masked (Authorization, x-client-token, Cookie, etc.)
494
+ - All request bodies are recursively masked for sensitive fields (password, token, secret, SSN, etc.)
495
+ - All response bodies are masked (limited to first 1000 characters)
496
+ - Query parameters are automatically masked
497
+ - Error messages are masked if they contain sensitive data
498
+ - Sensitive fields configuration can be customized via `sensitive_fields_config.json`
499
+
416
500
  → [Architecture Details](docs/api-reference.md#architecture)
417
501
 
418
502
  ---
@@ -450,6 +534,83 @@ The SDK consists of five core services:
450
534
  - [Flask Decorators](docs/examples.md#flask-decorators) - Decorator-based auth
451
535
  - [Error Handling](docs/examples.md#error-handling) - Best practices
452
536
 
537
+ ---
538
+
539
+ ### Structured Error Responses
540
+
541
+ **What happens:** The SDK automatically parses structured error responses from the API (RFC 7807-style format) and makes them available through the `MisoClientError` exception.
542
+
543
+ ```python
544
+ from miso_client import MisoClient, MisoClientError, ErrorResponse, load_config
545
+
546
+ client = MisoClient(load_config())
547
+ await client.initialize()
548
+
549
+ try:
550
+ result = await client.http_client.get("/api/some-endpoint")
551
+ except MisoClientError as e:
552
+ # Check if structured error response is available
553
+ if e.error_response:
554
+ print(f"Error Type: {e.error_response.type}")
555
+ print(f"Error Title: {e.error_response.title}")
556
+ print(f"Status Code: {e.error_response.statusCode}")
557
+ print(f"Errors: {e.error_response.errors}")
558
+ print(f"Instance: {e.error_response.instance}")
559
+ else:
560
+ # Fallback to traditional error handling
561
+ print(f"Error: {e.message}")
562
+ print(f"Status Code: {e.status_code}")
563
+ print(f"Error Body: {e.error_body}")
564
+ ```
565
+
566
+ **Error Response Structure:**
567
+
568
+ The `ErrorResponse` model follows RFC 7807-style format:
569
+
570
+ ```json
571
+ {
572
+ "errors": [
573
+ "The user has provided input that the browser is unable to convert.",
574
+ "There are multiple rows in the database for the same value"
575
+ ],
576
+ "type": "/Errors/Bad Input",
577
+ "title": "Bad Request",
578
+ "statusCode": 400,
579
+ "instance": "/OpenApi/rest/Xzy"
580
+ }
581
+ ```
582
+
583
+ **Features:**
584
+
585
+ - **Automatic Parsing**: Structured error responses are automatically parsed from HTTP responses
586
+ - **Backward Compatible**: Falls back to traditional error handling when structured format is not available
587
+ - **Type Safety**: Full type hints with Pydantic models for reliable error handling
588
+ - **Generic Interface**: `ErrorResponse` model can be reused across different applications
589
+ - **Instance URI**: Automatically extracted from request URL if not provided in response
590
+
591
+ **Using ErrorResponse directly:**
592
+
593
+ ```python
594
+ from miso_client import ErrorResponse
595
+
596
+ # Create ErrorResponse from dict
597
+ error_data = {
598
+ "errors": ["Validation failed"],
599
+ "type": "/Errors/Validation",
600
+ "title": "Validation Error",
601
+ "statusCode": 422,
602
+ "instance": "/api/endpoint"
603
+ }
604
+ error_response = ErrorResponse(**error_data)
605
+
606
+ # Access fields
607
+ print(error_response.errors) # ["Validation failed"]
608
+ print(error_response.type) # "/Errors/Validation"
609
+ print(error_response.title) # "Validation Error"
610
+ print(error_response.statusCode) # 422
611
+ print(error_response.instance) # "/api/endpoint"
612
+ ```
613
+
453
614
  ### Common Tasks
454
615
 
455
616
  **Add authentication middleware (FastAPI):**
@@ -490,6 +651,7 @@ MISO_CONTROLLER_URL=http://localhost:3000
490
651
  REDIS_HOST=localhost
491
652
  REDIS_PORT=6379
492
653
  MISO_LOG_LEVEL=info
654
+ API_KEY=your-test-api-key # Optional: For testing (bypasses OAuth2)
493
655
  ```
494
656
 
495
657
  ---
@@ -0,0 +1,26 @@
1
+ miso_client/__init__.py,sha256=MjiF-VJCkY6_s5_Oy8U43ZRa-XRVgrTpco-PnGPBTC4,14395
2
+ miso_client/errors.py,sha256=uyS5j-_bUCA5gbINPYQd0wMpGsaEH0tJRK0obQTq2oo,1976
3
+ miso_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ miso_client/models/__init__.py,sha256=lMnzU7j2Z5_UehvOeIrbJIo3MH4j5KINGfU1vJTzTyU,139
5
+ miso_client/models/config.py,sha256=TLckmwajrdnJpMTsjCtaFkz8wFAXcEQJfKjXQ8ww6vM,8024
6
+ miso_client/models/error_response.py,sha256=Dd-Rm2ylxU9ssYUsGBifjT-Let2MMxn28LJszQCO5bY,1362
7
+ miso_client/services/__init__.py,sha256=2ok62Z9kaS0Zze-OxRkxEJ4JidzN9jL_pzGMOxpZppQ,489
8
+ miso_client/services/auth.py,sha256=hYnHEoTNgeH_g0ItoVDq99fBZCZX0o-0o-9gRxqZYmw,5465
9
+ miso_client/services/cache.py,sha256=lXcLcRm56snOX3AQiEKi-j7FIikCLYnEK2HXxBkxm2M,6510
10
+ miso_client/services/encryption.py,sha256=8512ACLt0P8t3W_CGzmG0JRSvzDinvjPRvkifdDxIRs,3022
11
+ miso_client/services/logger.py,sha256=dopKQeBZpz9S3iX9vw8xcPsS1oyMASOUQ4-OvCdElTw,16772
12
+ miso_client/services/permission.py,sha256=GOGRAaXSfPKTXqEqbR0XP8hrA-YQgVFbHPxD-gGBUyA,6853
13
+ miso_client/services/redis.py,sha256=BWfgXoSOyyGrB9cf_kTY0lZwfbjUWQhkiOyFFSp590M,5348
14
+ miso_client/services/role.py,sha256=qmxhk54QUGCjCuCWm_ruDlTq7iT9yOicfUvdRVkFKUI,5517
15
+ miso_client/utils/__init__.py,sha256=HArSxVKrmCqFkqFOPwe1i3B2IBHJ1vRqYu98c_KASV0,366
16
+ miso_client/utils/config_loader.py,sha256=yZk4pXNIBu3i61KqxM8QwsjraM0xhqUcH2THl8-DMu0,3027
17
+ miso_client/utils/data_masker.py,sha256=D7AEyViGxoShLa5UUZHYhRCPQMPKqX7qNilTK9h87OM,7035
18
+ miso_client/utils/http_client.py,sha256=AwlP0h17SdJ2lqf5j19HVztjvvMrCPTybkbWdvGzM38,20252
19
+ miso_client/utils/internal_http_client.py,sha256=jgiaO94EiIUbMQWUKN4FhYqOQ9r0BZea0_grRcOepL4,16078
20
+ miso_client/utils/jwt_tools.py,sha256=-pvz5nk5BztEnhFnL-dtOv8Q5E0G2oh4RwFrVk2rVpg,1981
21
+ miso_client/utils/sensitive_fields_loader.py,sha256=EHODxyM1Gw7hgKXCvJ1B4Hf4LZqcEqWEXu4q5CPFaic,3667
22
+ miso_client-0.4.0.dist-info/licenses/LICENSE,sha256=3hoU8LdT9_EIFIx6FjMk5sQnVCBMX3FRIOzqqy5im4c,1076
23
+ miso_client-0.4.0.dist-info/METADATA,sha256=Ek0HsqCnGba1PhmwPWre-KSrxVcOthJ1XtDBuObGyUw,22690
24
+ miso_client-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ miso_client-0.4.0.dist-info/top_level.txt,sha256=8i_FNeRn8PRy6scnXOpVr-IJYsArkqIvxRMTZPtik9E,12
26
+ miso_client-0.4.0.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- miso_client/__init__.py,sha256=lL254-VN8Q8SV4nJwiTMYEWrYUpBzzG_uxNlNlQKuog,14205
2
- miso_client/errors.py,sha256=XEa0bbYoP4mH6n8GuTquf-qD4tkCr-Ca3QIWOKZJtxQ,1143
3
- miso_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- miso_client/models/__init__.py,sha256=Oy03VQKAqg0FGZiWfcNdSgOA-PzfbdQDX_1sqfv_r-U,67
5
- miso_client/models/config.py,sha256=PFiIp8fouoGGBUAu9ODwsVwhuW78v-iqEvDPBQ0YK5Q,7759
6
- miso_client/services/__init__.py,sha256=DfiZJ45MWQvVqwp0kyxjuK9ngiO3nW8zcdBqd7VOD7Y,488
7
- miso_client/services/auth.py,sha256=NrVX5MXaLqWinoWB7bAvEurTONkjVm2HlvDJPnmOkKU,4863
8
- miso_client/services/cache.py,sha256=gu5Ykbh43vrBb9hLvl6OXstGKFZpUUyIAa4fifj6KW8,6786
9
- miso_client/services/encryption.py,sha256=kQsES7oCs1l8vTmy1G9mI6eXXvrfdNuXMpZzG_xUX0M,3145
10
- miso_client/services/logger.py,sha256=tpj-N3Rq4dfkJteNu7rt_KniOFkf5eyhuTbFcapM-Nk,16789
11
- miso_client/services/permission.py,sha256=6vT9BV_NX9dJ7moSN5CBILjEn9u6do9IAeR4k3Fp9Q8,7210
12
- miso_client/services/redis.py,sha256=4ov5Pu1xKDqSUNMDx9rTvbsTuM4jwaRUrpSiLAzIU_I,5478
13
- miso_client/services/role.py,sha256=j4qCyYBXinubEpa0Yy_XPqFANuQHSQl0BILugRXM5WY,5896
14
- miso_client/utils/__init__.py,sha256=YErXOQ6cqaxflEC7JCQuV_XbPU4NTAdBhbe4L5tv73o,365
15
- miso_client/utils/config_loader.py,sha256=a2Jj8sd_IN8EhCjk3mtdMK1Z3MAG0P8IYThCd66dk3k,2912
16
- miso_client/utils/data_masker.py,sha256=PJ-8ro2zuzS_XkjB5aV_DjY9NAjnlynJhsy41nFr408,4570
17
- miso_client/utils/http_client.py,sha256=L9004iavGVM67BIJTl9_aI0rzV6fMSi0WPZi1h-CgTY,13347
18
- miso_client/utils/jwt_tools.py,sha256=W1WFA_J1YU1Ng-IcsA9KdUTPda4pqIy7TF7nvXl2KLk,2061
19
- miso_client-0.1.0.dist-info/licenses/LICENSE,sha256=3hoU8LdT9_EIFIx6FjMk5sQnVCBMX3FRIOzqqy5im4c,1076
20
- miso_client-0.1.0.dist-info/METADATA,sha256=ocOKMvNYl5VKFXr5NbD7FtdwWfMM947h0Rt4lgLRJR0,16006
21
- miso_client-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- miso_client-0.1.0.dist-info/top_level.txt,sha256=8i_FNeRn8PRy6scnXOpVr-IJYsArkqIvxRMTZPtik9E,12
23
- miso_client-0.1.0.dist-info/RECORD,,