Commit Graph

66 Commits

Author SHA1 Message Date
Oliver Kieselbach d532ffd7a4 massive re-org and re-structuring 2026-03-06 03:01:24 +01:00
Oliver Kieselbach b880f5b534 Added bootstrap endpoints and handling 2026-03-05 18:02:37 +01:00
Oliver Kieselbach 2b1cd6cb55 BootstrapToken now needs explicit enablement 2026-03-05 17:06:24 +01:00
Oliver Kieselbach 51033cce7b Bootstrap Session implementation 2026-03-05 13:08:14 +01:00
Oliver Kieselbach 0b960d7d6f added PowerShell Script Execution Tracking 2026-03-05 10:12:57 +01:00
Oliver Kieselbach 93037cd83d added Geographic Performance Heatmap 2026-03-05 08:40:36 +01:00
Oliver Kieselbach 82919d4791 session lifecycle: reliable end-detection for all deployment scenarios
Multi-signal enrollment completion with 3 independent paths:
- IME pattern (existing), ESP final exit + Hello (composite),
  Desktop arrival + Hello (no-ESP/WDP v2)

ESP failure detection: terminal failures emit enrollment_failed immediately,
recoverable failures (ESPProgress_Timeout) get 1-min grace period with
recovery cancellation on ESP phase change.

Agent max lifetime timer (6h default, configurable per-tenant) as safety
net against zombie agents. Desktop arrival detector polls explorer.exe
with WMI owner validation. Enrollment state persistence for crash recovery.

Completion check events with full state machine snapshot for observability.
Backend maintenance interval reduced from daily to every 2 hours.
ConfigVersion 12 → 13.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:12:26 +01:00
Oliver Kieselbach 46582be1d9 replace static 4h max collector duration with activity-aware idle timeout
Periodic collectors (Performance, AgentSelfMetrics) now stop after 15 min
(configurable) of no real enrollment activity instead of a fixed 4h window.
They restart automatically when new activity is detected, preventing session
bloat for stuck/unfinished enrollments while keeping data flowing during
legitimately long ones.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 12:32:37 +01:00
Oliver Kieselbach 20e93aa892 add Corporate Identifier Validation with preview-gated UI
Adds a second device validation method alongside existing Autopilot Device
Validation. Corporate Identifier Validation checks devices against Intune
Corporate Device Identifiers (manufacturer + model + serial number) via the
Graph beta searchExistingIdentities endpoint.

Backend: Extract GraphTokenService from AutopilotDeviceValidator for shared
token/consent logic. Add CorporateIdentifierValidator with caching. Update
SecurityValidator with cascading validation (Autopilot first, Corporate
Identifier fallback). Wire new validator through all agent endpoints.

Frontend: Add second toggle in settings gated behind preview mode. Shared
consent flow skips redirect when consent already exists from other toggle.
Section renamed to "Enrollment Device Validation" in preview mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:19:06 +01:00
Oliver Kieselbach 475739109a enhanced Autopilot profile interpretation with Hybrid Join detection and AutopilotMode labels
- CollectAutopilotProfile now interprets AutopilotMode (User Driven/Self Deploying/White Glove)
  and CloudAssignedDomainJoinMethod (Entra Join/Hybrid Azure AD Join) with human-readable labels
- Added IsHybridJoin as first-class session field (SessionRegistration, SessionSummary, Table Storage)
- DetectHybridJoinStatic reads DomainJoinMethod from registry at registration time
- UI session detail shows Autopilot Mode, improved Domain Join Method labels, HybridJoinSkipDCConnectivityCheck
- Dashboard shows purple "Hybrid" badge for Hybrid Azure AD Join sessions
- Note: IsUserDriven/IsPreProvisioned unchanged — profile fields are capabilities, not live state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:14:56 +01:00
Oliver Kieselbach 1fa30b542d WhiteGlove session display improvements and per-phase notification durations
Frontend: Add per-block durations to WhiteGlove event timeline headers,
pause-excluded combined duration in Session Info, visual dashed separator
between Pre-Provisioning and User Enrollment blocks, and group labels with
vertical separator in the Enrollment Progress tracker.

