miso-client 0.2.0__tar.gz → 0.4.0__tar.gz

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.

Files changed (39) hide show
  1. {miso_client-0.2.0 → miso_client-0.4.0}/CHANGELOG.md +117 -3
  2. {miso_client-0.2.0/miso_client.egg-info → miso_client-0.4.0}/PKG-INFO +129 -3
  3. {miso_client-0.2.0 → miso_client-0.4.0}/README.md +128 -2
  4. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/__init__.py +21 -3
  5. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/errors.py +22 -1
  6. miso_client-0.4.0/miso_client/models/__init__.py +5 -0
  7. miso_client-0.4.0/miso_client/models/error_response.py +41 -0
  8. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/logger.py +7 -6
  9. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/utils/data_masker.py +77 -5
  10. miso_client-0.4.0/miso_client/utils/http_client.py +585 -0
  11. miso_client-0.2.0/miso_client/utils/http_client.py → miso_client-0.4.0/miso_client/utils/internal_http_client.py +103 -19
  12. miso_client-0.4.0/miso_client/utils/sensitive_fields_loader.py +116 -0
  13. {miso_client-0.2.0 → miso_client-0.4.0/miso_client.egg-info}/PKG-INFO +129 -3
  14. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client.egg-info/SOURCES.txt +4 -1
  15. {miso_client-0.2.0 → miso_client-0.4.0}/pyproject.toml +1 -1
  16. {miso_client-0.2.0 → miso_client-0.4.0}/setup.py +1 -1
  17. miso_client-0.2.0/miso_client/models/__init__.py +0 -1
  18. {miso_client-0.2.0 → miso_client-0.4.0}/LICENSE +0 -0
  19. {miso_client-0.2.0 → miso_client-0.4.0}/MANIFEST.in +0 -0
  20. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/models/config.py +0 -0
  21. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/py.typed +0 -0
  22. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/__init__.py +0 -0
  23. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/auth.py +0 -0
  24. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/cache.py +0 -0
  25. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/encryption.py +0 -0
  26. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/permission.py +0 -0
  27. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/redis.py +0 -0
  28. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/services/role.py +0 -0
  29. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/utils/__init__.py +0 -0
  30. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/utils/config_loader.py +0 -0
  31. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client/utils/jwt_tools.py +0 -0
  32. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client.egg-info/dependency_links.txt +0 -0
  33. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client.egg-info/not-zip-safe +0 -0
  34. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client.egg-info/requires.txt +0 -0
  35. {miso_client-0.2.0 → miso_client-0.4.0}/miso_client.egg-info/top_level.txt +0 -0
  36. {miso_client-0.2.0 → miso_client-0.4.0}/pytest.ini +0 -0
  37. {miso_client-0.2.0 → miso_client-0.4.0}/requirements-test.txt +0 -0
  38. {miso_client-0.2.0 → miso_client-0.4.0}/requirements.txt +0 -0
  39. {miso_client-0.2.0 → miso_client-0.4.0}/setup.cfg +0 -0
