This commit is contained in:
Oliver Kieselbach
2026-03-31 22:38:28 +02:00
parent 7c3d8f54bd
commit e8903ff413
4 changed files with 0 additions and 135 deletions
-29
View File
@@ -1,29 +0,0 @@
# Changelog
## 2026-03-29 — Agent Integrity Verification (SHA-256)
### Security Enhancement
The bootstrapper script and agent self-updater now verify the SHA-256 hash of downloaded
agent packages against `version.json`. Additionally, the backend serves the expected hash
via the agent config endpoint as a second trust channel.
**What changed:**
- `version.json` now includes a `sha256` field with the SHA-256 hash of the agent ZIP
- Bootstrapper (`Install-AutopilotMonitor.ps1`) verifies the hash before installation
- Self-Updater (`SelfUpdater.cs`) verifies the hash before applying updates
- Backend delivers `LatestAgentSha256` via the agent config response (defense in depth)
- CI/CD pipeline and local build scripts compute and publish the hash automatically
**Action required:** Update your Intune bootstrapper script to the latest version
to benefit from SHA-256 integrity verification. Existing deployments continue to work
without changes (fully backward compatible).
The updated bootstrap script is available at:
- Blob Storage: `https://autopilotmonitor.blob.core.windows.net/agent/Install-AutopilotMonitor.ps1`
- GitHub: `scripts/Bootstrap/Install-AutopilotMonitor.ps1`
**Backward compatibility:**
- Old bootstrapper scripts (without hash check) continue to work unchanged
- Old agents (without hash check) continue to self-update normally
- New agents with old `version.json` (no `sha256` field) skip the check gracefully
-30
View File
@@ -1,30 +0,0 @@
# ADR-001: On-Demand SAS URL Delivery for Diagnostics Upload
**Status:** Accepted
**Date:** 2026-02
**Supersedes:** Original design with SAS URL in agent config response stored on disk
## Context
The agent needs to upload diagnostics ZIP packages to Azure Blob Storage. The original design included the long-lived SAS URL directly in the `agent/config` response, which was then persisted in `remote-config.json` on the device.
**Problems with the original approach:**
- SAS URL persisted on disk in plaintext (`remote-config.json`) — accessible to any local admin
- URL visible in agent logs
- No per-device access control — every device with the cached URL could upload at any time
## Decision
Instead of delivering the SAS URL via the config response, the agent calls `POST /api/diagnostics/upload-url` immediately before each upload. The backend returns the long-lived SAS URL (configured in tenant settings) in the response body. The agent uses it in-memory for the upload and discards it — it is never written to disk or cached in config.
**Config response changes:**
- Removed: `DiagnosticsBlobSasUrl` from agent config delivery
- Added: `DiagnosticsUploadEnabled` (bool) — controls whether the agent attempts upload
- Added: `POST /api/diagnostics/upload-url` endpoint (`GetDiagnosticsUploadUrlFunction`)
## Consequences
- SAS URL never persisted on device — only held in-memory for the duration of the upload
- Backend can deny the URL per-device (blocked devices, rate limiting, disabled tenants)
- Old agents that still read from `remote-config.json` fall back gracefully — they won't have a SAS URL and simply skip upload
- Slightly higher latency (one extra HTTP call before upload) — acceptable since uploads are infrequent
@@ -1,33 +0,0 @@
# ADR-002: Activity-Aware Idle Timeout Replaces Static Max Duration
**Status:** Accepted
**Date:** 2026-02
**Supersedes:** Static `MaxCollectorDurationHours` (4h hard cutoff)
## Context
The original design stopped all collectors after a fixed 4-hour window (`MaxCollectorDurationHours`). This caused problems:
- Long enrollments with many apps (>50) were cut off mid-collection
- Sessions with slow network or large downloads lost data
- No way to distinguish "still actively enrolling" from "enrollment finished, agent idle"
## Decision
Replace the static cutoff with an activity-aware idle timeout:
- **`CollectorIdleTimeoutMinutes`** (default: 15) — stops collectors when no "real" events arrive for this duration
- **"Real" events** = everything except `performance_snapshot`, `agent_metrics_snapshot`, and their `_stopped` variants
- Collectors auto-restart when new real activity arrives after idle stop
- `AgentMaxLifetimeMinutes` (default: 360/6h) remains as an absolute safety net
**Implementation:**
- `MonitoringService` tracks `_lastRealEventTime`
- Idle check timer fires every 60 seconds
- Global setting in `AdminConfiguration.CollectorIdleTimeoutMinutes`, delivered via `CollectorConfiguration`
## Consequences
- Long enrollments run to completion — no arbitrary cutoff
- Idle devices stop wasting CPU/network within 15 minutes
- Old agents (not updated) fall back to their built-in 4h default — no breaking change
- The 6h max lifetime timer prevents runaway agents regardless
@@ -1,43 +0,0 @@
# ADR-003: Multi-Signal Session Completion
**Status:** Accepted
**Date:** 2026-03
## Context
Windows Autopilot enrollment can follow multiple paths, and no single event reliably indicates "enrollment is done" across all scenarios:
- **ESP (Enrollment Status Page)** may or may not be present
- **Windows Hello** provisioning may be skipped, succeed, or time out
- **Windows Device Preparation (v2)** has no ESP at all
- **White Glove (Pre-Provisioning)** splits enrollment into two distinct phases
- Devices may reboot mid-enrollment, losing in-memory state
## Decision
Implement 3 independent completion paths, any of which can trigger `enrollment_complete`:
1. **IME Pattern Path** — The existing pattern-based detection from Intune Management Extension logs (legacy, most reliable for app-centric enrollments)
2. **ESP + Hello Composite Path** — ESP final exit event + Hello completion/skip/timeout. For device-only ESP (no Account Setup), a 5-minute timer after Device Setup exit classifies as device-only.
3. **Desktop + Hello Path (No-ESP)** — Desktop arrival (explorer.exe under real user) + Hello completion. Used when ESP is absent (e.g., WDP v2).
**Supporting infrastructure:**
- `EnrollmentStatePersistence` — crash recovery for completion signals (persists seen signals to disk)
- `DesktopArrivalDetector` — polls explorer.exe every 30s, validates user identity (excludes SYSTEM, DefaultUser*)
- Signal audit trail — terminal events include `signalsSeen` and `signalTimestamps`
- Completion check throttling — observability events at 1x/min/source
- WDP v2 gate skip — `enrollmentType == "v2"` skips desktop arrival gate
**Hello behavior:**
- `HelloCompletionTimeoutSeconds` = 300 (5 minutes)
- `HelloOutcome` tracks: `completed`, `skipped`, `timed_out`
## Consequences
- Covers all known Autopilot enrollment paths (Classic ESP, WDP v2, White Glove, device-only)
- State persists across reboots — no lost completions
- Each path is independently testable
- Adding new completion signals requires only extending `EnrollmentTracker.CompletionLogic.cs`
- Complexity concentrated in one partial class file (~789 lines) — acceptable given the domain complexity