diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt index 0914cc15..47eff070 100644 --- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt +++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt @@ -1 +1 @@ -865 +866 diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAdminConfigurationFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAdminConfigurationFunction.cs index 37096c34..4110b2ca 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAdminConfigurationFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAdminConfigurationFunction.cs @@ -35,6 +35,9 @@ namespace AutopilotMonitor.Functions.Functions.Config var config = await _adminConfigService.GetConfigurationAsync(); + // SECURITY NOTE: Returns full AdminConfiguration including NvdApiKey. + // Acceptable because this endpoint is GlobalAdminOnly (single user during preview). + // Consider masking NvdApiKey to a write-only sentinel before GA release. var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(config); return response; diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs index b9b03b11..f4b7b45f 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs @@ -37,6 +37,9 @@ namespace AutopilotMonitor.Functions.Functions.Config var config = await _configService.GetConfigurationAsync(requestCtx.TargetTenantId); + // NOTE: Returns full TenantConfiguration including DiagnosticsBlobSasUrl. + // Intentional — tenant admins need to view/manage the SAS URL in the Settings UI. + // Access restricted to TenantAdminOrGA by PolicyEnforcementMiddleware. var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(config); return response; diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Raw/TableQueryFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Raw/TableQueryFunction.cs index 12e16583..2f243dbb 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Raw/TableQueryFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Raw/TableQueryFunction.cs @@ -17,6 +17,9 @@ namespace AutopilotMonitor.Functions.Functions.Raw private readonly TableStorageService _storage; // Tables that must never be exposed (contain secrets) + // NOTE: Intentionally empty during preview — only Global Admin (single user) has access + // to this endpoint. Consider adding TenantConfiguration, AdminConfiguration, BootstrapSessions + // before GA release when more users may have Global Admin access. private static readonly HashSet _blacklistedTables = new(StringComparer.OrdinalIgnoreCase) { }; diff --git a/src/McpServer/autopilot-monitor-mcp/src/tools/search.ts b/src/McpServer/autopilot-monitor-mcp/src/tools/search.ts index 7226ba0c..58d4fe74 100644 --- a/src/McpServer/autopilot-monitor-mcp/src/tools/search.ts +++ b/src/McpServer/autopilot-monitor-mcp/src/tools/search.ts @@ -61,9 +61,27 @@ const KEYWORD_STOP_WORDS = new Set([ /** Short domain-specific terms that bypass the length filter. */ const DOMAIN_SHORT_KEYWORDS = new Set(['do', 'os', 'ad', 'ip', 'id']); +/** Multi-word domain phrases mapped to their technical search terms. */ +const DOMAIN_SYNONYMS: [RegExp, string][] = [ + [/\bdelivery\s+optimization\b/gi, 'do_telemetry'], + [/\bactive\s+directory\b/gi, 'aad'], + [/\benrollment\s+status\s+page\b/gi, 'esp'], + [/\bwindows\s+installer\b/gi, 'msi'], + [/\bintune\s+management\s+extension\b/gi, 'ime'], +]; + +/** Expand domain synonyms in the query before keyword extraction. */ +function expandSynonyms(query: string): string { + let expanded = query; + for (const [pattern, replacement] of DOMAIN_SYNONYMS) { + expanded = expanded.replace(pattern, `${replacement} $&`); + } + return expanded; +} + /** Extract meaningful keywords from a natural language query. */ function extractKeywords(query: string): string[] { - return query + return expandSynonyms(query) .toLowerCase() .replace(/[^\w\s-]/g, ' ') .split(/\s+/)