Backend: Store ResumedAt timestamp when WhiteGlove Part 2 starts, use it
to compute Duration 2 (user enrollment only) for Teams enrollment notifications.
Rename "WhiteGlove Pre-Provisioning" to "Pre-Provisioning" in notification text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:44:36 +01:00
Oliver Kieselbach d6dcbe0681 added tenant search, block management, and kill device 2026-03-02 20:56:13 +01:00
Oliver Kieselbach eae2898ce2 add Galactic Admin audit logs, audit pagination, and platform metrics backend cache
- Galactic Admin Mode for Audit Logs: banner + cross-tenant endpoint (galactic/audit/logs)
- Audit page pagination (12 entries per page) with Previous/Next controls
- Platform Metrics: moved computation to backend PlatformMetricsService with 5-min cache
- New endpoint GET /api/galactic/metrics/platform replaces N+1 client-side fetches
- IME log tracker enhancements, DO telemetry pattern, and download progress improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:40:37 +01:00
Oliver Kieselbach 0c739e96ca HelloWaitTimeoutSeconds is now configurable in Configuration 2026-03-02 16:35:58 +01:00
Oliver Kieselbach 1f835c20ac added UserDriven vs WhiteGlove stats 2026-03-02 15:17:38 +01:00
Oliver Kieselbach e63e48da1a added agent emergency reporter 2026-03-02 11:51:25 +01:00
Oliver Kieselbach 10250161ab added agent Analyzer system incl. first analyzer - LocalAdminAnalyzer
Trigger Options: AtStartup, AtShutdown
2026-03-01 19:41:39 +01:00
Oliver Kieselbach e1c6617b53 feat: replace broken JSON blobs in session report ZIP with proper CSV exports
- Remove session.json/events.json/analysis-results.json (serialized as
  {"ValueKind":1} due to System.Text.Json.JsonElement + Newtonsoft mismatch)
- Add session.csv, events.csv, ruleresults.csv — each mirroring the exact
  Azure Table Storage schema (PartitionKey, RowKey, all columns)
- Add timeline.txt (UI timeline view) is retained
- SessionSummary API response now includes OsBuild, OsEdition, OsLanguage,
  IsUserDriven, AgentVersion so session.csv is fully populated
- events.csv: Severity as "Name (int)", PhaseName derived column appended
- ruleresults.csv: JSON columns (RemediationJson etc.) kept as JSON strings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 18:13:17 +01:00
Oliver Kieselbach 14a3ce5b9c feat: fix session report download + add admin note feature
- Fix 500 error on download URL: replace GenerateSasUri() with
  blobClient.Uri (SAS already embedded in service-level connection string)
- Add AdminNote field to SessionReportMetadata shared model
- Read AdminNote from Table Storage in GetAllReportsAsync
- Add UpdateAdminNoteAsync to SessionReportService
- New PATCH /api/galactic/session-reports/{reportId}/note endpoint
- Frontend: editable Admin Note textarea in report detail modal with
  inline save feedback; Admin Note column in reports table with icon
- Add copy-to-clipboard buttons for Session ID, Tenant ID,
  Submitted By, and Email fields in report detail modal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 17:37:52 +01:00
Oliver Kieselbach 80ee69276d feat: add Report Session to Autopilot Monitor Team (Private Preview)
Tenant Admins can report sessions for analysis via a new button on the
session details page. Creates a ZIP with session JSON, events JSON,
analysis results, timeline TXT, events CSV, optional agent log (5 MB
limit), and optional screenshot — uploaded to central blob storage.

Admin-config page gets a new Session Reports table (Galactic Admin only)
showing all submitted reports with comment, email, and blob reference.

Export utilities (generateUiExport, generateCsvExport) extracted to
shared lib/sessionExportUtils.ts for reuse across admin export and
report modal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:11:09 +01:00
Oliver Kieselbach 6083a64ec0 layout re-order in admin-config + session table storage fix 2026-03-01 15:02:17 +01:00
Oliver Kieselbach c6227f546f feat: add agent self-metrics collector and platform metrics page
Add AgentSelfMetricsCollector that measures the agent's own CPU, memory,
threads, handles, and HTTP network traffic (bytes up/down, latency,
request count) with zero overhead — no WMI, no PerformanceCounters,
just Process properties and lock-free Interlocked counters.