@@ -5,7 +5,121 @@ All notable changes to the MisoClient SDK will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.2.0] - 2025-10-31
8
+ ## [0.4.0] - 2025-11-02
9
+
10
+ ### Added
11
+
12
+ - **ISO 27001 Compliant HTTP Client with Automatic Audit and Debug Logging**: New public `HttpClient` class that wraps `InternalHttpClient` with automatic ISO 27001 compliant audit and debug logging
13
+ - Automatic audit logging for all HTTP requests (`http.request.{METHOD}` format)
14
+ - Debug logging when `log_level === 'debug'` with detailed request/response information
15
+ - Automatic data masking using `DataMasker` before logging (ISO 27001 compliant)
16
+ - All request headers are masked (Authorization, x-client-token, Cookie, etc.)
17
+ - All request bodies are recursively masked for sensitive fields (password, token, secret, SSN, etc.)
18
+ - All response bodies are masked (limited to first 1000 characters)
19
+ - Query parameters are automatically masked
20
+ - Error messages are masked if they contain sensitive data
21
+ - Sensitive endpoints (`/api/logs`, `/api/auth/token`) are excluded from audit logging to prevent infinite loops
22
+ - JWT user ID extraction from Authorization headers for audit context
23
+ - Request duration tracking for performance monitoring
24
+ - Request/response size tracking for observability
25
+
26
+ - **JSON Configuration Support for DataMasker**: Enhanced `DataMasker` with JSON configuration file support for sensitive fields
27
+ - New `sensitive_fields_config.json` file with default ISO 27001 compliant sensitive fields
28
+ - Categories: authentication, pii, security
29
+ - Support for custom configuration path via `MISO_SENSITIVE_FIELDS_CONFIG` environment variable
30
+ - `DataMasker.set_config_path()` method for programmatic configuration
31
+ - Automatic merging of JSON fields with hardcoded defaults (fallback if JSON cannot be loaded)
32
+ - Backward compatible - existing hardcoded fields still work as fallback
33
+
34
+ - **New InternalHttpClient Class**: Separated core HTTP functionality into `InternalHttpClient` class
35
+ - Pure HTTP functionality with automatic client token management (no logging)
36
+ - Used internally by public `HttpClient` for actual HTTP requests
37
+ - Used by `LoggerService` for sending logs to prevent circular dependencies
38
+ - Not exported in public API (internal use only)
39
+
40
+ - **New sensitive_fields_loader Module**: Utility module for loading and merging sensitive fields configuration
41
+ - `load_sensitive_fields_config()` function for loading JSON configuration
42
+ - `get_sensitive_fields_array()` function for flattened sensitive fields list
43
+ - `get_field_patterns()` function for pattern matching rules
44
+ - Support for custom configuration paths via environment variables
45
+
46
+ ### Changed
47
+
48
+ - **Breaking Change: HttpClient Constructor**: Public `HttpClient` constructor now requires `logger` parameter
49
+ - Old: `HttpClient(config)`
50
+ - New: `HttpClient(config, logger)`
51
+ - This is handled automatically when using `MisoClient` - no changes needed for typical usage
52
+ - Only affects code that directly instantiates `HttpClient`
53
+
54
+ - **Breaking Change: LoggerService Constructor**: `LoggerService` constructor now uses `InternalHttpClient` instead of `HttpClient`
55
+ - Old: `LoggerService(http_client: HttpClient, redis: RedisService)`
56
+ - New: `LoggerService(internal_http_client: InternalHttpClient, redis: RedisService)`
57
+ - This is handled automatically when using `MisoClient` - no changes needed for typical usage
58
+ - Prevents circular dependency (LoggerService uses InternalHttpClient for log sending)
59
+
60
+ - **MisoClient Architecture**: Updated `MisoClient` constructor to use new HttpClient architecture
61
+ - Creates `InternalHttpClient` first (pure HTTP functionality)
62
+ - Creates `LoggerService` with `InternalHttpClient` (prevents circular dependency)
63
+ - Creates public `HttpClient` wrapping `InternalHttpClient` with logger (adds audit/debug logging)
64
+ - All services now use public `HttpClient` with automatic audit logging
65
+
66
+ - **DataMasker Enhancement**: Updated `DataMasker` to load sensitive fields from JSON configuration
67
+ - Maintains backward compatibility with hardcoded fields as fallback
68
+ - Automatic loading on first use with caching
69
+ - Support for custom configuration paths
70
+
71
+ ### ISO 27001 Compliance Features
72
+
73
+ - **Automatic Data Masking**: All sensitive data is automatically masked before logging
74
+ - Request headers: Authorization, x-client-token, Cookie, Set-Cookie, and any header containing sensitive keywords
75
+ - Request bodies: Recursively masks password, token, secret, SSN, creditcard, CVV, PIN, OTP, API keys, etc.
76
+ - Response bodies: Especially important for error responses that might contain sensitive data
77
+ - Query parameters: Automatically extracted and masked
78
+ - Error messages: Masked if containing sensitive data
79
+
80
+ - **Audit Log Structure**: Standardized audit log format for all HTTP requests
81
+ - Action: `http.request.{METHOD}` (e.g., `http.request.GET`, `http.request.POST`)
82
+ - Resource: Request URL path
83
+ - Context: method, url, statusCode, duration, userId, requestSize, responseSize, error (all sensitive data masked)
84
+
85
+ - **Debug Log Structure**: Detailed debug logging when `log_level === 'debug'`
86
+ - All audit context fields plus: requestHeaders, responseHeaders, requestBody, responseBody (all masked)
87
+ - Additional context: baseURL, timeout, queryParams (all sensitive data masked)
88
+
89
+ ### Technical Improvements
90
+
91
+ - Improved error handling: Logging errors never break HTTP requests (all errors caught and swallowed)
92
+ - Performance: Async logging that doesn't block request/response flow
93
+ - Safety: Sensitive endpoints excluded from audit logging to prevent infinite loops
94
+ - Flexibility: Configurable sensitive fields via JSON configuration file
95
+
96
+ ---
97
+
98
+ ## [0.3.0] - 2025-11-01
99
+
100
+ ### Added
101
+
102
+ - **Structured Error Response Interface**: Added generic `ErrorResponse` model following RFC 7807-style format for consistent error handling across applications
103
+ - `ErrorResponse` Pydantic model with fields: `errors`, `type`, `title`, `statusCode`, `instance`
104
+ - Automatic parsing of structured error responses from HTTP responses in `HttpClient`
105
+ - Support for both camelCase (`statusCode`) and snake_case (`status_code`) field names
106
+ - `MisoClientError` now includes optional `error_response` field with structured error information
107
+ - Enhanced error messages automatically generated from structured error responses
108
+ - Instance URI automatically extracted from request URL when not provided in response
109
+ - Backward compatible - falls back to traditional `error_body` dict when structured format is not available
110
+ - Export `ErrorResponse` from main module for reuse in other applications
111
+ - Comprehensive test coverage for error response parsing and fallback behavior
112
+ - Full type safety with Pydantic models
113
+
114
+ ### Changed
115
+
116
+ - **Error Handling**: `MisoClientError` now prioritizes structured error information when available
117
+ - Error messages are automatically enhanced from structured error responses
118
+ - Status codes are extracted from structured responses when provided
119
+
120
+ ---
121
+
122
+ ## [0.2.0] - 2025-10-31
9
123
 
