diff --git a/src/Backend/AutopilotMonitor.Functions.Tests/GetAgentConfigFunctionTests.cs b/src/Backend/AutopilotMonitor.Functions.Tests/GetAgentConfigFunctionTests.cs
index b1b54778..e2ecaadd 100644
--- a/src/Backend/AutopilotMonitor.Functions.Tests/GetAgentConfigFunctionTests.cs
+++ b/src/Backend/AutopilotMonitor.Functions.Tests/GetAgentConfigFunctionTests.cs
@@ -31,4 +31,27 @@ public class GetAgentConfigFunctionTests
var actual = GetAgentConfigFunction.ParseAgentMajor(agentVersion);
Assert.Equal(expectedMajor, actual);
}
+
+ [Theory]
+ // CustomerSas: gated on the per-tenant SAS URL being present.
+ [InlineData("https://acct.blob.core.windows.net/c?sv=...", "CustomerSas", true)]
+ [InlineData(null, "CustomerSas", false)]
+ [InlineData("", "CustomerSas", false)]
+ // Hosted: platform owns the storage, no per-tenant SAS URL — must still enable uploads.
+ // Regression guard for the bug where Hosted-destination tenants silently never uploaded.
+ [InlineData(null, "Hosted", true)]
+ [InlineData("", "Hosted", true)]
+ [InlineData(null, "hosted", true)] // case-insensitive
+ // Hosted with a SAS also set (belt-and-braces) stays enabled.
+ [InlineData("https://acct.blob.core.windows.net/c?sv=...", "Hosted", true)]
+ // Unknown/empty destination with no SAS → disabled (no silent uploads to nowhere).
+ [InlineData(null, null, false)]
+ [InlineData(null, "", false)]
+ [InlineData(null, "Bogus", false)]
+ public void ResolveDiagnosticsUploadEnabled_GatesOnSasOrHosted(
+ string? diagnosticsBlobSasUrl, string? destination, bool expected)
+ {
+ var actual = GetAgentConfigFunction.ResolveDiagnosticsUploadEnabled(diagnosticsBlobSasUrl, destination);
+ Assert.Equal(expected, actual);
+ }
}
diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs
index 4eeccf80..6ace3c77 100644
--- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs
+++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs
@@ -117,6 +117,19 @@ namespace AutopilotMonitor.Functions.Functions.Config
return int.TryParse(majorStr, out var major) ? major : 1;
}
+ ///
+ /// Decides whether the agent should perform diagnostics uploads at all.
+ /// The CustomerSas destination is gated on a per-tenant SAS URL being present, but the
+ /// Hosted destination has no such URL (the platform owns the storage) — so gating purely
+ /// on the SAS URL silently disabled uploads for every Hosted-destination tenant. Enable
+ /// when either a customer SAS is configured OR the destination is Hosted.
+ ///
+ internal static bool ResolveDiagnosticsUploadEnabled(string? diagnosticsBlobSasUrl, string? destination)
+ {
+ return !string.IsNullOrEmpty(diagnosticsBlobSasUrl)
+ || string.Equals(destination, "Hosted", StringComparison.OrdinalIgnoreCase);
+ }
+
///
/// Returns the (ZipSha256, ExeSha256) pair appropriate for the calling agent.
/// Reads the X-Agent-Version header, parses the major, and dispatches to the
@@ -197,7 +210,8 @@ namespace AutopilotMonitor.Functions.Functions.Config
EnrollmentSummaryBrandingImageUrl = tenantConfig.EnrollmentSummaryBrandingImageUrl,
EnrollmentSummaryLaunchRetrySeconds = tenantConfig.EnrollmentSummaryLaunchRetrySeconds ?? 120,
MaxBatchSize = tenantConfig.MaxBatchSize ?? 100,
- DiagnosticsUploadEnabled = !string.IsNullOrEmpty(tenantConfig.DiagnosticsBlobSasUrl),
+ DiagnosticsUploadEnabled = ResolveDiagnosticsUploadEnabled(
+ tenantConfig.DiagnosticsBlobSasUrl, tenantConfig.DiagnosticsUploadDestination),
DiagnosticsUploadMode = tenantConfig.DiagnosticsUploadMode ?? "Off",
DiagnosticsLogPaths = diagLogPaths,
Collectors = collectors,