NetworkMetrics tracks all BackendApiClient HTTP calls via Stopwatch and
byte counting in finally blocks. The collector emits agent_metrics_snapshot
events (Severity.Debug) through the existing spool/upload pipeline.

Add Galactic Admin-only /platform-metrics page that aggregates agent
footprint data across sessions with CPU/memory/network assessment badges,
per-session breakdowns, and agent version distribution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 01:11:20 +01:00
Oliver Kieselbach 4ce531191b feat: RuleStates table + community rules + remove global edit/delete
- New RuleStates table stores per-tenant enabled/disabled state separately
  from rule definitions, so built-in/community rule updates propagate
  centrally without losing tenant preferences
- New IsCommunity flag on GatherRule and AnalyzeRule models; community
  rules behave like built-in but show a Community badge in the UI
- Merge logic updated: global partition holds definitions (built-in +
  community), RuleStates holds per-tenant toggles, tenant partition
  holds custom rules only
- Fixed AnalyzeRule Trigger field not being persisted to/from Table Storage
- Fixed EnsureBuiltInRulesSeededAsync comparison to include Version,
  Trigger, and TriggerPhase so definition changes auto-propagate
- Removed Edit (Global) and Delete (Global) from Gather/Analyze rules UI;
  rule management is now exclusively via Git + Reseed
- Added Community filter option to type filter dropdowns
- ReseedFromGitHubFunction now deletes both IsBuiltIn and IsCommunity
  rules from global partition before reseeding
- GalacticAdminService dependency removed from Gather/AnalyzeRulesFunction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:33:46 +01:00
Oliver Kieselbach 1f796bf6e3 feat: externalize rules to GitHub + API consolidation + preview mode
## Rules as GitHub single source of truth
- Add 75 individual JSON rule files (2 gather, 18 analyze, 55 IME patterns)
  under rules/gather/, rules/analyze/, rules/ime-log-patterns/
- Add JSON Schemas for all three rule types with VS Code IntelliSense support
- Add CI combine script (rules/scripts/combine.js) + GitHub Action that
  validates schemas with ajv-cli and generates rules/dist/ combined files
- Convert BuiltIn*.cs from hardcoded C# objects to embedded JSON resource loaders
- Add GitHubRuleRepository service to fetch dist/ files from raw.githubusercontent.com
- Add ReseedFromGitHubFunction: POST /api/rules/reseed-from-github?type=all|gather|analyze|ime

## IME Log Patterns
- Extend ImeLogPattern model with Description and IsBuiltIn properties
- Add ImeLogPatterns table + API constants
- Add TableStorageService CRUD methods for IME log patterns
- Add ImeLogPatternService (CRUD, merge, auto-seed from embedded JSON)
- Add ImeLogPatternsFunction: GET/PUT /api/rules/ime-log-patterns (Phase 1: read-only
  for tenants, Galactic Admin can enable/disable/edit globally)
- Add IME Log Patterns management page (/ime-log-patterns)
- Wire GetAgentConfigFunction to use ImeLogPatternService instead of static class