10
124
  ### Added
11
125
 
@@ -43,7 +157,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
43
157
 
44
158
  ---
45
159
 
46
- ## [1.1.0] - 2025-10-30
160
+ ## [0.1.0] - 2025-10-30
47
161
 
48
162
  ### Added
49
163
 
@@ -82,7 +196,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
82
196
 
83
197
  ---
84
198
 
85
- ## [1.0.0] - 2025-10-01
199
+ ## [0.1.0] - 2025-10-01
86
200
 
87
201
  ### Added
88
202
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: miso-client
3
- Version: 0.2.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
 
@@ -414,6 +428,7 @@ config = MisoClientConfig(
414
428
  port=6379,
415
429
  ),
416
430
  log_level="info", # Optional: 'debug' | 'info' | 'warn' | 'error'
431
+ # Set to 'debug' for detailed HTTP request/response logging
417
432
  api_key="your-test-api-key", # Optional: API key for testing (bypasses OAuth2)
418
433
  cache={ # Optional: Cache TTL settings
419
434
  "role_ttl": 900, # Role cache TTL (default: 900s)
@@ -424,6 +439,18 @@ config = MisoClientConfig(
424
439
 
425
440
  **Recommended:** Use `load_config()` to load from `.env` file automatically.
426
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
+
427
454
  → [Complete Configuration Reference](docs/configuration.md)
428
455
 
429
456
  ---
@@ -448,6 +475,28 @@ The SDK consists of five core services:
448
475
  - **LoggerService** - Centralized logging with API key authentication
449
476
  - **RedisService** - Caching and queue management (optional)
450
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
+
451
500
  → [Architecture Details](docs/api-reference.md#architecture)
452
501
 
453
502
  ---
@@ -485,6 +534,83 @@ The SDK consists of five core services:
485
534
  - [Flask Decorators](docs/examples.md#flask-decorators) - Decorator-based auth
486
535
  - [Error Handling](docs/examples.md#error-handling) - Best practices
487
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
+
488
614
  ### Common Tasks
489
615
 
490
616
  **Add authentication middleware (FastAPI):**
@@ -31,10 +31,13 @@ The **AI Fabrix Miso Client SDK** provides authentication, authorization, and lo
31
31
  ### 📊 Compliance & Audit
32
32
 
33
33
  **ISO 27001 Compliance**
34
- - Comprehensive audit trails for all user actions
34
+ - Comprehensive audit trails for all user actions and HTTP requests
35
+ - Automatic data masking for all sensitive information in logs
36
+ - HTTP request/response audit logging with masked sensitive data
35
37
  - Data access logging and monitoring
36
38
  - Security event tracking
37
39
  - Accountability and non-repudiation
40
+ - Configurable sensitive fields via JSON configuration
38
41
 
39
42
  **Regulatory Compliance**
40
43
  - GDPR-ready data protection
@@ -85,9 +88,13 @@ The **AI Fabrix Miso Client SDK** provides authentication, authorization, and lo
85
88
 
86
89
  **Observability**
87
90
  - Centralized logging with correlation IDs
91
+ - Automatic HTTP request/response audit logging (ISO 27001 compliant)
92
+ - Debug logging with detailed request/response information (when `log_level='debug'`)
88
93
  - Performance tracking and metrics
89
94
  - Error tracking and debugging
90
95
  - Health monitoring
96
+ - Automatic data masking for sensitive information in logs
97
+ - Configurable sensitive fields via JSON configuration
91
98
 
92
99
  ---
93
100
 
@@ -213,7 +220,7 @@ if is_admin:
213
220
 
214
221
  ### Step 5: Activate Logging
215
222
 
216
- **What happens:** Application logs are sent to the Miso Controller with client token authentication.
223
+ **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.
217
224
 
218
225
  ```python
219
226
  from miso_client import MisoClient, load_config
@@ -229,10 +236,17 @@ user = await client.get_user(token)
229
236
  await client.log.info('User accessed dashboard', {'userId': user.id if user else None})
230
237
  await client.log.error('Operation failed', {'error': str(err)})
231
238
  await client.log.warn('Unusual activity', {'details': '...'})
239
+
240
+ # HTTP requests are automatically audited
241
+ # All sensitive data is automatically masked before logging
242
+ result = await client.http_client.get('/api/users')
243
+ # This automatically creates an audit log: http.request.GET with masked sensitive data
232
244
  ```
233
245
 
234
246
  **What happens to logs?** They're sent to the Miso Controller for centralized monitoring and analysis. Client token is automatically included.
235
247
 
248
+ **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).
249
+
236
250
  → [Complete logging example](examples/step-5-logging.py)
237
251
  → [Logging Reference](docs/api-reference.md#logger-service)
238
252
 
@@ -365,6 +379,7 @@ config = MisoClientConfig(
365
379
  port=6379,
366
380
  ),
367
381
  log_level="info", # Optional: 'debug' | 'info' | 'warn' | 'error'
382
+ # Set to 'debug' for detailed HTTP request/response logging
368
383
  api_key="your-test-api-key", # Optional: API key for testing (bypasses OAuth2)
369
384
  cache={ # Optional: Cache TTL settings
370
385
  "role_ttl": 900, # Role cache TTL (default: 900s)
@@ -375,6 +390,18 @@ config = MisoClientConfig(
375
390
 
376
391
  **Recommended:** Use `load_config()` to load from `.env` file automatically.
377
392
 
393
+ **ISO 27001 Data Masking Configuration:**
394
+
395
+ Sensitive fields are configured via `miso_client/utils/sensitive_fields_config.json`. You can customize this by:
396
+
397
+ 1. Setting `MISO_SENSITIVE_FIELDS_CONFIG` environment variable to point to a custom JSON file
398
+ 2. Using `DataMasker.set_config_path()` to set a custom path programmatically
399
+
400
+ The default configuration includes ISO 27001 compliant sensitive fields:
401
+ - Authentication: password, token, secret, key, auth, authorization
402
+ - PII: ssn, creditcard, cc, cvv, pin, otp
403
+ - Security: apikey, accesstoken, refreshtoken, privatekey, secretkey, cookie, session
404
+
378
405
  → [Complete Configuration Reference](docs/configuration.md)
379
406
 
380
407
  ---
@@ -399,6 +426,28 @@ The SDK consists of five core services:
399
426
  - **LoggerService** - Centralized logging with API key authentication
400
427
  - **RedisService** - Caching and queue management (optional)
401
428
 
429
+ ### HTTP Client Architecture
430
+
431
+ The SDK uses a two-layer HTTP client architecture for ISO 27001 compliance:
432
+
433
+ - **InternalHttpClient** - Core HTTP functionality with automatic client token management (internal)
434
+ - **HttpClient** - Public wrapper that adds automatic ISO 27001 compliant audit and debug logging
435
+
436
+ **Features:**
437
+ - Automatic audit logging for all HTTP requests (`http.request.{METHOD}`)
438
+ - Debug logging when `log_level === 'debug'` with detailed request/response information
439
+ - Automatic data masking using `DataMasker` before logging (ISO 27001 compliant)
440
+ - Sensitive endpoints (`/api/logs`, `/api/auth/token`) are excluded from audit logging to prevent infinite loops
441
+ - All sensitive data (headers, bodies, query params) is automatically masked before logging
442
+
443
+ **ISO 27001 Compliance:**
444
+ - All request headers are masked (Authorization, x-client-token, Cookie, etc.)
445
+ - All request bodies are recursively masked for sensitive fields (password, token, secret, SSN, etc.)
446
+ - All response bodies are masked (limited to first 1000 characters)
447
+ - Query parameters are automatically masked
448
+ - Error messages are masked if they contain sensitive data
449
+ - Sensitive fields configuration can be customized via `sensitive_fields_config.json`
450
+
402
451
  → [Architecture Details](docs/api-reference.md#architecture)
403
452
 
404
453
  ---
@@ -436,6 +485,83 @@ The SDK consists of five core services:
436
485
  - [Flask Decorators](docs/examples.md#flask-decorators) - Decorator-based auth
437
486
  - [Error Handling](docs/examples.md#error-handling) - Best practices
438
487
 
488
+ ---
489
+
490
+ ### Structured Error Responses
491
+
492
+ **What happens:** The SDK automatically parses structured error responses from the API (RFC 7807-style format) and makes them available through the `MisoClientError` exception.
493
+
494
+ ```python
495
+ from miso_client import MisoClient, MisoClientError, ErrorResponse, load_config
496
+
497
+ client = MisoClient(load_config())
498
+ await client.initialize()
499
+
500
+ try:
501
+ result = await client.http_client.get("/api/some-endpoint")
502
+ except MisoClientError as e:
503
+ # Check if structured error response is available
504
+ if e.error_response:
505
+ print(f"Error Type: {e.error_response.type}")
506
+ print(f"Error Title: {e.error_response.title}")
507
+ print(f"Status Code: {e.error_response.statusCode}")
508
+ print(f"Errors: {e.error_response.errors}")
509
+ print(f"Instance: {e.error_response.instance}")
510
+ else:
511
+ # Fallback to traditional error handling
512
+ print(f"Error: {e.message}")
513
+ print(f"Status Code: {e.status_code}")
514
+ print(f"Error Body: {e.error_body}")
515
+ ```
516
+
517
+ **Error Response Structure:**
518
+
519
+ The `ErrorResponse` model follows RFC 7807-style format:
520
+
521
+ ```json
522
+ {
523
+ "errors": [
524
+ "The user has provided input that the browser is unable to convert.",
525
+ "There are multiple rows in the database for the same value"
526
+ ],
527
+ "type": "/Errors/Bad Input",
528
+ "title": "Bad Request",
529
+ "statusCode": 400,
530
+ "instance": "/OpenApi/rest/Xzy"
531
+ }
532
+ ```
533
+
534
+ **Features:**
535
+
536
+ - **Automatic Parsing**: Structured error responses are automatically parsed from HTTP responses
537
+ - **Backward Compatible**: Falls back to traditional error handling when structured format is not available
538
+ - **Type Safety**: Full type hints with Pydantic models for reliable error handling
539
+ - **Generic Interface**: `ErrorResponse` model can be reused across different applications
540
+ - **Instance URI**: Automatically extracted from request URL if not provided in response
541
+
542
+ **Using ErrorResponse directly:**
543
+
544
+ ```python
545
+ from miso_client import ErrorResponse
546
+
547
+ # Create ErrorResponse from dict
548
+ error_data = {
549
+ "errors": ["Validation failed"],
550
+ "type": "/Errors/Validation",
551
+ "title": "Validation Error",
552
+ "statusCode": 422,
553
+ "instance": "/api/endpoint"
554
+ }
555
+ error_response = ErrorResponse(**error_data)
556
+
557
+ # Access fields
558
+ print(error_response.errors) # ["Validation failed"]
559
+ print(error_response.type) # "/Errors/Validation"
560
+ print(error_response.title) # "Validation Error"
561
+ print(error_response.statusCode) # 422
562
+ print(error_response.instance) # "/api/endpoint"
563
+ ```
564
+
439
565
  ### Common Tasks
440
566
 
441
567
  **Add authentication middleware (FastAPI):**
@@ -26,6 +26,7 @@ from .models.config import (
26
26
  RoleResult,
27
27
  UserInfo,
28
28
  )
29
+ from .models.error_response import ErrorResponse
29
30
  from .services.auth import AuthService
30
31
  from .services.cache import CacheService
31
32
  from .services.encryption import EncryptionService
@@ -35,8 +36,9 @@ from .services.redis import RedisService
35
36
  from .services.role import RoleService
36
37
  from .utils.config_loader import load_config
37
38
  from .utils.http_client import HttpClient
39
+ from .utils.internal_http_client import InternalHttpClient
38
40
 
39
- __version__ = "0.1.0"
41
+ __version__ = "0.4.0"
40
42
  __author__ = "AI Fabrix Team"
41
43
  __license__ = "MIT"
42
44
 
@@ -60,14 +62,29 @@ class MisoClient:
60
62
  config: MisoClient configuration including controller URL, client credentials, etc.
61
63
  """
62
64
  self.config = config
63
- self.http_client = HttpClient(config)
65
+
66
+ # Create InternalHttpClient first (pure HTTP functionality, no logging)
67
+ self._internal_http_client = InternalHttpClient(config)
68
+
69
+ # Create Redis service
64
70
  self.redis = RedisService(config.redis)
71
+
72
+ # Create LoggerService with InternalHttpClient (to avoid circular dependency)
73
+ # LoggerService uses InternalHttpClient for sending logs to prevent audit loops
74
+ self.logger = LoggerService(self._internal_http_client, self.redis)
75
+
76
+ # Create public HttpClient wrapping InternalHttpClient with logger
77
+ # This HttpClient adds automatic ISO 27001 compliant audit and debug logging
78
+ self.http_client = HttpClient(config, self.logger)
79
+
65
80
  # Cache service (uses Redis if available, falls back to in-memory)
66
81
  self.cache = CacheService(self.redis)
82
+
83
+ # Services use public HttpClient (with audit logging)
67
84
  self.auth = AuthService(self.http_client, self.redis)
68
85
  self.roles = RoleService(self.http_client, self.cache)
69
86
  self.permissions = PermissionService(self.http_client, self.cache)
70
- self.logger = LoggerService(self.http_client, self.redis)
87
+
71
88
  # Encryption service (reads ENCRYPTION_KEY from environment by default)
72
89
  self.encryption = EncryptionService()
73
90
  self.initialized = False
@@ -473,6 +490,7 @@ __all__ = [
473
490
  "ClientTokenResponse",
474
491
  "PerformanceMetrics",
475
492
  "ClientLoggingOptions",
493
+ "ErrorResponse",
476
494
  "AuthService",
477
495
  "RoleService",
478
496
  "PermissionService",
@@ -4,12 +4,21 @@ SDK exceptions and error handling.
4
4
  This module defines custom exceptions for the MisoClient SDK.
5
5
  """
6
6
 
7
+ from typing import TYPE_CHECKING
8
+
9
+ if TYPE_CHECKING:
10
+ from ..models.error_response import ErrorResponse
11
+
7
12
 
8
13
  class MisoClientError(Exception):
9
14
  """Base exception for MisoClient SDK errors."""
10
15
 
11
16
  def __init__(
12
- self, message: str, status_code: int | None = None, error_body: dict | None = None
17
+ self,
18
+ message: str,
19
+ status_code: int | None = None,
20
+ error_body: dict | None = None,
21
+ error_response: "ErrorResponse | None" = None,
13
22
  ):
14
23
  """
15
24
  Initialize MisoClient error.
@@ -18,11 +27,23 @@ class MisoClientError(Exception):
18
27
  message: Error message
19
28
  status_code: HTTP status code if applicable
20
29
  error_body: Sanitized error response body (secrets masked)
30
+ error_response: Structured error response object (RFC 7807-style)
21
31
  """
22
32
  super().__init__(message)
23
33
  self.message = message
24
34
  self.status_code = status_code
25
35
  self.error_body = error_body if error_body is not None else None
36
+ self.error_response = error_response
37
+
38
+ # Enhance message with structured error information if available
39
+ if error_response and error_response.errors:
40
+ if len(error_response.errors) == 1:
41
+ self.message = error_response.errors[0]
42
+ else:
43
+ self.message = f"{error_response.title}: {'; '.join(error_response.errors)}"
44
+ # Override status_code from structured response if available
45
+ if error_response.statusCode:
46
+ self.status_code = error_response.statusCode
26
47
 
27
48
 
28
49
  class AuthenticationError(MisoClientError):
@@ -0,0 +1,5 @@
1
+ """Pydantic models for MisoClient configuration and data types."""
2
+
3
+ from .error_response import ErrorResponse
4
+
5
+ __all__ = ["ErrorResponse"]