diff --git a/Agents/Implementation Agents/Trace Parser/TraceParserMCP/README.md b/Agents/Implementation Agents/Trace Parser/TraceParserMCP/README.md index de283180..e6240731 100644 --- a/Agents/Implementation Agents/Trace Parser/TraceParserMCP/README.md +++ b/Agents/Implementation Agents/Trace Parser/TraceParserMCP/README.md @@ -47,7 +47,7 @@ The Large Language Model (LLM) used with this MCP server is **entirely customer- - **Data accuracy depends on source traces.** The MCP server returns data as-is from the database. Analysis quality depends on the completeness and correctness of imported trace data. - **No built-in authentication.** The default configuration uses anonymous read access. Customers must implement appropriate authentication and network security for their deployment. - **AI analysis is non-deterministic.** Different AI models and prompts will produce different analysis results for the same trace data. Results should be verified by qualified engineers. -- **Read-only access.** The MCP server provides read and execute permissions only. It cannot modify trace data. +- **Read-only access.** Tables and views allow reads only. Procedure execution is limited to the four read-only keyword searches; trace deletion is not exposed by DAB. - **View-based analysis thresholds are fixed.** Analytical views (e.g., N+1 pattern detection at >100 DB calls, slow SQL at >5 seconds) use hardcoded thresholds that may not suit all scenarios. ### Disclaimers @@ -273,6 +273,8 @@ All server behavior is defined declaratively in `dab-config.json`. Key settings: - **GraphQL introspection:** Enabled - **REST request body:** Strict validation +The supplied configuration does not expose `DeleteTrace` and grants no table mutations on REST, GraphQL or MCP. Disabling MCP DML tools alone is not an authorization boundary for the other protocols. Keep deletion out of this public analysis API; [TraceParserWeb](../TraceParserWeb/README.md#authenticated-trace-deletion) provides a separate server-side path for signed-in users. + ## Third-Party Dependencies This project uses the following third-party components: diff --git a/Agents/Implementation Agents/Trace Parser/TraceParserMCP/dab-config.json b/Agents/Implementation Agents/Trace Parser/TraceParserMCP/dab-config.json index 27d3ff33..c0a39214 100644 --- a/Agents/Implementation Agents/Trace Parser/TraceParserMCP/dab-config.json +++ b/Agents/Implementation Agents/Trace Parser/TraceParserMCP/dab-config.json @@ -58,9 +58,6 @@ "actions": [ { "action": "read" - }, - { - "action": "delete" } ] } @@ -88,9 +85,6 @@ "actions": [ { "action": "read" - }, - { - "action": "delete" } ] } @@ -145,9 +139,6 @@ "actions": [ { "action": "read" - }, - { - "action": "delete" } ] } @@ -665,44 +656,6 @@ ] } ] - }, - "DeleteTrace": { - "description": "Delete a trace and all related data (TraceLines, UserSessions, etc.) by TraceId.", - "source": { - "object": "dbo.sp_DeleteTrace", - "type": "stored-procedure", - "parameters": [ - { - "name": "TraceId", - "required": false, - "default": "0" - } - ] - }, - "graphql": { - "enabled": true, - "operation": "mutation", - "type": { - "singular": "DeleteTrace", - "plural": "DeleteTraces" - } - }, - "rest": { - "enabled": true, - "methods": [ - "post" - ] - }, - "permissions": [ - { - "role": "anonymous", - "actions": [ - { - "action": "execute" - } - ] - } - ] } } } \ No newline at end of file diff --git a/Agents/Implementation Agents/Trace Parser/TraceParserWeb/README.md b/Agents/Implementation Agents/Trace Parser/TraceParserWeb/README.md index 1167b5bc..fe130145 100644 --- a/Agents/Implementation Agents/Trace Parser/TraceParserWeb/README.md +++ b/Agents/Implementation Agents/Trace Parser/TraceParserWeb/README.md @@ -98,3 +98,32 @@ For local dev, add to `appsettings.Development.json` or user secrets: } } ``` + +## Authenticated trace deletion + +Deletion is performed inside the Blazor server, not through the public DAB API. Immediately before accessing SQL, the service requires a signed-in user whose tenant claim matches the configured `AzureAd:TenantId`. **Every signed-in user in that tenant, including admitted guests, can delete any trace.** This is not an administrator-only or per-trace ownership policy. + +Deletion is disabled until `TraceAdministration:SqlConnectionString` is configured. On App Service the setting name is `TraceAdministration__SqlConnectionString`. Keep its value in protected server configuration (or a Key Vault reference), never in source, browser fields, logs, or saved agent profiles. The connection validates the SQL server certificate and requires encryption. + +Provision a dedicated database principal; do not reuse the SQL administrator, DAB, or importer credential. Prefer a managed identity where SQL Entra authentication is already configured. Alternatively, an operator can create a contained SQL user with a generated password and store that password securely. Grant only: + +```sql +GRANT EXECUTE ON OBJECT::dbo.sp_DeleteTrace TO [TraceParserWebDeletion]; +GRANT SELECT ON OBJECT::dbo.Traces TO [TraceParserWebDeletion]; +``` + +The principal must not belong to `db_owner`, `db_datawriter`, or other broad roles. The procedure relies on the normal same-owner SQL ownership chain; do not grant table-delete permissions to compensate for a broken chain. No SQL schema or procedure replacement is required by this change. + +The server repeats the existing procedure until a separate parameterized query confirms the trace is absent. This supports both the original procedure and incremental versions returning `HasMore`; one successful batch is not reported as a completed deletion. Errors and cancellation are surfaced, and the operation has a five-minute budget. A failed or timed-out operation can leave a partially deleted trace; refresh and retry. Do not delete traces while they are being imported. + +Deploy the updated **read-only** `TraceParserMCP/dab-config.json` as part of this update. Merely hiding the Delete button does not remove direct API access. Existing deployments must remove the `DeleteTrace` entity and table-delete grants, not just update the web application. Anonymous analysis remains unchanged; protect sensitive traces with appropriate network and read-access controls. + +`deploy.ps1` does not provision deletion credentials. Configure the dedicated principal and server setting separately, then restart the web app. If deletion is unavailable, retain the read-only DAB configuration rather than restoring public mutations. + +### Deletion regression checks + +The dependency-free console harness checks denied anonymous/wrong-tenant calls, ordinary tenant-user access, disabled configuration, incremental completion, failure/cancellation propagation, and read-only DAB permissions. It uses synthetic identities and a fake store, with no database or network calls: + +```powershell +dotnet run --project .\tests\TraceParserWeb.RegressionTests -c Release +``` diff --git a/Agents/Implementation Agents/Trace Parser/TraceParserWeb/TraceParserWeb/Components/Pages/Traces/TraceList.razor b/Agents/Implementation Agents/Trace Parser/TraceParserWeb/TraceParserWeb/Components/Pages/Traces/TraceList.razor index ed1ba1ea..1998b5ed 100644 --- a/Agents/Implementation Agents/Trace Parser/TraceParserWeb/TraceParserWeb/Components/Pages/Traces/TraceList.razor +++ b/Agents/Implementation Agents/Trace Parser/TraceParserWeb/TraceParserWeb/Components/Pages/Traces/TraceList.razor @@ -3,6 +3,7 @@ @using TraceParserWeb.Services @attribute [Authorize] @inject TraceService TraceSvc +@inject TraceDeletionService DeletionSvc @inject ILogger Logger @implements IDisposable @@ -20,6 +21,10 @@

Imported Traces

Manage imported ETL trace sessions.

+ @if (!DeletionSvc.IsConfigured) + { +

Deletion is unavailable until the deployment owner configures authenticated trace deletion.

+ }
@@ -107,7 +112,7 @@ } else { -