Runtime Parameters (Agent)
- The effective values the agent receives at runtime, with defaults applied for unset fields.
- The tag says where a value is resolved from: tenant config, global config, the tenant's entitlement, or a fixed backend constant.
+ What an agent of this tenant receives from the backend right now, resolved server-side.
+ The tag says which knob a value comes from: tenant config, global config, the tenant's entitlement, or a fixed agent default.
- {RUNTIME_REPORT_SECTIONS.map(({ section, rows }) => (
-
- {rows.map(({ key, row }) => {
- const value = row.value(runtimeCtx);
+ {!effective && (
+
+ Effective agent configuration not available.
+
+ )}
+
+ {effective && RUNTIME_REPORT_SECTIONS.map(({ section, rows }) => (
+
+ {rows.map(({ key, row, value: read, default: def }) => {
+ const value = read(effective);
return (
);
})}
diff --git a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/__tests__/tenantConfigReportCatalog.test.ts b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/__tests__/tenantConfigReportCatalog.test.ts
index e3692524..5e6126e1 100644
--- a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/__tests__/tenantConfigReportCatalog.test.ts
+++ b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/__tests__/tenantConfigReportCatalog.test.ts
@@ -2,28 +2,29 @@
* Parity pins for the Tenant Config Report catalog.
*
* The catalog is compile-time exhaustive over the generated wire types; this file adds the
- * runtime half against SHARED_MANIFEST.tenantConfiguration.fields (the C#-reflected field
- * list, independent of the TS type) and pins the runtime resolution rules that mirror
- * GetAgentConfigFunction.cs with test-local fixtures.
+ * runtime half against the shared manifest (the C#-reflected field lists and initializer
+ * defaults, independent of the TS types): every field is catalogued, every catalogued field
+ * has a default to compare against, and the value accessors read the effective agent config
+ * the backend returns. The derivation rules themselves are pinned in the backend
+ * (AgentConfigResolverTests) — nothing is re-computed here.
*/
import { describe, expect, it } from "vitest";
import { SHARED_MANIFEST } from "@/utils/shared-manifests.generated";
-import type { AdminConfiguration, TenantConfiguration, TenantFeatureFlagsResponse } from "@/utils/wire-types.generated";
+import type { AgentConfigResponse } from "@/utils/wire-types.generated";
import {
ANALYZER_FIELDS,
COLLECTOR_FIELDS,
- DEFAULT_UPLOAD_INTERVAL_SECONDS,
isExcluded,
isNonDefault,
RUNTIME_FIELDS,
RUNTIME_REPORT_SECTIONS,
+ RUNTIME_SECTIONS_COLLAPSED,
TENANT_FIELDS,
TENANT_REPORT_SECTIONS,
- UNRESOLVED,
- type RuntimeContext,
} from "../tenantConfigReportCatalog";
const manifestFields = [...SHARED_MANIFEST.tenantConfiguration.fields] as string[];
+const manifestDefaults = SHARED_MANIFEST.tenantConfiguration.defaults as Record;
describe("TENANT_FIELDS parity with the C# field manifest", () => {
it("catalogues every wire field of TenantConfiguration (rendered or excluded with a reason)", () => {
@@ -36,6 +37,11 @@ describe("TENANT_FIELDS parity with the C# field manifest", () => {
expect(stale).toEqual([]);
});
+ it("the manifest carries an initializer default for every field", () => {
+ const withoutDefault = manifestFields.filter((f) => !(f in manifestDefaults));
+ expect(withoutDefault).toEqual([]);
+ });
+
it("gives every exclusion a reason and every row a non-empty label", () => {
for (const [key, spec] of Object.entries(TENANT_FIELDS)) {
if (isExcluded(spec)) expect(spec.excluded, key).not.toBe("");
@@ -44,7 +50,7 @@ describe("TENANT_FIELDS parity with the C# field manifest", () => {
});
it("renders the fields the operator asked for by name", () => {
- const rendered = new Set(TENANT_REPORT_SECTIONS.flatMap((s) => s.rows.map((r) => r.key)));
+ const rendered = new Set(TENANT_REPORT_SECTIONS.flatMap((s) => s.rows.map((r) => r.key as string)));
for (const key of [
"payingCustomer", "maxDelegatedTenantsOverride", "mcpUsagePlanOverride", "managedByProTenantId",
"trialConsumed", "proDowngradedUtc", "validateDeviceAssociation", "validateCloudPcDevice",
@@ -56,154 +62,94 @@ describe("TENANT_FIELDS parity with the C# field manifest", () => {
}
});
- it("renders each field in exactly one section", () => {
+ it("renders each field in exactly one section, with its manifest default attached", () => {
const seen = new Map();
for (const { rows } of TENANT_REPORT_SECTIONS) {
- for (const { key } of rows) seen.set(key, (seen.get(key) ?? 0) + 1);
+ for (const { key, default: def } of rows) {
+ seen.set(key, (seen.get(key) ?? 0) + 1);
+ expect(def, key).toEqual(manifestDefaults[key]);
+ }
}
expect([...seen.entries()].filter(([, n]) => n !== 1)).toEqual([]);
});
+
+ it("secrets, masked values and timestamps are informational (never marked custom)", () => {
+ for (const [key, spec] of Object.entries(TENANT_FIELDS)) {
+ if (isExcluded(spec)) continue;
+ if (spec.kind === "secret" || spec.kind === "masked" || spec.kind === "date") {
+ expect(spec.informational, key).toBe(true);
+ }
+ }
+ });
+
+ it("pins a few manifest defaults the report relies on", () => {
+ expect(manifestDefaults.planTier).toBe("free");
+ expect(manifestDefaults.dataRetentionDays).toBe(90);
+ expect(manifestDefaults.diagnosticsUploadDestination).toBe("CustomerSas");
+ expect(manifestDefaults.payingCustomer).toBe(false);
+ // The one string default the table read also applies to a blank cell — a stored
+ // "time.windows.com" must not read as custom.
+ expect(manifestDefaults.ntpServer).toBe("time.windows.com");
+ });
});
-// ── Runtime rules ────────────────────────────────────────────────────────────
+// ── Runtime catalog ──────────────────────────────────────────────────────────
-/** Minimal stored config: everything nullable unset, non-nullables at their C# initializers. */
-function storedConfig(overrides: Partial = {}): TenantConfiguration {
- return {
- tenantId: "00000000-0000-0000-0000-000000000001",
- domainName: "contoso.example",
- lastUpdated: "2026-09-06T00:00:00Z",
- updatedBy: "ga@operator.example",
- disabled: false,
- mcpDisabled: false,
- planTier: "free",
- trialConsumed: false,
- payingCustomer: false,
- manufacturerWhitelist: "Dell*,HP*,Lenovo*,Microsoft Corporation",
- modelWhitelist: "*",
- validateAutopilotDevice: false,
- validateCorporateIdentifier: false,
- validateDeviceAssociation: false,
- validateCloudPcDevice: false,
- validateIntuneDeviceBinding: false,
- allowInsecureAgentRequests: false,
- dataRetentionDays: 90,
- sessionTimeoutHours: 5,
- sessionGraceHours: 0,
- maxNdjsonPayloadSizeMB: 5,
- enablePerformanceCollector: true,
- performanceCollectorIntervalSeconds: 30,
- helloWaitTimeoutSeconds: 30,
- ntpServer: "time.windows.com",
- logLevel: "",
- enrollmentSummaryBrandingImageUrl: "",
- localAdminAllowedAccountsJson: "",
- bootstrapTokenEnabled: false,
- unrestrictedModeEnabled: false,
- unrestrictedMode: false,
- entraAppRolesEnabled: false,
- diagnosticsLogPathsJson: "",
- diagnosticsBlobSasUrl: "",
- diagnosticsUploadMode: "Off",
- diagnosticsUploadDestination: "CustomerSas",
- sendTraceEvents: true,
- teamsWebhookUrl: "",
- teamsNotifyOnSuccess: true,
- teamsNotifyOnFailure: true,
- teamsNotifyOnStart: false,
- webhookProviderType: 0,
- webhookUrl: "",
- webhookNotifyOnSuccess: true,
- webhookNotifyOnFailure: true,
- webhookNotifyOnHardwareRejection: false,
- webhookNotifyOnStart: false,
- webhookCustomHeadersJson: "",
- notificationChannelsJson: "",
- slaNotifyOnSuccessRateBreach: false,
- slaNotifyOnDurationBreach: false,
- slaNotifyOnAppInstallBreach: false,
- slaNotifyOnConsecutiveFailures: false,
- slaConsecutiveFailureThreshold: 5,
- ...overrides,
- };
-}
+const agentDefaults = SHARED_MANIFEST.agentConfig;
-const adminConfig = { collectorIdleTimeoutMinutes: 25, desktopDetectorNoCandidateTimeoutMinutes: 7, allowAgentDowngrade: true, modernDeploymentHarmlessEventIdsJson: "[100, 42]" } as AdminConfiguration;
-const flags = (unrestrictedMode: boolean) => ({ unrestrictedMode }) as TenantFeatureFlagsResponse;
-
-const ctx = (overrides: Partial = {}, extra: Partial = {}): RuntimeContext => ({
- config: storedConfig(overrides),
- adminConfig: null,
- flags: null,
- ...extra,
-});
-
-const runtimeValue = (record: typeof RUNTIME_FIELDS | typeof COLLECTOR_FIELDS | typeof ANALYZER_FIELDS, key: string, c: RuntimeContext) => {
- const spec = (record as Record)[key];
- if (!spec || isExcluded(spec)) throw new Error(`${key} is not a rendered runtime row`);
- return spec.value(c);
-};
-
-describe("runtime rows mirror GetAgentConfigFunction", () => {
- it("upload interval is the backend constant (10), not the old 30", () => {
- expect(DEFAULT_UPLOAD_INTERVAL_SECONDS).toBe(10);
- expect(runtimeValue(RUNTIME_FIELDS, "uploadIntervalSeconds", ctx())).toBe(10);
- });
-
- it("diagnostics upload is enabled by a SAS URL or the hosted destination, regardless of mode", () => {
- expect(runtimeValue(RUNTIME_FIELDS, "diagnosticsUploadEnabled", ctx())).toBe(false);
- expect(runtimeValue(RUNTIME_FIELDS, "diagnosticsUploadEnabled", ctx({ diagnosticsUploadDestination: "Hosted" }))).toBe(true);
- expect(runtimeValue(RUNTIME_FIELDS, "diagnosticsUploadEnabled", ctx({ diagnosticsBlobSasUrl: "https://x.blob.core.windows.net/c?sig=1", diagnosticsUploadMode: "Off" }))).toBe(true);
- });
-
- it("unrestricted mode comes from the entitlement flags, never from the stored toggle alone", () => {
- expect(runtimeValue(RUNTIME_FIELDS, "unrestrictedMode", ctx({ unrestrictedModeEnabled: true, unrestrictedMode: true }))).toBe(UNRESOLVED);
- expect(runtimeValue(RUNTIME_FIELDS, "unrestrictedMode", ctx({ unrestrictedModeEnabled: true, unrestrictedMode: true }, { flags: flags(false) }))).toBe(false);
- expect(runtimeValue(RUNTIME_FIELDS, "unrestrictedMode", ctx({}, { flags: flags(true) }))).toBe(true);
- });
-
- it("operator knobs resolve from the global config and are unresolved without it", () => {
- expect(runtimeValue(COLLECTOR_FIELDS, "collectorIdleTimeoutMinutes", ctx())).toBe(UNRESOLVED);
- const c = ctx({}, { adminConfig });
- expect(runtimeValue(COLLECTOR_FIELDS, "collectorIdleTimeoutMinutes", c)).toBe(25);
- expect(runtimeValue(COLLECTOR_FIELDS, "desktopDetectorNoCandidateTimeoutMinutes", c)).toBe(7);
- expect(runtimeValue(COLLECTOR_FIELDS, "modernDeploymentHarmlessEventIds", c)).toEqual([100, 42]);
- expect(runtimeValue(RUNTIME_FIELDS, "allowAgentDowngrade", c)).toBe(true);
- });
-
- it("applies the analyzer defaults of the agent config builder", () => {
- const c = ctx();
- expect(runtimeValue(ANALYZER_FIELDS, "enableLocalAdminAnalyzer", c)).toBe(true);
- expect(runtimeValue(ANALYZER_FIELDS, "enableIntegrityBypassAnalyzer", c)).toBe(true);
- expect(runtimeValue(ANALYZER_FIELDS, "enableConsoleBypassDetection", c)).toBe(true);
- expect(runtimeValue(ANALYZER_FIELDS, "enableSoftwareInventoryAnalyzer", c)).toBe(false);
- expect(runtimeValue(ANALYZER_FIELDS, "enableRealmJoinWatcher", c)).toBe(false);
- expect(runtimeValue(ANALYZER_FIELDS, "keepAwakeDuringUserEsp", c)).toBe(false);
- expect(runtimeValue(ANALYZER_FIELDS, "localAdminAllowedAccounts", ctx({ localAdminAllowedAccountsJson: '["Admin","Helpdesk"]' }))).toEqual(["Admin", "Helpdesk"]);
- expect(runtimeValue(ANALYZER_FIELDS, "localAdminAllowedAccounts", ctx({ localAdminAllowedAccountsJson: "not json" }))).toEqual([]);
- });
-
- it("nullable agent knobs fall back to the agent defaults", () => {
- const c = ctx();
- expect(runtimeValue(RUNTIME_FIELDS, "maxAuthFailures", c)).toBe(5);
- expect(runtimeValue(RUNTIME_FIELDS, "authFailureTimeoutMinutes", c)).toBe(0);
- expect(runtimeValue(RUNTIME_FIELDS, "logLevel", ctx({ logLevel: null as unknown as string }))).toBe("Info");
- expect(runtimeValue(RUNTIME_FIELDS, "ntpServer", ctx({ ntpServer: "" }))).toBe("time.windows.com");
- expect(runtimeValue(COLLECTOR_FIELDS, "agentMaxLifetimeMinutes", c)).toBe(360);
- expect(runtimeValue(RUNTIME_FIELDS, "rebootDelaySeconds", ctx({ rebootDelaySeconds: 30 }))).toBe(30);
+describe("runtime catalogs parity with the agent-config defaults manifest", () => {
+ it.each([
+ ["responseDefaults", RUNTIME_FIELDS],
+ ["collectorDefaults", COLLECTOR_FIELDS],
+ ["analyzerDefaults", ANALYZER_FIELDS],
+ ] as const)("%s ↔ catalog: same key set", (section, record) => {
+ const keys = Object.keys(agentDefaults[section]);
+ expect(keys.filter((k) => !(k in record))).toEqual([]);
+ expect(Object.keys(record).filter((k) => !keys.includes(k))).toEqual([]);
});
it("renders every runtime row in exactly one section", () => {
const keys = RUNTIME_REPORT_SECTIONS.flatMap((s) => s.rows.map((r) => r.key));
expect(new Set(keys).size).toBe(keys.length);
expect(keys).toContain("uploadIntervalSeconds");
- expect(keys).toContain("collectorIdleTimeoutMinutes");
- expect(keys).toContain("enableConsoleBypassDetection");
+ expect(keys).toContain("collectors.collectorIdleTimeoutMinutes");
+ expect(keys).toContain("analyzers.enableConsoleBypassDetection");
+ expect(keys).toContain("configVersion");
+ expect(keys).not.toContain("deviceKillSignal");
+ });
+
+ it("collapsed sections exist in the section list", () => {
+ const sections = new Set(RUNTIME_REPORT_SECTIONS.map((s) => s.section));
+ for (const s of RUNTIME_SECTIONS_COLLAPSED) expect(sections.has(s), s).toBe(true);
+ });
+
+ it("value accessors read the top level and the two sub-objects of the response", () => {
+ const response = {
+ uploadIntervalSeconds: 10,
+ collectors: { collectorIdleTimeoutMinutes: 25 },
+ analyzers: { enableConsoleBypassDetection: false },
+ diagnosticsLogPaths: [{ path: "a" }, { path: "b" }],
+ } as unknown as AgentConfigResponse;
+ const byKey = new Map(RUNTIME_REPORT_SECTIONS.flatMap((s) => s.rows.map((r) => [r.key, r] as const)));
+
+ expect(byKey.get("uploadIntervalSeconds")!.value(response)).toBe(10);
+ expect(byKey.get("collectors.collectorIdleTimeoutMinutes")!.value(response)).toBe(25);
+ expect(byKey.get("analyzers.enableConsoleBypassDetection")!.value(response)).toBe(false);
+ expect(byKey.get("diagnosticsLogPaths")!.row.kind).toBe("count");
+ expect(byKey.get("diagnosticsLogPaths")!.value(response)).toHaveLength(2);
+ });
+
+ it("pins the agent defaults the report highlights against", () => {
+ expect(agentDefaults.responseDefaults.uploadIntervalSeconds).toBe(10);
+ expect(agentDefaults.responseDefaults.maxBatchSize).toBe(100);
+ expect(agentDefaults.collectorDefaults.collectorIdleTimeoutMinutes).toBe(15);
+ expect(agentDefaults.analyzerDefaults.enableIntegrityBypassAnalyzer).toBe(true);
+ expect(agentDefaults.analyzerDefaults.enableRealmJoinWatcher).toBe(false);
});
});
describe("isNonDefault", () => {
- it("treats null and undefined as one value and compares arrays by content", () => {
+ it("treats null, undefined and the empty string as one value and compares arrays by content", () => {
expect(isNonDefault(undefined, null)).toBe(false);
expect(isNonDefault("", null)).toBe(false);
expect(isNonDefault("", "Off")).toBe(true);
diff --git a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts
index 337c0bea..cddb2a6a 100644
--- a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts
+++ b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/tenantConfigReportCatalog.ts
@@ -4,39 +4,56 @@
* Both halves of the report are exhaustive over the generated wire types: `TENANT_FIELDS`
* over every key of `TenantConfiguration` (GET config/{tenantId}) and `RUNTIME_FIELDS` /
* `COLLECTOR_FIELDS` / `ANALYZER_FIELDS` over every key of `AgentConfigResponse` and its two
- * sub-objects (what GET agent/config serves). A key is either rendered (a row with section
- * and label) or excluded with a reason — nothing can be silently forgotten: a new C# property
- * forces the wire-type regeneration (SharedManifestParityTests) and `tsc` then fails here
- * until the key is catalogued. The vitest next to this module pins the same thing at runtime
- * against `SHARED_MANIFEST.tenantConfiguration.fields`.
+ * sub-objects (GET config/{tenantId}/effective-agent-config — the backend's own derivation,
+ * nothing is re-computed here). A key is either rendered (a row with section and label) or
+ * excluded with a reason — nothing can be silently forgotten: a new C# property forces the
+ * wire-type regeneration (SharedManifestParityTests) and `tsc` then fails here until the key
+ * is catalogued.
*
- * Runtime rows mirror the resolution rules of GetAgentConfigFunction.cs (backend); every
- * rule carries the source it reads from so the operator sees which knob to turn.
+ * The "custom" highlight compares a value against the C# initializer of the same property,
+ * which the shared manifest carries as `defaults` (generated by the same test) — no
+ * hand-copied default anywhere in this file.
*/
+import { SHARED_MANIFEST } from "@/utils/shared-manifests.generated";
import type {
- AdminConfiguration,
AgentConfigResponse,
AnalyzerConfiguration,
CollectorConfiguration,
TenantConfiguration,
- TenantFeatureFlagsResponse,
} from "@/utils/wire-types.generated";
+// ── Defaults from the manifest (compile-time complete over the wire types) ────
+
+export const TENANT_DEFAULTS: Record = SHARED_MANIFEST.tenantConfiguration.defaults;
+export const RUNTIME_DEFAULTS: Record = SHARED_MANIFEST.agentConfig.responseDefaults;
+export const COLLECTOR_DEFAULTS: Record = SHARED_MANIFEST.agentConfig.collectorDefaults;
+export const ANALYZER_DEFAULTS: Record = SHARED_MANIFEST.agentConfig.analyzerDefaults;
+
// ── Row model ────────────────────────────────────────────────────────────────
-/** How a value is rendered. `secret` never shows the value, only whether one is set. */
-export type RowKind = "value" | "date" | "masked" | "secret";
+/**
+ * How a value is rendered. `secret` never shows the value, only whether one is set;
+ * `count` shows the length of a list.
+ */
+export type RowKind = "value" | "date" | "masked" | "secret" | "count";
-export interface TenantRow {
- section: TenantSection;
+interface RowBase {
label: string;
kind?: RowKind;
- /**
- * The C# initializer of TenantConfiguration.cs. A row WITH this key (even `null`) is
- * compared against it and highlighted as "custom" when the stored value differs; a row
- * without it is informational and never highlighted.
- */
- default?: unknown;
+ /** Informational rows (reasons, timestamps, identities, secrets) are never marked "custom". */
+ informational?: true;
+}
+
+export interface TenantRow extends RowBase {
+ section: TenantSection;
+}
+
+/** Which knob a runtime value is resolved from (AgentConfigResolver.Build). */
+export type RuntimeSource = "tenant" | "global" | "entitlement" | "fixed";
+
+export interface RuntimeRow extends RowBase {
+ section: RuntimeSection;
+ source: RuntimeSource;
}
export interface Excluded {
@@ -65,8 +82,6 @@ export const TENANT_SECTIONS = [
] as const;
export type TenantSection = (typeof TENANT_SECTIONS)[number];
-const NTP_DEFAULT = "time.windows.com";
-
// ── Tenant configuration (left column) ───────────────────────────────────────
const HEADER = { excluded: "shown in the tenant header card" } as const;
@@ -79,98 +94,97 @@ export const TENANT_FIELDS: Record = new Set(["Collector Internals"]);
-export interface RuntimeRow {
- section: RuntimeSection;
- label: string;
- source: RuntimeSource;
- /** Backend resolution rule (GetAgentConfigFunction.cs). */
- value: (ctx: RuntimeContext) => unknown;
- /** The agent-side default (AgentConfigResponse.cs / AdminConfiguration.cs initializer) for the "custom" highlight. */
- default?: unknown;
-}
-
-/** Shared.Constants.DefaultUploadIntervalSeconds — the one runtime constant not on any config row. */
-export const DEFAULT_UPLOAD_INTERVAL_SECONDS = 10;
-
-/** GetAgentConfigFunction.ResolveDiagnosticsUploadEnabled: a SAS URL or the hosted destination, regardless of mode. */
-export const resolveDiagnosticsUploadEnabled = (c: TenantConfiguration): boolean =>
- !!c.diagnosticsBlobSasUrl || (c.diagnosticsUploadDestination ?? "").toLowerCase() === "hosted";
-
-/** TenantConfiguration.GetLocalAdminAllowedAccounts: JSON string array, anything else → empty. */
-export const parseLocalAdminAllowedAccounts = (json: string | null | undefined): string[] => {
- if (!json) return [];
- try {
- const parsed: unknown = JSON.parse(json);
- return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === "string") : [];
- } catch {
- return [];
- }
-};
-
-/** AdminConfiguration.GetModernDeploymentHarmlessEventIds: JSON int array, blank/invalid → defaults. */
-export const parseModernDeploymentHarmlessEventIds = (json: string | null | undefined): number[] => {
- const defaults = [100, 1005, 1010];
- if (!json || !json.trim()) return defaults;
- try {
- const parsed: unknown = JSON.parse(json);
- return Array.isArray(parsed) && parsed.every((x) => typeof x === "number") ? parsed : defaults;
- } catch {
- return defaults;
- }
-};
-
-const admin = (pick: (a: AdminConfiguration) => T) =>
- (ctx: RuntimeContext): T | typeof UNRESOLVED => (ctx.adminConfig ? pick(ctx.adminConfig) : UNRESOLVED);
-
-const NOT_CONFIG = { excluded: "per-request payload, not a configuration value" } as const;
+const PER_DEVICE = { excluded: "per-device kill verdict, only on the agent channel" } as const;
const SUB_OBJECT = { excluded: "sub-object, catalogued separately" } as const;
-const CLASS_DEFAULT = { excluded: "agent class default, neither tenant- nor operator-tunable" } as const;
+
+/** Agent class default, neither tenant- nor operator-tunable — shown once, collapsed. */
+const internal = (label: string): RuntimeRow => ({ section: "Collector Internals", label, source: "fixed" });
export const RUNTIME_FIELDS: Record = {
- configVersion: { excluded: "compiled into the backend" },
- uploadIntervalSeconds: { section: "Upload & Batching", label: "Upload Interval (sec)", source: "constant", value: () => DEFAULT_UPLOAD_INTERVAL_SECONDS, default: DEFAULT_UPLOAD_INTERVAL_SECONDS },
- maxBatchSize: { section: "Upload & Batching", label: "Max Batch Size", source: "tenant", value: ({ config }) => config.maxBatchSize ?? 100, default: 100 },
+ configVersion: { section: "Catalogs & Integrity", label: "Config Version", source: "fixed", informational: true },
+ uploadIntervalSeconds: { section: "Upload & Batching", label: "Upload Interval (sec)", source: "fixed" },
+ maxBatchSize: { section: "Upload & Batching", label: "Max Batch Size", source: "tenant" },
- selfDestructOnComplete: { section: "Agent Behavior", label: "Self-Destruct", source: "tenant", value: ({ config }) => config.selfDestructOnComplete ?? true, default: true },
- keepLogFile: { section: "Agent Behavior", label: "Keep Log File", source: "tenant", value: ({ config }) => config.keepLogFile ?? false, default: false },
- rebootOnComplete: { section: "Agent Behavior", label: "Reboot On Complete", source: "tenant", value: ({ config }) => config.rebootOnComplete ?? false, default: false },
- rebootDelaySeconds: { section: "Agent Behavior", label: "Reboot Delay (sec)", source: "tenant", value: ({ config }) => config.rebootDelaySeconds ?? 10, default: 10 },
- enableGeoLocation: { section: "Agent Behavior", label: "Geo-Location", source: "tenant", value: ({ config }) => config.enableGeoLocation ?? true, default: true },
- enableTimezoneAutoSet: { section: "Agent Behavior", label: "Timezone Auto-Set", source: "tenant", value: ({ config }) => config.enableTimezoneAutoSet ?? false, default: false },
- enableDoGroupIdAutoSet: { section: "Agent Behavior", label: "DO GroupId Auto-Set", source: "tenant", value: ({ config }) => config.enableDoGroupIdAutoSet ?? false, default: false },
- ntpServer: { section: "Agent Behavior", label: "NTP Server", source: "tenant", value: ({ config }) => config.ntpServer || NTP_DEFAULT, default: NTP_DEFAULT },
- enableImeMatchLog: { section: "Agent Behavior", label: "IME Match Log", source: "tenant", value: ({ config }) => config.enableImeMatchLog ?? false, default: false },
- enableGatherRuleDebugLog: { section: "Agent Behavior", label: "Gather Rule Debug Log", source: "tenant", value: ({ config }) => config.enableGatherRuleDebugLog ?? false, default: false },
- enableEspContinueAnywayObservation: { section: "Agent Behavior", label: "Continue-Anyway Observation", source: "tenant", value: ({ config }) => config.enableEspContinueAnywayObservation ?? false, default: false },
- logLevel: { section: "Agent Behavior", label: "Log Level", source: "tenant", value: ({ config }) => config.logLevel ?? "Info", default: "Info" },
- sendTraceEvents: { section: "Agent Behavior", label: "Send Trace Events", source: "tenant", value: ({ config }) => config.sendTraceEvents, default: true },
- // TenantEntitlementService.IsUnrestrictedModeActive = edition entitlement && GA gate && tenant toggle;
- // feature-flags carries the backend-resolved value, so the entitlement logic is not rebuilt here.
- unrestrictedMode: { section: "Agent Behavior", label: "Unrestricted Mode (effective)", source: "flags", value: ({ flags }) => (flags ? flags.unrestrictedMode : UNRESOLVED), default: false },
- allowAgentDowngrade: { section: "Agent Behavior", label: "Allow Agent Downgrade", source: "admin", value: admin((a) => a.allowAgentDowngrade), default: false },
+ selfDestructOnComplete: { section: "Agent Behavior", label: "Self-Destruct", source: "tenant" },
+ keepLogFile: { section: "Agent Behavior", label: "Keep Log File", source: "tenant" },
+ rebootOnComplete: { section: "Agent Behavior", label: "Reboot On Complete", source: "tenant" },
+ rebootDelaySeconds: { section: "Agent Behavior", label: "Reboot Delay (sec)", source: "tenant" },
+ enableGeoLocation: { section: "Agent Behavior", label: "Geo-Location", source: "tenant" },
+ enableTimezoneAutoSet: { section: "Agent Behavior", label: "Timezone Auto-Set", source: "tenant" },
+ enableDoGroupIdAutoSet: { section: "Agent Behavior", label: "DO GroupId Auto-Set", source: "tenant" },
+ ntpServer: { section: "Agent Behavior", label: "NTP Server", source: "tenant" },
+ enableImeMatchLog: { section: "Agent Behavior", label: "IME Match Log", source: "tenant" },
+ enableGatherRuleDebugLog: { section: "Agent Behavior", label: "Gather Rule Debug Log", source: "tenant" },
+ enableEspContinueAnywayObservation: { section: "Agent Behavior", label: "Continue-Anyway Observation", source: "tenant" },
+ logLevel: { section: "Agent Behavior", label: "Log Level", source: "tenant" },
+ sendTraceEvents: { section: "Agent Behavior", label: "Send Trace Events", source: "tenant" },
+ // TenantEntitlementService.IsUnrestrictedModeActive = edition entitlement && GA gate && tenant toggle.
+ unrestrictedMode: { section: "Agent Behavior", label: "Unrestricted Mode (effective)", source: "entitlement" },
+ allowAgentDowngrade: { section: "Agent Behavior", label: "Allow Agent Downgrade", source: "global" },
- maxAuthFailures: { section: "Auth Circuit Breaker", label: "Max Auth Failures", source: "tenant", value: ({ config }) => config.maxAuthFailures ?? 5, default: 5 },
- authFailureTimeoutMinutes: { section: "Auth Circuit Breaker", label: "Auth Failure Timeout (min)", source: "tenant", value: ({ config }) => config.authFailureTimeoutMinutes ?? 0, default: 0 },
+ maxAuthFailures: { section: "Auth Circuit Breaker", label: "Max Auth Failures", source: "tenant" },
+ authFailureTimeoutMinutes: { section: "Auth Circuit Breaker", label: "Auth Failure Timeout (min)", source: "tenant" },
- showEnrollmentSummary: { section: "Enrollment Summary", label: "Show Summary", source: "tenant", value: ({ config }) => config.showEnrollmentSummary ?? false, default: false },
- enrollmentSummaryTimeoutSeconds: { section: "Enrollment Summary", label: "Timeout (sec)", source: "tenant", value: ({ config }) => config.enrollmentSummaryTimeoutSeconds ?? 60, default: 60 },
- enrollmentSummaryBrandingImageUrl: { section: "Enrollment Summary", label: "Branding Image URL", source: "tenant", value: ({ config }) => config.enrollmentSummaryBrandingImageUrl ?? null },
- enrollmentSummaryLaunchRetrySeconds: { section: "Enrollment Summary", label: "Launch Retry (sec)", source: "tenant", value: ({ config }) => config.enrollmentSummaryLaunchRetrySeconds ?? 120, default: 120 },
+ showEnrollmentSummary: { section: "Enrollment Summary", label: "Show Summary", source: "tenant" },
+ enrollmentSummaryTimeoutSeconds: { section: "Enrollment Summary", label: "Timeout (sec)", source: "tenant" },
+ enrollmentSummaryBrandingImageUrl: { section: "Enrollment Summary", label: "Branding Image URL", source: "tenant" },
+ enrollmentSummaryLaunchRetrySeconds: { section: "Enrollment Summary", label: "Launch Retry (sec)", source: "tenant" },
- diagnosticsUploadEnabled: { section: "Diagnostics", label: "Upload Enabled", source: "tenant", value: ({ config }) => resolveDiagnosticsUploadEnabled(config), default: false },
- diagnosticsUploadMode: { section: "Diagnostics", label: "Upload Mode", source: "tenant", value: ({ config }) => config.diagnosticsUploadMode ?? "Off", default: "Off" },
- diagnosticsLogPaths: { excluded: "merged global + tenant path list (see Custom Log Paths and the global diagnostics settings)" },
+ diagnosticsUploadEnabled: { section: "Diagnostics", label: "Upload Enabled", source: "tenant" },
+ diagnosticsUploadMode: { section: "Diagnostics", label: "Upload Mode", source: "tenant" },
+ diagnosticsLogPaths: { section: "Diagnostics", label: "Log Paths (global + tenant)", source: "global", kind: "count" },
collectors: SUB_OBJECT,
analyzers: SUB_OBJECT,
- gatherRules: { excluded: "active gather-rule catalog for the tenant" },
- imeLogPatterns: { excluded: "active IME log-pattern catalog for the tenant" },
- whiteGloveSealingPatternIds: { excluded: "global pattern-id list (AdminConfiguration)" },
- latestAgentSha256: { excluded: "per-major agent hash oracle selected from the caller's X-Agent-Version (AdminConfiguration)" },
- latestAgentExeSha256: { excluded: "per-major agent hash oracle selected from the caller's X-Agent-Version (AdminConfiguration)" },
- deviceBlocked: NOT_CONFIG,
- deviceKillSignal: NOT_CONFIG,
- unblockAt: NOT_CONFIG,
- migrateToApiBaseUrl: { excluded: "endpoint-migration target, global or per-tenant override (AdminConfiguration)" },
+
+ gatherRules: { section: "Catalogs & Integrity", label: "Active Gather Rules", source: "tenant", kind: "count", informational: true },
+ imeLogPatterns: { section: "Catalogs & Integrity", label: "Active IME Log Patterns", source: "tenant", kind: "count", informational: true },
+ whiteGloveSealingPatternIds: { section: "Catalogs & Integrity", label: "White Glove Sealing Pattern IDs", source: "global", informational: true },
+ latestAgentSha256: { section: "Catalogs & Integrity", label: "Latest Agent ZIP SHA-256", source: "global", informational: true },
+ latestAgentExeSha256: { section: "Catalogs & Integrity", label: "Latest Agent EXE SHA-256", source: "global", informational: true },
+ migrateToApiBaseUrl: { section: "Catalogs & Integrity", label: "Migrate To API Base URL", source: "global" },
+
+ deviceBlocked: PER_DEVICE,
+ deviceKillSignal: PER_DEVICE,
+ unblockAt: PER_DEVICE,
};
export const COLLECTOR_FIELDS: Record = {
- enablePerformanceCollector: { section: "Collectors", label: "Performance Collector", source: "tenant", value: ({ config }) => config.enablePerformanceCollector, default: true },
- performanceIntervalSeconds: { section: "Collectors", label: "Perf. Interval (sec)", source: "tenant", value: ({ config }) => config.performanceCollectorIntervalSeconds, default: 30 },
- collectorIdleTimeoutMinutes: { section: "Collectors", label: "Idle Timeout (min)", source: "admin", value: admin((a) => a.collectorIdleTimeoutMinutes), default: 15 },
- desktopDetectorNoCandidateTimeoutMinutes: { section: "Collectors", label: "Desktop Detector No-Candidate Timeout (min)", source: "admin", value: admin((a) => a.desktopDetectorNoCandidateTimeoutMinutes), default: 10 },
- enableAgentSelfMetrics: { section: "Collectors", label: "Agent Self-Metrics", source: "constant", value: () => true, default: true },
- agentSelfMetricsIntervalSeconds: { section: "Collectors", label: "Self-Metrics Interval (sec)", source: "constant", value: () => 60, default: 60 },
- helloWaitTimeoutSeconds: { section: "Collectors", label: "Hello Wait Timeout (sec)", source: "tenant", value: ({ config }) => config.helloWaitTimeoutSeconds, default: 30 },
- agentMaxLifetimeMinutes: { section: "Collectors", label: "Agent Max Lifetime (min)", source: "tenant", value: ({ config }) => config.agentMaxLifetimeMinutes ?? 360, default: 360 },
- modernDeploymentHarmlessEventIds: { section: "Collectors", label: "Modern Deployment Harmless Event IDs", source: "admin", value: admin((a) => parseModernDeploymentHarmlessEventIds(a.modernDeploymentHarmlessEventIdsJson)), default: [100, 1005, 1010] },
- enableDeliveryOptimizationCollector: CLASS_DEFAULT,
- deliveryOptimizationIntervalSeconds: CLASS_DEFAULT,
- enableOfficeInstallDetector: CLASS_DEFAULT,
- officeInstallSettleSeconds: CLASS_DEFAULT,
- enablePowerStateWatcher: CLASS_DEFAULT,
- stallProbeEnabled: CLASS_DEFAULT,
- stallProbeThresholdsMinutes: CLASS_DEFAULT,
- stallProbeTraceIndices: CLASS_DEFAULT,
- stallProbeSources: CLASS_DEFAULT,
- sessionStalledAfterProbeIndex: CLASS_DEFAULT,
- modernDeploymentWatcherEnabled: CLASS_DEFAULT,
- modernDeploymentLogLevelMax: CLASS_DEFAULT,
- modernDeploymentBackfillEnabled: CLASS_DEFAULT,
- modernDeploymentBackfillLookbackMinutes: CLASS_DEFAULT,
- windowsUpdateWatcherEnabled: CLASS_DEFAULT,
- windowsUpdateTargetedEventIds: CLASS_DEFAULT,
- windowsUpdateBackfillLookbackMinutes: CLASS_DEFAULT,
- windowsUpdateChannelCensusEnabled: CLASS_DEFAULT,
- mdmRebootPolicyWatcherEnabled: CLASS_DEFAULT,
- mdmRebootPolicyBackfillLookbackMinutes: CLASS_DEFAULT,
- enableSystemTimelineWatcher: CLASS_DEFAULT,
- systemEventBackfillLookbackMinutes: CLASS_DEFAULT,
+ enablePerformanceCollector: { section: "Collectors", label: "Performance Collector", source: "tenant" },
+ performanceIntervalSeconds: { section: "Collectors", label: "Perf. Interval (sec)", source: "tenant" },
+ collectorIdleTimeoutMinutes: { section: "Collectors", label: "Idle Timeout (min)", source: "global" },
+ desktopDetectorNoCandidateTimeoutMinutes: { section: "Collectors", label: "Desktop Detector No-Candidate Timeout (min)", source: "global" },
+ enableAgentSelfMetrics: { section: "Collectors", label: "Agent Self-Metrics", source: "fixed" },
+ agentSelfMetricsIntervalSeconds: { section: "Collectors", label: "Self-Metrics Interval (sec)", source: "fixed" },
+ helloWaitTimeoutSeconds: { section: "Collectors", label: "Hello Wait Timeout (sec)", source: "tenant" },
+ agentMaxLifetimeMinutes: { section: "Collectors", label: "Agent Max Lifetime (min)", source: "tenant" },
+ modernDeploymentHarmlessEventIds: { section: "Collectors", label: "Modern Deployment Harmless Event IDs", source: "global" },
+ enableDeliveryOptimizationCollector: internal("Delivery Optimization Collector"),
+ deliveryOptimizationIntervalSeconds: internal("DO Interval (sec)"),
+ enableOfficeInstallDetector: internal("Office Install Detector"),
+ officeInstallSettleSeconds: internal("Office Install Settle (sec)"),
+ enablePowerStateWatcher: internal("Power State Watcher"),
+ stallProbeEnabled: internal("Stall Probe"),
+ stallProbeThresholdsMinutes: internal("Stall Probe Thresholds (min)"),
+ stallProbeTraceIndices: internal("Stall Probe Trace Indices"),
+ stallProbeSources: internal("Stall Probe Sources"),
+ sessionStalledAfterProbeIndex: internal("Session Stalled After Probe Index"),
+ modernDeploymentWatcherEnabled: internal("Modern Deployment Watcher"),
+ modernDeploymentLogLevelMax: internal("Modern Deployment Log Level Max"),
+ modernDeploymentBackfillEnabled: internal("Modern Deployment Backfill"),
+ modernDeploymentBackfillLookbackMinutes: internal("Modern Deployment Backfill Lookback (min)"),
+ windowsUpdateWatcherEnabled: internal("Windows Update Watcher"),
+ windowsUpdateTargetedEventIds: internal("Windows Update Targeted Event IDs"),
+ windowsUpdateBackfillLookbackMinutes: internal("Windows Update Backfill Lookback (min)"),
+ windowsUpdateChannelCensusEnabled: internal("Windows Update Channel Census"),
+ mdmRebootPolicyWatcherEnabled: internal("MDM Reboot Policy Watcher"),
+ mdmRebootPolicyBackfillLookbackMinutes: internal("MDM Reboot Policy Backfill Lookback (min)"),
+ enableSystemTimelineWatcher: internal("System Timeline Watcher"),
+ systemEventBackfillLookbackMinutes: internal("System Event Backfill Lookback (min)"),
};
export const ANALYZER_FIELDS: Record = {
- enableLocalAdminAnalyzer: { section: "Analyzers", label: "Local Admin Analyzer", source: "tenant", value: ({ config }) => config.enableLocalAdminAnalyzer ?? true, default: true },
- localAdminAllowedAccounts: { section: "Analyzers", label: "Allowed Local Admin Accounts", source: "tenant", value: ({ config }) => parseLocalAdminAllowedAccounts(config.localAdminAllowedAccountsJson), default: [] },
- enableSoftwareInventoryAnalyzer: { section: "Analyzers", label: "Software Inventory Analyzer", source: "tenant", value: ({ config }) => config.enableSoftwareInventoryAnalyzer ?? false, default: false },
- enableIntegrityBypassAnalyzer: { section: "Analyzers", label: "Integrity Bypass Analyzer", source: "tenant", value: ({ config }) => config.enableIntegrityBypassAnalyzer ?? true, default: true },
- enableRealmJoinWatcher: { section: "Analyzers", label: "Realm Join Watcher", source: "tenant", value: ({ config }) => config.enableRealmJoinWatcher ?? false, default: false },
- keepAwakeDuringUserEsp: { section: "Analyzers", label: "Keep Awake During User ESP", source: "tenant", value: ({ config }) => config.keepAwakeDuringUserEsp ?? false, default: false },
- enableConsoleBypassDetection: { section: "Analyzers", label: "Console Bypass Detection", source: "tenant", value: ({ config }) => config.enableConsoleBypassDetection ?? true, default: true },
+ enableLocalAdminAnalyzer: { section: "Analyzers", label: "Local Admin Analyzer", source: "tenant" },
+ localAdminAllowedAccounts: { section: "Analyzers", label: "Allowed Local Admin Accounts", source: "tenant" },
+ enableSoftwareInventoryAnalyzer: { section: "Analyzers", label: "Software Inventory Analyzer", source: "tenant" },
+ enableIntegrityBypassAnalyzer: { section: "Analyzers", label: "Integrity Bypass Analyzer", source: "tenant" },
+ enableRealmJoinWatcher: { section: "Analyzers", label: "Realm Join Watcher", source: "tenant" },
+ keepAwakeDuringUserEsp: { section: "Analyzers", label: "Keep Awake During User ESP", source: "tenant" },
+ enableConsoleBypassDetection: { section: "Analyzers", label: "Console Bypass Detection", source: "tenant" },
};
// ── Ordered views for rendering ──────────────────────────────────────────────
-export interface CataloguedRow {
+/** One rendered row: where its value and default come from, resolved against a response. */
+export interface CataloguedRuntimeRow {
key: string;
- row: TRow;
+ row: RuntimeRow;
+ value: (r: AgentConfigResponse) => unknown;
+ default: unknown;
}
-function groupBySection(
- sections: readonly TSection[],
- records: Array>,
-): Array<{ section: TSection; rows: CataloguedRow[] }> {
- const bySection = new Map[]>(sections.map((s) => [s, []]));
- for (const record of records) {
- for (const [key, spec] of Object.entries(record)) {
- if (isExcluded(spec)) continue;
- bySection.get(spec.section)!.push({ key, row: spec });
- }
+export interface CataloguedTenantRow {
+ key: keyof TenantConfiguration;
+ row: TenantRow;
+ default: unknown;
+}
+
+function tenantRows(): Array<{ section: TenantSection; rows: CataloguedTenantRow[] }> {
+ const bySection = new Map(TENANT_SECTIONS.map((s) => [s, []]));
+ for (const [key, spec] of Object.entries(TENANT_FIELDS) as Array<[keyof TenantConfiguration, TenantRow | Excluded]>) {
+ if (isExcluded(spec)) continue;
+ bySection.get(spec.section)!.push({ key, row: spec, default: TENANT_DEFAULTS[key] });
}
- return sections.map((section) => ({ section, rows: bySection.get(section)! }));
+ return TENANT_SECTIONS.map((section) => ({ section, rows: bySection.get(section)! }));
}
-export const TENANT_REPORT_SECTIONS = groupBySection(TENANT_SECTIONS, [TENANT_FIELDS]);
+function runtimeRows(): Array<{ section: RuntimeSection; rows: CataloguedRuntimeRow[] }> {
+ const bySection = new Map(RUNTIME_SECTIONS.map((s) => [s, []]));
+ const add = (key: string, spec: RuntimeRow | Excluded, value: (r: AgentConfigResponse) => unknown, def: unknown) => {
+ if (isExcluded(spec)) return;
+ bySection.get(spec.section)!.push({ key, row: spec, value, default: def });
+ };
+ for (const [key, spec] of Object.entries(RUNTIME_FIELDS) as Array<[keyof AgentConfigResponse, RuntimeRow | Excluded]>) {
+ add(key, spec, (r) => r[key], RUNTIME_DEFAULTS[key]);
+ }
+ for (const [key, spec] of Object.entries(COLLECTOR_FIELDS) as Array<[keyof CollectorConfiguration, RuntimeRow | Excluded]>) {
+ add(`collectors.${key}`, spec, (r) => r.collectors?.[key], COLLECTOR_DEFAULTS[key]);
+ }
+ for (const [key, spec] of Object.entries(ANALYZER_FIELDS) as Array<[keyof AnalyzerConfiguration, RuntimeRow | Excluded]>) {
+ add(`analyzers.${key}`, spec, (r) => r.analyzers?.[key], ANALYZER_DEFAULTS[key]);
+ }
+ return RUNTIME_SECTIONS.map((section) => ({ section, rows: bySection.get(section)! }));
+}
-export const RUNTIME_REPORT_SECTIONS = groupBySection(RUNTIME_SECTIONS, [
- RUNTIME_FIELDS,
- COLLECTOR_FIELDS,
- ANALYZER_FIELDS,
-]);
+export const TENANT_REPORT_SECTIONS = tenantRows();
+export const RUNTIME_REPORT_SECTIONS = runtimeRows();
/**
* Value equality for the "custom" highlight: null, undefined and the empty string are one
diff --git a/src/Web/autopilot-monitor-web/lib/api.ts b/src/Web/autopilot-monitor-web/lib/api.ts
index 006bf59b..39e8c26f 100644
--- a/src/Web/autopilot-monitor-web/lib/api.ts
+++ b/src/Web/autopilot-monitor-web/lib/api.ts
@@ -135,6 +135,13 @@ export const api = {
*/
fields: (tenantId: string) => `${API_BASE_URL}/api/config/${encodeURIComponent(tenantId)}/fields`,
featureFlags: (tenantId: string) => `${API_BASE_URL}/api/config/${encodeURIComponent(tenantId)}/feature-flags`,
+ /**
+ * GET — GA-only: the AgentConfigResponse an agent of the tenant receives right now (same
+ * derivation as agent/config, minus the per-device kill verdict). Optional agentVersion
+ * selects the hash-oracle line like X-Agent-Version would; absent = the current line.
+ */
+ effectiveAgentConfig: (tenantId: string, agentVersion?: string) =>
+ `${API_BASE_URL}/api/config/${encodeURIComponent(tenantId)}/effective-agent-config${agentVersion ? `?agentVersion=${encodeURIComponent(agentVersion)}` : ''}`,
/** PATCH — GA-only plan/trial mutation: { planTier?, trialExpiresUtc?: ISO | null }. */
plan: (tenantId: string) => `${API_BASE_URL}/api/config/${encodeURIComponent(tenantId)}/plan`,
/** POST — tenant-admin self-service 30-day Pro trial (once per tenant, 409 after). */
diff --git a/src/Web/autopilot-monitor-web/utils/shared-manifests.generated.ts b/src/Web/autopilot-monitor-web/utils/shared-manifests.generated.ts
index 5e103834..f1f533a0 100644
--- a/src/Web/autopilot-monitor-web/utils/shared-manifests.generated.ts
+++ b/src/Web/autopilot-monitor-web/utils/shared-manifests.generated.ts
@@ -60,7 +60,62 @@ export const SHARED_MANIFEST = {
"msrcLastSyncUtc",
"nvdCacheLastRefreshUtc",
"epssLastSyncUtc"
- ]
+ ],
+ "defaults": {
+ "partitionKey": "GlobalConfig",
+ "rowKey": "config",
+ "lastUpdated": "0001-01-01T00:00:00.0000000",
+ "updatedBy": null,
+ "globalRateLimitRequestsPerMinute": 100,
+ "userRateLimitRequestsPerMinute": 120,
+ "portalUserRateLimitRequestsPerMinute": 600,
+ "globalAdminRateLimitRequestsPerMinute": 600,
+ "planTierDefinitionsJson": null,
+ "platformStatsBlobSasUrl": "",
+ "collectorIdleTimeoutMinutes": 15,
+ "desktopDetectorNoCandidateTimeoutMinutes": 10,
+ "excessiveEventCountThreshold": 2000,
+ "excessiveEventAutoActionMode": "Off",
+ "excessiveEventAutoActionThreshold": 2500,
+ "excessiveEventAutoActionDurationHours": 24,
+ "opsEventRetentionDays": 90,
+ "slaNotificationCooldownHours": 24,
+ "feedbackEnabled": true,
+ "feedbackMinTenantAgeDays": 14,
+ "feedbackCooldownDays": 60,
+ "diagnosticsGlobalLogPathsJson": null,
+ "maxDiagnosticsDownloadSizeMB": 500,
+ "diagnosticsDownloadTimeoutSeconds": 120,
+ "mcpAccessPolicy": "WhitelistOnly",
+ "nvdApiKey": null,
+ "opsAlertRulesJson": null,
+ "opsAlertTelegramEnabled": false,
+ "opsAlertTelegramChatId": null,
+ "opsAlertTeamsEnabled": false,
+ "opsAlertTeamsWebhookUrl": null,
+ "opsAlertSlackEnabled": false,
+ "opsAlertSlackWebhookUrl": null,
+ "opsNotificationChannelsJson": null,
+ "latestAgentV2Version": null,
+ "latestAgentV2Sha256": null,
+ "latestAgentV2ExeSha256": null,
+ "latestBootstrapV2ScriptVersion": null,
+ "allowAgentDowngrade": false,
+ "agentMigrateApiBaseUrl": "",
+ "agentMigrateTenantOverridesJson": "",
+ "modernDeploymentHarmlessEventIdsJson": null,
+ "whiteGloveSealingPatternIdsJson": null,
+ "vulnerabilityCorrelationEnabled": true,
+ "autoApproveNewTenants": false,
+ "imeMsiArchivingEnabled": true,
+ "maxImeMsiDownloadSizeMB": 250,
+ "selfServiceAppHomingEnabled": false,
+ "sessionDeletionKillSwitch": false,
+ "vulnerabilityDataLastSyncUtc": null,
+ "msrcLastSyncUtc": null,
+ "nvdCacheLastRefreshUtc": null,
+ "epssLastSyncUtc": null
+ }
},
"tenantConfiguration": {
"fields": [
@@ -166,7 +221,217 @@ export const SHARED_MANIFEST = {
"slaNotifyOnAppInstallBreach",
"slaNotifyOnConsecutiveFailures",
"slaConsecutiveFailureThreshold"
- ]
+ ],
+ "defaults": {
+ "tenantId": null,
+ "domainName": null,
+ "lastUpdated": "0001-01-01T00:00:00.0000000",
+ "updatedBy": null,
+ "onboardedBy": null,
+ "contactEmail": null,
+ "companyName": null,
+ "onboardedAt": null,
+ "homedAppClientId": null,
+ "lastAuthClientId": null,
+ "lastAuthClientIdSince": null,
+ "disabled": false,
+ "disabledReason": null,
+ "disabledUntil": null,
+ "mcpDisabled": false,
+ "mcpDisabledReason": null,
+ "customRateLimitRequestsPerMinute": null,
+ "customUserRateLimitRequestsPerMinute": null,
+ "planTier": "free",
+ "trialExpiresUtc": null,
+ "trialStartedUtc": null,
+ "trialConsumed": false,
+ "trialGrantedBy": null,
+ "proDowngradedUtc": null,
+ "maxDelegatedTenantsOverride": null,
+ "mcpUsagePlanOverride": null,
+ "payingCustomer": false,
+ "managedByProTenantId": null,
+ "manufacturerWhitelist": "Dell*,HP*,Lenovo*,Microsoft Corporation",
+ "modelWhitelist": "*",
+ "validateAutopilotDevice": false,
+ "validateCorporateIdentifier": false,
+ "validateDeviceAssociation": false,
+ "validateCloudPcDevice": false,
+ "validateIntuneDeviceBinding": false,
+ "allowInsecureAgentRequests": false,
+ "dataRetentionDays": 90,
+ "sessionTimeoutHours": 5,
+ "sessionGraceHours": 0,
+ "maxNdjsonPayloadSizeMB": 5,
+ "enablePerformanceCollector": true,
+ "performanceCollectorIntervalSeconds": 30,
+ "helloWaitTimeoutSeconds": 30,
+ "maxAuthFailures": null,
+ "authFailureTimeoutMinutes": null,
+ "agentMaxLifetimeMinutes": null,
+ "absoluteMaxSessionHours": null,
+ "selfDestructOnComplete": true,
+ "keepLogFile": false,
+ "rebootOnComplete": null,
+ "rebootDelaySeconds": null,
+ "enableGeoLocation": null,
+ "ntpServer": "time.windows.com",
+ "enableTimezoneAutoSet": null,
+ "enableDoGroupIdAutoSet": null,
+ "enableImeMatchLog": null,
+ "enableGatherRuleDebugLog": null,
+ "enableEspContinueAnywayObservation": null,
+ "logLevel": null,
+ "maxBatchSize": null,
+ "showEnrollmentSummary": null,
+ "enrollmentSummaryTimeoutSeconds": null,
+ "enrollmentSummaryBrandingImageUrl": null,
+ "enrollmentSummaryLaunchRetrySeconds": null,
+ "showScriptOutput": true,
+ "enableLocalAdminAnalyzer": null,
+ "enableSoftwareInventoryAnalyzer": null,
+ "enableIntegrityBypassAnalyzer": null,
+ "enableRealmJoinWatcher": null,
+ "keepAwakeDuringUserEsp": null,
+ "enableConsoleBypassDetection": null,
+ "localAdminAllowedAccountsJson": null,
+ "bootstrapTokenEnabled": false,
+ "unrestrictedModeEnabled": false,
+ "unrestrictedMode": false,
+ "entraAppRolesEnabled": false,
+ "diagnosticsLogPathsJson": null,
+ "diagnosticsBlobSasUrl": null,
+ "diagnosticsUploadMode": "Off",
+ "diagnosticsUploadDestination": "CustomerSas",
+ "sendTraceEvents": true,
+ "teamsWebhookUrl": null,
+ "teamsNotifyOnSuccess": true,
+ "teamsNotifyOnFailure": true,
+ "teamsNotifyOnStart": false,
+ "webhookProviderType": 0,
+ "webhookUrl": null,
+ "webhookNotifyOnSuccess": true,
+ "webhookNotifyOnFailure": true,
+ "webhookNotifyOnHardwareRejection": false,
+ "webhookNotifyOnStart": false,
+ "webhookCustomHeadersJson": null,
+ "notificationChannelsJson": null,
+ "slaTargetSuccessRate": null,
+ "slaTargetMaxDurationMinutes": null,
+ "slaTargetAppInstallSuccessRate": null,
+ "slaNotifyOnSuccessRateBreach": false,
+ "slaSuccessRateNotifyThreshold": null,
+ "slaNotifyOnDurationBreach": false,
+ "slaNotifyOnAppInstallBreach": false,
+ "slaNotifyOnConsecutiveFailures": false,
+ "slaConsecutiveFailureThreshold": 5
+ }
+ },
+ "agentConfig": {
+ "responseDefaults": {
+ "configVersion": 0,
+ "uploadIntervalSeconds": 10,
+ "selfDestructOnComplete": true,
+ "keepLogFile": false,
+ "enableGeoLocation": true,
+ "enableImeMatchLog": false,
+ "enableGatherRuleDebugLog": false,
+ "enableEspContinueAnywayObservation": false,
+ "collectors": null,
+ "gatherRules": [],
+ "imeLogPatterns": [],
+ "whiteGloveSealingPatternIds": [],
+ "maxAuthFailures": 5,
+ "authFailureTimeoutMinutes": 0,
+ "logLevel": "Info",
+ "rebootOnComplete": false,
+ "rebootDelaySeconds": 10,
+ "showEnrollmentSummary": false,
+ "enrollmentSummaryTimeoutSeconds": 60,
+ "enrollmentSummaryBrandingImageUrl": null,
+ "enrollmentSummaryLaunchRetrySeconds": 120,
+ "maxBatchSize": 100,
+ "diagnosticsUploadEnabled": false,
+ "diagnosticsUploadMode": "Off",
+ "diagnosticsLogPaths": [],
+ "analyzers": null,
+ "sendTraceEvents": true,
+ "unrestrictedMode": false,
+ "latestAgentSha256": null,
+ "latestAgentExeSha256": null,
+ "allowAgentDowngrade": false,
+ "ntpServer": "time.windows.com",
+ "enableTimezoneAutoSet": false,
+ "enableDoGroupIdAutoSet": false,
+ "deviceBlocked": false,
+ "deviceKillSignal": false,
+ "unblockAt": null,
+ "migrateToApiBaseUrl": null
+ },
+ "collectorDefaults": {
+ "enablePerformanceCollector": true,
+ "performanceIntervalSeconds": 30,
+ "collectorIdleTimeoutMinutes": 15,
+ "desktopDetectorNoCandidateTimeoutMinutes": 10,
+ "enableAgentSelfMetrics": true,
+ "agentSelfMetricsIntervalSeconds": 60,
+ "helloWaitTimeoutSeconds": 30,
+ "agentMaxLifetimeMinutes": 360,
+ "enableDeliveryOptimizationCollector": true,
+ "deliveryOptimizationIntervalSeconds": 3,
+ "enableOfficeInstallDetector": true,
+ "officeInstallSettleSeconds": 10,
+ "enablePowerStateWatcher": true,
+ "stallProbeEnabled": true,
+ "stallProbeThresholdsMinutes": [
+ 2,
+ 15,
+ 30,
+ 60,
+ 180
+ ],
+ "stallProbeTraceIndices": [
+ 2
+ ],
+ "stallProbeSources": [
+ "provisioning_registry",
+ "diagnostics_registry",
+ "eventlog",
+ "appworkload_log"
+ ],
+ "sessionStalledAfterProbeIndex": 4,
+ "modernDeploymentWatcherEnabled": true,
+ "modernDeploymentLogLevelMax": 3,
+ "modernDeploymentBackfillEnabled": true,
+ "modernDeploymentHarmlessEventIds": [
+ 100,
+ 1005,
+ 1010
+ ],
+ "modernDeploymentBackfillLookbackMinutes": 30,
+ "windowsUpdateWatcherEnabled": true,
+ "windowsUpdateTargetedEventIds": [
+ 19,
+ 20,
+ 43,
+ 44
+ ],
+ "windowsUpdateBackfillLookbackMinutes": 60,
+ "windowsUpdateChannelCensusEnabled": true,
+ "mdmRebootPolicyWatcherEnabled": true,
+ "mdmRebootPolicyBackfillLookbackMinutes": 60,
+ "enableSystemTimelineWatcher": true,
+ "systemEventBackfillLookbackMinutes": 1440
+ },
+ "analyzerDefaults": {
+ "enableLocalAdminAnalyzer": true,
+ "localAdminAllowedAccounts": [],
+ "enableSoftwareInventoryAnalyzer": false,
+ "enableIntegrityBypassAnalyzer": true,
+ "enableRealmJoinWatcher": false,
+ "keepAwakeDuringUserEsp": false,
+ "enableConsoleBypassDetection": true
+ }
},
"sessionStatuses": [
"InProgress",
diff --git a/src/Web/autopilot-monitor-web/utils/shared-manifests.json b/src/Web/autopilot-monitor-web/utils/shared-manifests.json
index 8bc46f32..9031ab56 100644
--- a/src/Web/autopilot-monitor-web/utils/shared-manifests.json
+++ b/src/Web/autopilot-monitor-web/utils/shared-manifests.json
@@ -56,7 +56,62 @@
"msrcLastSyncUtc",
"nvdCacheLastRefreshUtc",
"epssLastSyncUtc"
- ]
+ ],
+ "defaults": {
+ "partitionKey": "GlobalConfig",
+ "rowKey": "config",
+ "lastUpdated": "0001-01-01T00:00:00.0000000",
+ "updatedBy": null,
+ "globalRateLimitRequestsPerMinute": 100,
+ "userRateLimitRequestsPerMinute": 120,
+ "portalUserRateLimitRequestsPerMinute": 600,
+ "globalAdminRateLimitRequestsPerMinute": 600,
+ "planTierDefinitionsJson": null,
+ "platformStatsBlobSasUrl": "",
+ "collectorIdleTimeoutMinutes": 15,
+ "desktopDetectorNoCandidateTimeoutMinutes": 10,
+ "excessiveEventCountThreshold": 2000,
+ "excessiveEventAutoActionMode": "Off",
+ "excessiveEventAutoActionThreshold": 2500,
+ "excessiveEventAutoActionDurationHours": 24,
+ "opsEventRetentionDays": 90,
+ "slaNotificationCooldownHours": 24,
+ "feedbackEnabled": true,
+ "feedbackMinTenantAgeDays": 14,
+ "feedbackCooldownDays": 60,
+ "diagnosticsGlobalLogPathsJson": null,
+ "maxDiagnosticsDownloadSizeMB": 500,
+ "diagnosticsDownloadTimeoutSeconds": 120,
+ "mcpAccessPolicy": "WhitelistOnly",
+ "nvdApiKey": null,
+ "opsAlertRulesJson": null,
+ "opsAlertTelegramEnabled": false,
+ "opsAlertTelegramChatId": null,
+ "opsAlertTeamsEnabled": false,
+ "opsAlertTeamsWebhookUrl": null,
+ "opsAlertSlackEnabled": false,
+ "opsAlertSlackWebhookUrl": null,
+ "opsNotificationChannelsJson": null,
+ "latestAgentV2Version": null,
+ "latestAgentV2Sha256": null,
+ "latestAgentV2ExeSha256": null,
+ "latestBootstrapV2ScriptVersion": null,
+ "allowAgentDowngrade": false,
+ "agentMigrateApiBaseUrl": "",
+ "agentMigrateTenantOverridesJson": "",
+ "modernDeploymentHarmlessEventIdsJson": null,
+ "whiteGloveSealingPatternIdsJson": null,
+ "vulnerabilityCorrelationEnabled": true,
+ "autoApproveNewTenants": false,
+ "imeMsiArchivingEnabled": true,
+ "maxImeMsiDownloadSizeMB": 250,
+ "selfServiceAppHomingEnabled": false,
+ "sessionDeletionKillSwitch": false,
+ "vulnerabilityDataLastSyncUtc": null,
+ "msrcLastSyncUtc": null,
+ "nvdCacheLastRefreshUtc": null,
+ "epssLastSyncUtc": null
+ }
},
"tenantConfiguration": {
"fields": [
@@ -162,7 +217,217 @@
"slaNotifyOnAppInstallBreach",
"slaNotifyOnConsecutiveFailures",
"slaConsecutiveFailureThreshold"
- ]
+ ],
+ "defaults": {
+ "tenantId": null,
+ "domainName": null,
+ "lastUpdated": "0001-01-01T00:00:00.0000000",
+ "updatedBy": null,
+ "onboardedBy": null,
+ "contactEmail": null,
+ "companyName": null,
+ "onboardedAt": null,
+ "homedAppClientId": null,
+ "lastAuthClientId": null,
+ "lastAuthClientIdSince": null,
+ "disabled": false,
+ "disabledReason": null,
+ "disabledUntil": null,
+ "mcpDisabled": false,
+ "mcpDisabledReason": null,
+ "customRateLimitRequestsPerMinute": null,
+ "customUserRateLimitRequestsPerMinute": null,
+ "planTier": "free",
+ "trialExpiresUtc": null,
+ "trialStartedUtc": null,
+ "trialConsumed": false,
+ "trialGrantedBy": null,
+ "proDowngradedUtc": null,
+ "maxDelegatedTenantsOverride": null,
+ "mcpUsagePlanOverride": null,
+ "payingCustomer": false,
+ "managedByProTenantId": null,
+ "manufacturerWhitelist": "Dell*,HP*,Lenovo*,Microsoft Corporation",
+ "modelWhitelist": "*",
+ "validateAutopilotDevice": false,
+ "validateCorporateIdentifier": false,
+ "validateDeviceAssociation": false,
+ "validateCloudPcDevice": false,
+ "validateIntuneDeviceBinding": false,
+ "allowInsecureAgentRequests": false,
+ "dataRetentionDays": 90,
+ "sessionTimeoutHours": 5,
+ "sessionGraceHours": 0,
+ "maxNdjsonPayloadSizeMB": 5,
+ "enablePerformanceCollector": true,
+ "performanceCollectorIntervalSeconds": 30,
+ "helloWaitTimeoutSeconds": 30,
+ "maxAuthFailures": null,
+ "authFailureTimeoutMinutes": null,
+ "agentMaxLifetimeMinutes": null,
+ "absoluteMaxSessionHours": null,
+ "selfDestructOnComplete": true,
+ "keepLogFile": false,
+ "rebootOnComplete": null,
+ "rebootDelaySeconds": null,
+ "enableGeoLocation": null,
+ "ntpServer": "time.windows.com",
+ "enableTimezoneAutoSet": null,
+ "enableDoGroupIdAutoSet": null,
+ "enableImeMatchLog": null,
+ "enableGatherRuleDebugLog": null,
+ "enableEspContinueAnywayObservation": null,
+ "logLevel": null,
+ "maxBatchSize": null,
+ "showEnrollmentSummary": null,
+ "enrollmentSummaryTimeoutSeconds": null,
+ "enrollmentSummaryBrandingImageUrl": null,
+ "enrollmentSummaryLaunchRetrySeconds": null,
+ "showScriptOutput": true,
+ "enableLocalAdminAnalyzer": null,
+ "enableSoftwareInventoryAnalyzer": null,
+ "enableIntegrityBypassAnalyzer": null,
+ "enableRealmJoinWatcher": null,
+ "keepAwakeDuringUserEsp": null,
+ "enableConsoleBypassDetection": null,
+ "localAdminAllowedAccountsJson": null,
+ "bootstrapTokenEnabled": false,
+ "unrestrictedModeEnabled": false,
+ "unrestrictedMode": false,
+ "entraAppRolesEnabled": false,
+ "diagnosticsLogPathsJson": null,
+ "diagnosticsBlobSasUrl": null,
+ "diagnosticsUploadMode": "Off",
+ "diagnosticsUploadDestination": "CustomerSas",
+ "sendTraceEvents": true,
+ "teamsWebhookUrl": null,
+ "teamsNotifyOnSuccess": true,
+ "teamsNotifyOnFailure": true,
+ "teamsNotifyOnStart": false,
+ "webhookProviderType": 0,
+ "webhookUrl": null,
+ "webhookNotifyOnSuccess": true,
+ "webhookNotifyOnFailure": true,
+ "webhookNotifyOnHardwareRejection": false,
+ "webhookNotifyOnStart": false,
+ "webhookCustomHeadersJson": null,
+ "notificationChannelsJson": null,
+ "slaTargetSuccessRate": null,
+ "slaTargetMaxDurationMinutes": null,
+ "slaTargetAppInstallSuccessRate": null,
+ "slaNotifyOnSuccessRateBreach": false,
+ "slaSuccessRateNotifyThreshold": null,
+ "slaNotifyOnDurationBreach": false,
+ "slaNotifyOnAppInstallBreach": false,
+ "slaNotifyOnConsecutiveFailures": false,
+ "slaConsecutiveFailureThreshold": 5
+ }
+ },
+ "agentConfig": {
+ "responseDefaults": {
+ "configVersion": 0,
+ "uploadIntervalSeconds": 10,
+ "selfDestructOnComplete": true,
+ "keepLogFile": false,
+ "enableGeoLocation": true,
+ "enableImeMatchLog": false,
+ "enableGatherRuleDebugLog": false,
+ "enableEspContinueAnywayObservation": false,
+ "collectors": null,
+ "gatherRules": [],
+ "imeLogPatterns": [],
+ "whiteGloveSealingPatternIds": [],
+ "maxAuthFailures": 5,
+ "authFailureTimeoutMinutes": 0,
+ "logLevel": "Info",
+ "rebootOnComplete": false,
+ "rebootDelaySeconds": 10,
+ "showEnrollmentSummary": false,
+ "enrollmentSummaryTimeoutSeconds": 60,
+ "enrollmentSummaryBrandingImageUrl": null,
+ "enrollmentSummaryLaunchRetrySeconds": 120,
+ "maxBatchSize": 100,
+ "diagnosticsUploadEnabled": false,
+ "diagnosticsUploadMode": "Off",
+ "diagnosticsLogPaths": [],
+ "analyzers": null,
+ "sendTraceEvents": true,
+ "unrestrictedMode": false,
+ "latestAgentSha256": null,
+ "latestAgentExeSha256": null,
+ "allowAgentDowngrade": false,
+ "ntpServer": "time.windows.com",
+ "enableTimezoneAutoSet": false,
+ "enableDoGroupIdAutoSet": false,
+ "deviceBlocked": false,
+ "deviceKillSignal": false,
+ "unblockAt": null,
+ "migrateToApiBaseUrl": null
+ },
+ "collectorDefaults": {
+ "enablePerformanceCollector": true,
+ "performanceIntervalSeconds": 30,
+ "collectorIdleTimeoutMinutes": 15,
+ "desktopDetectorNoCandidateTimeoutMinutes": 10,
+ "enableAgentSelfMetrics": true,
+ "agentSelfMetricsIntervalSeconds": 60,
+ "helloWaitTimeoutSeconds": 30,
+ "agentMaxLifetimeMinutes": 360,
+ "enableDeliveryOptimizationCollector": true,
+ "deliveryOptimizationIntervalSeconds": 3,
+ "enableOfficeInstallDetector": true,
+ "officeInstallSettleSeconds": 10,
+ "enablePowerStateWatcher": true,
+ "stallProbeEnabled": true,
+ "stallProbeThresholdsMinutes": [
+ 2,
+ 15,
+ 30,
+ 60,
+ 180
+ ],
+ "stallProbeTraceIndices": [
+ 2
+ ],
+ "stallProbeSources": [
+ "provisioning_registry",
+ "diagnostics_registry",
+ "eventlog",
+ "appworkload_log"
+ ],
+ "sessionStalledAfterProbeIndex": 4,
+ "modernDeploymentWatcherEnabled": true,
+ "modernDeploymentLogLevelMax": 3,
+ "modernDeploymentBackfillEnabled": true,
+ "modernDeploymentHarmlessEventIds": [
+ 100,
+ 1005,
+ 1010
+ ],
+ "modernDeploymentBackfillLookbackMinutes": 30,
+ "windowsUpdateWatcherEnabled": true,
+ "windowsUpdateTargetedEventIds": [
+ 19,
+ 20,
+ 43,
+ 44
+ ],
+ "windowsUpdateBackfillLookbackMinutes": 60,
+ "windowsUpdateChannelCensusEnabled": true,
+ "mdmRebootPolicyWatcherEnabled": true,
+ "mdmRebootPolicyBackfillLookbackMinutes": 60,
+ "enableSystemTimelineWatcher": true,
+ "systemEventBackfillLookbackMinutes": 1440
+ },
+ "analyzerDefaults": {
+ "enableLocalAdminAnalyzer": true,
+ "localAdminAllowedAccounts": [],
+ "enableSoftwareInventoryAnalyzer": false,
+ "enableIntegrityBypassAnalyzer": true,
+ "enableRealmJoinWatcher": false,
+ "keepAwakeDuringUserEsp": false,
+ "enableConsoleBypassDetection": true
+ }
},
"sessionStatuses": [
"InProgress",