## API route consolidation
- All rule endpoints now under /api/rules/* for single certificate exclusion path:
  /api/rules/gather, /api/rules/analyze, /api/rules/ime-log-patterns,
  /api/rules/reseed-from-github

## Export buttons
- Add per-rule and export-all JSON download buttons to gather-rules,
  analyze-rules, and ime-log-patterns pages

## Admin configuration
- Replace old individual reseed buttons with unified "Fetch & Reseed from GitHub"
  (calls new GitHub endpoint) plus compact individual-type reseed buttons
- Add CDN cache hint: GitHub raw.githubusercontent.com caches up to 5 minutes

## Preview mode
- ?preview=1 URL param seeds localStorage.previewMode (persists across navigation)
- ?preview=0 clears it; toggle in Navbar settings dropdown (indigo, eye icon)
- IME Log Patterns nav link gated behind galacticAdminMode OR previewMode
- Preview badge shown on nav link when active for normal users

## Tests
- Add xUnit test project (net8.0) with 5 tests for embedded resource loading,
  known IME actions validation, and valid categories check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:12:09 +01:00
Oliver Kieselbach 3d7c4a0af2 feat: configurable diagnostics log paths + reseed gather rules
- Add DiagnosticsLogPath model and DiagnosticsPathGuards (agent-side allowlist)
- Global paths configurable by Galactic Admin (AdminConfiguration.DiagnosticsGlobalLogPathsJson)
- Tenant-specific paths configurable in Settings (TenantConfiguration.DiagnosticsLogPathsJson)
- Backend merges global + tenant paths and delivers via AgentConfigResponse (ConfigVersion 9)
- Agent reads merged paths in DiagnosticsPackageService, validates via guards before adding to ZIP
- Admin Configuration page: new Diagnostics Log Paths panel (teal/cyan)
- Settings page: Additional Log Paths section with global read-only chips + tenant chip editor
- Add reseed endpoint and service method for gather rules (POST /api/gather-rules/reseed)
- Docs: SectionGatherRules guard lists collapse by default; SectionSettings adds Additional Log Paths row

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 21:21:30 +01:00
Oliver Kieselbach 8eb8c31e90 feat: EventLog collector rewrite, dynamic gather rule UI hints, docs
Agent:
- Rewrite EventLog collector from System.Diagnostics.EventLog to
  EventLogReader — supports operational/analytic logs (e.g.,
  Microsoft-Windows-Shell-Core/Operational), not just classic logs
- New parameters: eventId (XPath filter), messageFilter (*contains*),
  source (provider name), maxEntries (1-50)
- Event entries now include Event ID in output: [ID:62407]

UI (gather-rules):
- Dynamic target placeholder and hint text per collector type
- EventLog parameter fields: Event ID, Max Entries, Message Filter
- buildParameters() serializes params per collector type (create+edit)
- on_event placeholder updated to show enrollment_complete/failed
- Documentation link in header → /docs#gather-rules

Docs:
- New "Gather Rules" section with all 6 collector types documented
- Each collector: target format, parameters, allowlists, examples
- Trigger types documented (startup, interval, phase_change, on_event)
- Hash-based deep linking from gather-rules page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:58:22 +01:00
Oliver Kieselbach 17cfc91273 fix: persistent sequence counter across boots, spool RemoveEvents collision fix
The event sequence counter reset to 0 on every agent restart, causing three
bugs in WhiteGlove (pre-provisioning) sessions: spool sort order mixed boot
events, backend status regressed from Pending to InProgress, and UI timeline
split broke. Additionally, EventSpool.RemoveEvents used a glob pattern that
could delete files from both boots sharing the same sequence number.

Changes:
- SessionPersistence: persist sequence in session.seq alongside session.id
- EventSpool: RemoveEvents uses exact filename instead of glob, new
  GetMaxSequence for crash recovery
- MonitoringService: init sequence from persistence + spool ceiling, periodic
  save every 50 events + on critical events, save before WhiteGlove exit
- TableStorageService: document WhiteGlove guard as promotion rule
- EnrollmentEvent: clarify Timestamp is agent-side, not server-side

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:39:53 +01:00
Oliver Kieselbach b78b872f68 implement WhiteGlove (Pre-Provisioning) support end-to-end
- Rename HelloDetector → EspAndHelloTracker (class tracks both ESP and Hello)
- Detect CommercialOOBE_ESPProgress_WhiteGlove_Success (EventID 62407) and emit
  whiteglove_complete event; WhiteGlove check placed before generic OOBE_ESP.*Exiting
  regex to avoid false match; idempotency guard prevents duplicate events
- Detect CommercialOOBE_ESPProgress_Failure (EventID 62407) and emit esp_failure
  event with Error severity for timeline visibility
- Agent exits gracefully after WhiteGlove (Environment.Exit, no DeleteSessionId,
  no enrollment-complete marker); scheduled task restarts on next boot
- EnrollmentTracker subscribes to WhiteGloveCompleted event, stops summary timer,
  emits whiteglove_complete without writing completion marker or deleting IME state
- Backend: whiteglove_complete transitions session to SessionStatus.Pending;
  SetSessionPreProvisionedAsync marks session for split-timeline rendering
- Backend: Pending → InProgress auto-resume on agent re-registration (WhiteGlove Part 2)
- Backend: GetExcessiveDataSendersAsync excludes IsPreProvisioned sessions to prevent
  false blocking of devices resuming after weeks in storage
- Shared: SessionStatus.Pending added; IsPreProvisioned added to SessionSummary;
  WhiteGloveComplete event type constant added
- UI: Pending status badge (amber) in dashboard and session detail
- UI: Split timeline for WhiteGlove sessions — Pre-Provisioning Part + User Enrollment
  Part; Awaiting User Enrollment info box when Part 2 has no events yet
- UI: Mark as Failed button enabled for Pending sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:36:24 +01:00
Oliver Kieselbach 81c4806083 Hardening: re-architecture to use mTLS for complete agent communication (agent endpoints consolidated) 2026-02-26 23:02:50 +01:00
Oliver Kieselbach 2d5efc9b73 add excessive data sender detection to nightly maintenance
Devices that continuously send data beyond a configurable window (default
24h) are now automatically blocked by the daily maintenance function,
regardless of session status. Introduces LastEventAt tracking on session
entities (written on every event batch ingest) to enable efficient
per-tenant queries without scanning the Events table.

- Add LastEventAt field to SessionSummary and session entity writes
- Add GetExcessiveDataSendersAsync query (StartedAt < cutoff AND LastEventAt > cutoff)
- Add BlockExcessiveDataSendersAsync maintenance step with idempotency check
- Add MaxSessionWindowHours and MaintenanceBlockDurationHours to AdminConfiguration
- Expose both settings in Device Block Management section of Admin Config UI
- Include HelloDetector agent changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 12:44:03 +01:00
Oliver Kieselbach 58b41a26b1 add temporary device blocking for rogue devices sending excessive data
Galactic Admins can block a device by serial number from the admin-configuration
page. The block is enforced at ingest time (after security validation, before
body decompression) and is configurable in duration (default 12h, max 30 days).
The agent receives a DeviceBlocked signal in the IngestEventsResponse and stops
all uploads for the session. Blocks persist across backend restarts via a new
BlockedDevices table in Azure Table Storage, with an in-memory cache for fast
ingest lookups.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 10:42:17 +01:00
Oliver Kieselbach 326557c4cd add max collector duration policy, SignalR signal refactor, session export tool, changelog page, security-first ingest ordering
- Agent/Backend: configurable MaxCollectorDurationHours (default 4h) stops interval-based collectors on stuck sessions; setting exposed in global admin config
- Backend: IngestEventsFunction now runs all security checks (cert, rate limit, hardware whitelist, Autopilot validation) before touching the request body, eliminating unnecessary gzip decompression and JSON parsing on rejected requests; added TenantId header/body cross-check
- Backend/Frontend: SignalR eventStream refactored from full event payload to signal-only (newEventCount); frontend fetches canonical event state from Table Storage on each signal, eliminating gap issues and phase-name race conditions
- Frontend: fetchEvents replaces (not merges) event list; phaseName computed at render time in eventsByPhase useMemo; 30s catch-up fetch added as safety net
- Frontend: session event export tool in admin-configuration (teal block) — fetch by sessionId+tenantId, download timeline export (.txt with UI phase grouping) and raw CSV export
- Frontend: changelog page (/changelog) with Private Preview context and first architecture entry; dashboard feedback banner updated to link changelog; Navbar overflow menu gains Preview Changelog link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 09:52:22 +01:00
Oliver Kieselbach bbf815f739 remove dead UploadBundle code and fix Lenovo model detection
- Remove UploadBundleRequest, UploadBundleResponse classes (ApiModels.cs)
- Remove UploadBundle API endpoint constant (Constants.cs)
- Remove GetBundleUploadUrlAsync method (BackendApiClient.cs) — no callers anywhere
- Fix HardwareInfo: Lenovo devices report the marketing model name in
  Win32_ComputerSystemProduct.Version, not Win32_ComputerSystem.Model;
  add Lenovo-specific WMI fallback for correct model string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 23:28:53 +01:00
Oliver Kieselbach 6aafaa5ff8 fetch diagnostics SAS URL on-demand to reduce device exposure window
Instead of delivering the long-lived SAS URL in the agent config response
(where it was cached on disk for the full enrollment period), the agent now
requests a short-lived URL via POST /api/diagnostics/upload-url just before
uploading — the URL is held in memory only and never written to config.

Backend: new GetDiagnosticsUploadUrlFunction with same cert/hardware
security validation as all other agent endpoints; GetAgentConfigFunction
now sends DiagnosticsUploadEnabled (bool) instead of the SAS URL;
ConfigVersion bumped to 6.

Agent: BackendApiClient.GetDiagnosticsUploadUrlAsync added;
DiagnosticsPackageService fetches URL on-demand via the API client;
AgentConfiguration.DiagnosticsBlobSasUrl replaced by DiagnosticsUploadEnabled.

UI: settings page parses SAS URL expiry (se= param) and shows expiry date
inline with colour coding; expired or near-expiry URLs trigger
error/warning notifications at the top of the page on load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 21:15:50 +01:00
Oliver Kieselbach 79a4407831 enhanced platform stats and better tenant management 2026-02-24 17:54:39 +01:00
Oliver Kieselbach 2235170a57 add generic event_correlation source for flexible cross-event rule correlation
Replaces the hardcoded app_state_regression source with a generic
event_correlation source that allows correlating any two event types
by a shared field (e.g. appId), with optional time windows and filters
on both events — all configurable via JSON without backend code changes.

RuleCondition gains 5 new nullable properties:
- CorrelateEventType: second event type (Event B)
- JoinField: field to match across both events (e.g. "appId")
- TimeWindowSeconds: max time between Event A and B
- EventAFilterField/Operator/Value: optional filter on Event A

ANALYZE-APP-010 migrated to use event_correlation source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:38:46 +01:00
Oliver Kieselbach 6deb2f9845 fix ANALYZE-APP-010: correlate app regression by appId using new source type
The previous rule incorrectly matched any app_install_completed event
against any app_install_failed event without correlating by appId.

Changes:
- RuleEngine: add app_state_regression source that finds apps where
  app_install_completed is followed by app_install_failed for the same
  appId, with optional DataField filter on the failed event; returns
  appId, appName, both event details and errorDetail as evidence
- AnalyzeRule: document new app_state_regression source in comment
- ANALYZE-APP-010: rewrite to use single app_state_regression condition
  (IME-ERROR-REPORT filter) + enrollment_complete check; evidence now
  contains the exact app name and id that regressed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:19:05 +01:00
Oliver Kieselbach ca39032ed4 Add Telegram notification for new Private Preview tenant signups
Sends a Telegram message to @AutopilotMonitor-PrivatePreview whenever
a new tenant signs up. The bot webhook URL is stored in the new
PreviewConfig table (PartitionKey=TelegramBot, RowKey=config,
WebhookUrl=<url>) — same lifecycle as PreviewWhitelist, easy to remove
after GA. Notification is fire-and-forget and non-fatal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 23:13:22 +01:00
Oliver Kieselbach f1cff9b89e new agent defaults for new tenants 2026-02-18 15:15:26 +01:00
Oliver Kieselbach 19e9713a31 added platform stats 2026-02-18 12:19:52 +01:00
Oliver Kieselbach 31f4cddc13 Large rename job SerialNumberValidation to AutopilotDeviceValidation 2026-02-17 22:49:26 +01:00
Oliver Kieselbach ddc083581b added diagnostics package download link to portal 2026-02-16 20:14:35 +01:00
Oliver Kieselbach 897fd02fe8 Upload Diagnostics package implementation 2026-02-16 19:59:57 +01:00
Oliver Kieselbach 5b835fd7f0 reboot and keep logfiles configurable in UI now 2026-02-16 17:49:49 +01:00
Oliver Kieselbach 25cb01e315 rework agent cleanup
teams notifications on success or failure
2026-02-16 17:18:27 +01:00
Oliver Kieselbach 2354d0a8cd added more agent remote config params + verbose level 2026-02-16 13:26:18 +01:00
Oliver Kieselbach e14675c847 fixed constants
fix for analyze rule reboot loop
added completed timestamp to progress portal
longer os age default in bootstrapper
removed legacy filed name in events
2026-02-16 12:29:03 +01:00
Oliver Kieselbach f0465e76a1 added CORS logging and Agent max auth retry logic via config 2026-02-16 10:09:10 +01:00
Oliver Kieselbach 8227c909a5 added private preview support 2026-02-15 20:07:45 +01:00
Oliver Kieselbach 4802668e38 Re-architecture, removal of dead code, security hardening, Rules re-work, same caching strategy everywhere used 2026-02-15 17:00:18 +01:00