From 6aa8456095337cc1492f10b489003227bd887e8a Mon Sep 17 00:00:00 2001 From: Debasis Ghosh <65386308+debdevops@users.noreply.github.com> Date: Sun, 26 Apr 2026 20:54:47 +0530 Subject: [PATCH] Enhance documentation and safety guidelines for production usage; update telemetry to redact sensitive data --- .gitignore | 4 +- README.md | 53 ++++++++++++- .../messages/MessageDetailPanel.tsx | 2 +- apps/web/src/lib/helpContent.ts | 6 +- apps/web/src/lib/telemetry.ts | 27 ++++--- apps/web/src/pages/ConnectPage.tsx | 19 ++++- apps/web/src/pages/WelcomePage.tsx | 78 +++++++++++++++++++ .../SensitiveDataTelemetryProcessor.cs | 47 +++++++++-- 8 files changed, 213 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index b43412a..deaf14d 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,6 @@ project.nuget.cache *.prompt.local.md .github/copilot-cache/ .github/README.md -How-To-Use.md \ No newline at end of file +How-To-Use.md + +docs/linkedin \ No newline at end of file diff --git a/README.md b/README.md index 5692e64..0f5ad15 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,22 @@ Real-time runtime metrics for the ServiceHub API itself: uptime, memory usage, t --- +## 🚦 Recommended Usage Flow + +Follow this path before connecting to a production namespace. This protects your live environment and gives you confidence in every operation before it matters. + +| Step | Environment | Goal | +|------|-------------|------| +| **Step 1** | **DEV** | Connect your development Service Bus namespace. Explore message browsing, DLQ inspection, AI pattern analysis, and auto-replay rules in a safe environment where mistakes are harmless. | +| **Step 2** | **UAT** | Repeat in your UAT namespace with realistic production-like data. Validate replay targets, confirm rule logic, review AI findings, and check that scheduled messages behave as expected. | +| **Step 3** | **PROD** | Connect only after DEV and UAT validation. Production namespaces enforce read-only browsing by default — Quick Actions (replay, send, generate) are disabled to prevent accidental data modification. | + +> āš ļø **Do NOT connect a production Service Bus namespace without prior validation in DEV and UAT.** +> While ServiceHub is read-only by default, replay and send operations are destructive. +> Validate your replay rules and message targets in lower environments first. + +--- + ## ⚔ Quick Start ### One-Command Setup (Recommended) @@ -356,14 +372,45 @@ For deep-dive architecture details, see [services/api/ARCHITECTURE.md](services/ --- -## šŸ›”ļø Security & Safety +## šŸ›”ļø Security & Privacy + +### What ServiceHub guarantees - **Read-only by default** — Uses `PeekMessagesAsync`; messages are **never removed or consumed** - **Minimal permissions** — Full functionality with Listen-only access -- **AES-GCM encryption** — Connection strings encrypted at rest; key stored in local config +- **AES-GCM encryption** — Connection strings encrypted at rest; key stored in local config, never returned to the browser - **Zero external calls** — AI analysis runs entirely in-browser; no message data leaves your environment -- **No message persistence** — Messages displayed in-memory only during your session +- **No message persistence** — Messages are displayed in-memory only during your session; never written to a database - **Production-safe** — Won't interfere with your active message consumers +- **Log redaction** — Backend logging pipeline strips connection strings, API keys, and access tokens before any log output + +### What ServiceHub does NOT collect or store + +| Data | Stored? | Notes | +|------|---------|-------| +| Connection strings | āŒ Never in plaintext | AES-GCM encrypted at rest; decrypted in memory only during use | +| Message bodies | āŒ Never | Displayed in-browser session memory only; not logged or persisted | +| User data / PII | āŒ Never | No user database exists | +| Message correlation IDs (business) | āŒ Never logged | Infrastructure correlation IDs for request tracing only | +| Customer / tenant data | āŒ Never | Messages never leave your own infrastructure | + +### Application Insights telemetry (privacy-safe) + +ServiceHub optionally emits telemetry to Azure Application Insights. When enabled, telemetry is strictly limited to: + +- **Request durations** and HTTP status codes (not request/response bodies) +- **Error codes** and exception types (not exception messages containing secrets) +- **System-level metrics** — memory, GC, thread counts + +The following is **explicitly excluded** from telemetry: + +- Connection strings (redacted by `SensitiveDataTelemetryProcessor` and `LogRedactor`) +- Message bodies and payloads (message-body API endpoints excluded from auto-tracking) +- Business-level correlation IDs from message content +- User input fields +- API keys and tokens (redacted from query strings and headers) + +Application Insights is **disabled by default** — it only activates when `ApplicationInsights:ConnectionString` is configured in `appsettings.Local.json`. --- diff --git a/apps/web/src/components/messages/MessageDetailPanel.tsx b/apps/web/src/components/messages/MessageDetailPanel.tsx index 3800ab9..9085be6 100644 --- a/apps/web/src/components/messages/MessageDetailPanel.tsx +++ b/apps/web/src/components/messages/MessageDetailPanel.tsx @@ -126,7 +126,7 @@ function ActionButtons({ message, namespaceId }: ActionButtonsProps) { setConfirmState({ isOpen: true, title: 'Replay Message', - message: `Are you sure you want to replay message ${shortId}?\n\nThis will re-send the message to the queue for processing.\n\nāš ļø Replay is best-effort and not atomic. If a transient error occurs after the message is sent but before it is removed from the DLQ, both the original DLQ entry and the new copy may briefly coexist. Check ApplicationProperties for "Replayed=true" if you see unexpected duplicates.`, + message: `Are you sure you want to replay message ${shortId}?\n\nThis will re-send the message to the queue for processing.\n\nšŸ’” Best practice: validate replay in DEV or UAT before using in PROD. Production namespaces block this action.\n\nāš ļø Replay is best-effort and not atomic. If a transient error occurs after the message is sent but before it is removed from the DLQ, both the original DLQ entry and the new copy may briefly coexist. Check ApplicationProperties for "Replayed=true" if you see unexpected duplicates.`, variant: 'default', action: 'replay', }); diff --git a/apps/web/src/lib/helpContent.ts b/apps/web/src/lib/helpContent.ts index df956ce..36cf307 100644 --- a/apps/web/src/lib/helpContent.ts +++ b/apps/web/src/lib/helpContent.ts @@ -103,10 +103,10 @@ export const tooltips = { 'Use the tabs to view Properties (metadata), Body (payload), AI Analysis (pattern detection), System Info, and Actions (replay / complete).', } as TooltipContent, replay: { - text: 'Resubmit this dead-letter message', + text: 'Resubmit this dead-letter message — use in DEV/UAT before PROD', detail: - 'Sends the message back to the original queue for reprocessing. Only available in Dev/UAT environments. Production namespaces block this action.', - action: 'Fix the root cause first, then click Replay.', + 'Sends the message back to the original queue for reprocessing. Recommended: validate replay behaviour in DEV or UAT before applying to production traffic. Production namespaces block this action for safety.', + action: 'Fix the root cause first, validate in DEV/UAT, then click Replay.', } as TooltipContent, search: { text: 'Filter messages by content', diff --git a/apps/web/src/lib/telemetry.ts b/apps/web/src/lib/telemetry.ts index 6393700..52cb57c 100644 --- a/apps/web/src/lib/telemetry.ts +++ b/apps/web/src/lib/telemetry.ts @@ -13,22 +13,31 @@ const appInsights = new ApplicationInsights({ // Cost-effective settings samplingPercentage: Number(import.meta.env.VITE_APPINSIGHTS_SAMPLING_PERCENTAGE) || 50, - disableFetchTracking: false, enableCorsCorrelation: true, enableAutoRouteTracking: true, - // Reduce telemetry volume - maxBatchInterval: 15000, // Batch every 15s instead of default 5s - maxBatchSizeInBytes: 102400, // 100KB batch size - disableExceptionTracking: false, // Keep exception tracking (critical) - disableAjaxTracking: false, // Keep API call tracking - - // Exclude health check and noisy internal endpoints from AJAX tracking - correlationHeaderExcludedDomains: [], + // ── Privacy & security ──────────────────────────────────────────── + // Never capture request or response bodies — message content must not be sent to telemetry + disableAjaxTracking: false, // Track API call durations and status codes (not bodies) + disableFetchTracking: false, // Track fetch durations and status codes (not bodies) + // Do NOT log any user input or identifiers to telemetry + disableCookiesUsage: true, + // Do NOT add correlation headers to cross-origin Service Bus requests + correlationHeaderExcludedDomains: ['*.servicebus.windows.net', '*.azure.com'], + // Exclude endpoints that carry message body data from AJAX auto-tracking excludeRequestFromAutoTrackingPatterns: [ + /\/api\/v1\/namespaces\/[^/]+\/queues\/[^/]+\/messages/i, + /\/api\/v1\/namespaces\/[^/]+\/topics\//i, + /\/api\/v1\/correlation/i, /\/health/i, /\/internal\//i, ], + // ───────────────────────────────────────────────────────────────── + + // Reduce telemetry volume + maxBatchInterval: 15000, // Batch every 15s instead of default 5s + maxBatchSizeInBytes: 102400, // 100KB batch size + disableExceptionTracking: false, // Keep exception tracking (critical for error monitoring) }, }); diff --git a/apps/web/src/pages/ConnectPage.tsx b/apps/web/src/pages/ConnectPage.tsx index dfd24d2..8160e74 100644 --- a/apps/web/src/pages/ConnectPage.tsx +++ b/apps/web/src/pages/ConnectPage.tsx @@ -303,7 +303,24 @@ export function ConnectPage() { -

Production disables Quick Actions for safety.

+

+ {environment === 'prod' ? ( + <> + āš ļø Production namespace: + {' '}Quick Actions (replay, send, generate) are disabled for safety. Validate your workflow in DEV and UAT first. + + ) : environment === 'uat' ? ( + <> + UAT namespace: + {' '}Validate replay rules and DLQ behaviour here before connecting to PROD. + + ) : ( + <> + Recommended: start with a DEV namespace. + {' '}Test DLQ inspection, replay rules, and message operations safely before moving to UAT or PROD. + + )} +