Skip to content

v1.0.0

Choose a tag to compare

@rknightion rknightion released this 25 Jul 11:55
4ac6a0f

1.0.0 (2026-07-25)

⚠ BREAKING CHANGES

  • m365: rename user_principal_name to user_id on both audit signals - the name claimed a shape the value does not have
  • telemetry: stamp tenant_id on every domain signal - two tenants' metrics were the same series

Features

  • admin: /healthz + per-collector status page (5b7e0ac), closes #12
  • admin: align console with fleet standard — tabbed layout, auto-refresh, wider table (#206) (e17788a)
  • admin: richer per-collector/per-tenant status page (#85) (fd361c9)
  • admin: runtime, throughput, fleet and headroom trend charts (e4a7439), closes #227
  • admin: surface ingest transport + twin coverage in status UI (#178 Part A) (1f4dcb8)
  • admin: surface per-collector checkpoint cursor state in status UI (#178 Part B) (5f75ac9)
  • admin: throttle-headroom panel + profiling docs; close pprof AC N/A (#85) (2e69d67)
  • alerts: example Grafana alert rules for expiry, compliance, staleness & throttle (M6 #30) (ff22eb0)
  • auth: per-tenant DefaultAzureCredential wiring + Graph scope (06396c5), closes #3
  • blobpipeline: byte-offset engine for Azure Storage blob ingest (fca3c08), closes #89
  • blobpipeline: metric-derivation seam + recency-window gate fn (#128) (2b3dd46)
  • blobpipeline: opt-in exclude_self drops the poller's own exhaust from blob ingest (ad92d56), closes #154
  • blobpipeline: recency gate + gate self-obs metrics and per-tick summary log (#128) (51a3537)
  • checkpoint: file-based per-tenant+endpoint CheckpointStore (6adfce2), closes #7
  • cmd: wire the M1 composition root (telemetry provider + admin server) (eb2a95b)
  • collector: collector framework + per-collector self-observability (a830310), closes #6 #9
  • collectors: 6 Intune export-report gaps from the #202 catalog sweep (9fc685e), closes #204
  • collectors: add defender.email_post_delivery and quarantine audit coverage (5bb442c), closes #233
  • collectors: add defender.quarantine — queue depth over Exchange Online (073eb8e), closes #233
  • collectors: an EXO-transport window path, and a HighVolume opt-in (e7e8a6e), closes #254
  • collectors: beta collector opt-in seam (59ac9ff)
  • collectors: Defender + message-center on by default; Experimental means Graph-beta only (8cf65f5), closes #183
  • collectors: Defender incidents, M365 unified audit, Purview labels (#92, #97, #101) (b66596d)
  • collectors: Entra app/SP credential expiry buckets (flagship) (c7cc115), closes #48
  • collectors: Entra authentication-methods policy config gauges (3555357), closes #72
  • collectors: Entra Conditional Access + named location posture gauges (16d4c7b), closes #58
  • collectors: Entra consent surface privileged-grant gauges (02f5ff5), closes #70
  • collectors: Entra directory roles + PIM assignment gauges (ff33946), closes #66
  • collectors: Entra directory-audit, provisioning, risk-detection & security-alert logs (d7814ce), closes #22 #23 #24 #25
  • collectors: Entra directory-device aggregate + stale gauges (4edea3c), closes #44
  • collectors: Entra domains verification/federation posture gauges (be169c8), closes #46
  • collectors: Entra groups population + role-assignable gauges (c02d4e5), closes #43
  • collectors: Entra licensing subscribedSku utilization gauges (e6f6244), closes #45
  • collectors: Entra MFA/auth-methods registration summaries (9d3db52), closes #69
  • collectors: Entra organization tenant + dir-sync freshness gauges (bc0d5a3), closes #47
  • collectors: Entra recommendations gauges (beta, opt-in) (e1c222d), closes #74
  • collectors: Entra risky users + risky service principals gauges (5a9ce18), closes #71
  • collectors: Entra Secure Score + control-profile gauges (e4683dc), closes #68
  • collectors: Entra sign-in log WindowCollectors (interactive + beta streams) (7e55f03), closes #18 #19 #20 #21
  • collectors: Entra SP/credential sign-in activity gauges (beta) (d4f2cae), closes #75
  • collectors: Entra terms-of-use agreements + acceptance gauges (22c42d1), closes #73
  • collectors: Entra users population + stale-account gauges (98bd0f1), closes #39
  • collectors: entra.deleted_items — directory recycle-bin census (#191) (3647b21)
  • collectors: entra.graph_activity reads MicrosoftGraphActivityLogs from blob (8027d10), closes #89
  • collectors: entra.graph_activity.endpoint_requests counter + URI normalization (#185) (bbdcb58)
  • collectors: entra.graph_activity.requests recency-gated counter (#128) (441e193)
  • collectors: entra.graph_notifications + intune.compliance_alerts blob collectors (60d7571), closes #134
  • collectors: entra.risk_detections UserRiskEvents blob source (#135-C) (9f4a4be)
  • collectors: entra.risky_agents + entra.agent_risk_detections — Entra Agent ID risk (beta, read-only) (99670c8), closes #133
  • collectors: entra.service_principal_risk_detections (#133 SP half) (90b3708)
  • collectors: entra.service_principal_risk_detections maps MITRE technique (#133) (3e0a7b8)
  • collectors: entra.signin.count across the blob sign-in family (#187) (fdc92d8)
  • collectors: EPM user/publisher attribution + per-device encryption posture (bfbe749)
  • collectors: expose detected license Caps on collector Deps (8360b9b)
  • collectors: five bounded posture signals riding existing fetches (b2dfa9d), closes #124 #125 #122 #173 #123
  • collectors: five collectors off the Phase 6 grants, plus two silent data-loss fixes (3d129cb), closes #255 #256 #257 #258 #259 #260 #261
  • collectors: intune boot-security, Autopilot-V2 + EPM-elevations exports (96b0591)
  • collectors: Intune config, apps, update & security metrics (M4 wave 2) (17a1502), closes #53 #54 #56 #57 #59 #60 #63 #64 #65
  • collectors: Intune device, compliance & inventory metrics (M4 wave 1) (d427cdf), closes #49 #50 #51 #52 #55 #61 #62 #67
  • collectors: Intune export-report metrics — app install, certs, Defender (M5) (fe68c16), closes #37 #41 #42
  • collectors: Intune log WindowCollectors + reports export subsystem (M5 foundations) (971667e), closes #14 #15 #16 #17
  • collectors: intune.autopilot_deployment_apps + _scripts — device-prep V2 Apps/Scripts tabs (14c14cb), closes #202
  • collectors: intune.cloud_pc_audit — Windows 365 admin-audit blob source (#198) (4608e59)
  • collectors: intune.devices — compliance grace-period expiry on the twin (#193) (5059d84)
  • collectors: intune.devices_blob — Devices twin via keep-gauges/suppress-twin (#135-F) (635421d)
  • collectors: intune.endpoint_analytics — OS-version app-health aggregate (#194) (770aaaa)
  • collectors: intune.endpoint_analytics — Windows 11 upgrade readiness (WFA) (77af941), closes #194
  • collectors: intune.epm_elevation_events — per-elevation SIEM stream over an export watermark (9883cfd), closes #205
  • collectors: intune.remediation_run_states — proactive-remediation per-device health (read-only beta) (709be25), closes #207
  • collectors: keep-gauges/suppress-twin guard + entra.risky_users blob (#135-C) (f7c9739)
  • collectors: M2 collector framework + Entra directory counts (c9e9449), closes #36
  • collectors: m365.sharepoint_settings — tenant SharePoint/OneDrive sharing posture (171b0c4), closes #127
  • collectors: m365.storage — SharePoint + OneDrive storage capacity (d40add3), closes #120
  • collectors: m365.teams — Teams inventory (ownerless, guests, membership) (#121) (debb0e1)
  • collectors: managed-identity sign-ins, update-policy summaries, 2 Defender tables (#135, #193, #200) (2ac12bb)
  • collectors: mdca.discovery_parse — Cloud Discovery parse health (#145) (e8ee309)
  • collectors: MGAL native histograms — request.duration + response.size (#186) (c8f3d4a)
  • collectors: noncompliant_settings — map SettingStatus code 5 -> error (a436064)
  • collectors: purview.ediscovery_cases — eDiscovery case inventory (#102) (5d49f57)
  • collectors: read three sign-in categories from blob, timestamped correctly (180caf8), closes #135
  • collectors: source graph|blob toggle + AuditLogs/ProvisioningLogs blob twins (f9dfd2a), closes #135
  • collectors: wire jobpipeline JobClient into WindowDeps (#97) (e04eed7)
  • config: blob_ingest.metric_recency_window gate key (#128) (8371f4f)
  • config: expand config surface for the collector framework (0a88fb0), closes #2
  • config: tenant-level exclude_self spanning blob + Graph transports (#176) (66d55eb)
  • dashboards: add throttle/rate-limit panels to the self-obs dashboard (6193d39), closes #29
  • dashboards: Grafana dashboards for Entra, Intune & self-observability (M6) (f71c871), closes #27 #28 #29
  • defender.oauth_app: OAuth-app posture on the hunting engine (b4ed339), closes #252
  • defender: advanced-hunting blob engine + deviceregistry (#106) (51ffdac)
  • defender: behavior layer + Teams message security — 4 blob containers read by nothing (02d8e08), closes #241
  • defender: device_logon, device_info, email, alert_evidence (#106) (26eaedf)
  • defender: device_process, device_file, device_network, device_event (#106) (75b9d5e)
  • defender: DeviceTvm* posture — vulnerabilities, secure config, software inventory (1f99aa6), closes #249
  • defender: emit identity_logon last_seen_for_user enrichment (#106) (d2bfee2)
  • defender: tenant allow/block list, the standing-holes-in-mail-security signal (702a395), closes #250
  • defender: the 8 companion advanced-hunting tables (#106) (363548b)
  • entra.app_ownership: ownerless apps + federated identity credentials (1c4e405), closes #244
  • entra.gsa: Global Secure Access posture — #130's deferral has fired (27c2258), closes #239
  • entra.pim_role_policies: what it takes to activate a role — bounded requirement gauge + Warn twin (46492cb), closes #242
  • entra.tenant_policy: CIS-shaped tenant posture switches as bounded 0/1 gauge + twin (197ea8d), closes #245
  • entra: emit the risk-detection fields that were on the wire and dropped (c7864d6), closes #159
  • entra: extract role_name, granted_scope, modified_property_names on directory_audits (#190) (1d73fe7)
  • exoclient: add the Exchange Online admin API transport (5b50d7d), closes #233
  • exoclient: surface response truncation, and stop believing the nextLink (268cd7d), closes #254
  • exo: Exchange Online DKIM + Defender for Office 365 policy posture (7ee6803)
  • graphclient: 4xx/5xx self-observability counters (#91) (07f829b)
  • graphclient: Graph client factory with re-attached Kiota middlewares (408d3ba), closes #4
  • graphclient: per-workload rate limiters + own backoff (c578bb2), closes #5
  • helm: Kubernetes Helm chart + wire chart publish into the release pipeline (M6 #26) (271a4d8)
  • hunt: advanced-hunting query engine + HuntDeps, the 7th registration path (c7180b9), closes #249
  • initial project scaffold (7d182ad), closes #1
  • intune.devices: widen $select — model, manufacturer, wiFiMacAddress, partnerReportedThreatState (fd06d6a), closes #180
  • intune.endpoint_analytics: per-entity log twins on every sub-fetch, plus startup processes and device app health (4a976fc)
  • intune.endpoint_analytics: per-model score rollups, and the sixth score category nobody mapped (45f0fe0), closes #194
  • intune.hardware_inventory: per-device hardware inventory over chunked $batch (b85fc1b), closes #199
  • intune: Managed Google Play bind health + Autopilot sync staleness (9bd01ff), closes #248
  • intune: per-device log twin for endpoint_analytics device scores (5b770e9), closes #179
  • intune: reports-export + endpoint-analytics coverage, first wave (#192) (35c4afa)
  • intune: retire both app allow-lists, relying on the central limiter (40d9e43), closes #235
  • jobpipeline: async job-poll collector engine mode (#88) (6801985)
  • license: per-tenant license-tier detection + graceful degradation (eb2a6a9), closes #10
  • logpipeline: generic watermark poller for all WindowCollectors (ed2d70a), closes #13
  • logpipeline: window-collector registration seam for M3 (a466fb7)
  • m365.exchange_audit_config: report unified-audit-log ingestion state (9b51997)
  • m365.teams: Teams installed apps (sideloaded + RSC) and channel census (966483c), closes #247
  • m365: collect the unified audit log over the stable Management API (98d5583)
  • m365: emit user_principal_name on m365.activity, move the adapter into o365pipeline, document the second write-scope break (0f57e1f), closes #100
  • m365: Exchange Online mail-flow connectors, the routing nobody watches (2800ef4), closes #253
  • m365: Exchange transport rules, remote domains, mailboxes and org config (85ae23f), closes #250
  • m365: message-center collector (#182) (66d3d62)
  • m365: per-message mail flow from the Exchange Online message trace (0f9b5da), closes #254
  • m365: service-health collector (#119) (c581d13)
  • o365activity: add the Office 365 Management Activity API client (6b80308)
  • obs: blob-category census — detect billed-but-unread diagnostic categories (0018b32), closes #238
  • ops: dashboards-as-code — a catalogue that maintains itself, and a gate that proves coverage (6ddaaf4)
  • ops: fleet-parity wave 1 — release tooling, console tabs, file-secrets, helm/docs (6312c02), closes #209 #210 #211 #212 #213 #214 #215 #216
  • ops: generate alert + recording rules from the signal catalogue + CI gate (66b991d), closes #219
  • ops: Microsoft Graph beta drift canary (f6a957a), closes #220
  • preflight: graph2otel check permission-preflight subcommand (fbdb72b), closes #11
  • profiling: optional Pyroscope continuous profiling (9f0c9cb)
  • purview.dlp_policies: DLP policy inventory + enforcement mode (93f5da5), closes #246
  • pyroscope: collect all profile types by default incl. goroutine-leak (cf01fba), closes #107
  • scripts: seed-diagnostic-data.py — re-light thin diagnostic containers on demand (00e4a43)
  • scripts: storage-report — per-container write-op breakdown (16f0145)
  • scripts: storage-report.py — estimated monthly cost per container (1b18a56)
  • scripts: storage-report.py — per-container blob-storage sizing + growth tracking (26c0d13)
  • scripts: storage-report.py — what-if cost modelling knobs (32b1e45)
  • telemetry: active-series cap config + emit series.* self-obs (#105) (0ab7ac5)
  • telemetry: add the ingest_transport provenance attribute and its stamping seam (603cd69), closes #141
  • telemetry: capture metric unit and aggregation kind in the signal goldens (aedd01b)
  • telemetry: central per-metric cardinality limiter, replacing the SDK cap (86c2cf7)
  • telemetry: classify every metric unit as additive or not, and gate it (1e03ff3), closes #235
  • telemetry: freeze the Emitter facade interface seam (da4513d)
  • telemetry: OTLP provider + Emitter facade + in-memory recorder (f372948), closes #8
  • telemetry: stamp ingest_transport on every emitted log record (62c3850), closes #141
  • telemetry: stamp tenant_id on every domain signal - two tenants' metrics were the same series (b0293c4), closes #143 #160
  • test: capture what every collector really emits, and fail on drift (2bf2b37), closes #140
  • test: gate #112 mechanically - no per-entity data on a metric label (94f6ca9)
  • wirecheck: report Microsoft API responses that contradict what we built against (f08f994), closes #233
  • wirecheck: watch 14 assumed value sets across 9 collectors, all of them metric labels (db50d00), closes #234
  • wirecheck: watch entra.risky_agents' risk enums, reusing entra.risk's sets (f1bc0db), closes #234
  • wirecheck: watch four more metric-label fields off their existing bucket maps (f30e296), closes #234
  • wirecheck: watch the four raw-passthrough risk + sharing metric labels (67f7fb9)
  • wirecheck: watch the last five metric-label collectors from the beta CSDL (c703629)

Bug Fixes

  • checkpoint: resume in-flight async jobs across restarts, make backfill configurable (4ab4523), closes #118
  • ci: pin go-licenses to v1.6.0 for the Dockerfile notices bake (765a590)
  • collectors: cap risk-detections page size at 500 (d4d7966)
  • collectors: correct consent $filter encoding and users stale count (9604905)
  • collectors: declare Reports.Read.All on entra.signin_activity (fc0cfe5), closes #84
  • collectors: don't license-gate entra.service_principal_risk_detections (#133) (66ae6d4)
  • collectors: emit a log twin for risky users and service principals (2c57fdd), closes #110
  • collectors: emit a log twin for the Purview label catalogs (f4ed32c), closes #111
  • collectors: emit log twins for the four Intune decode-and-drop collectors (4b331b6), closes #114
  • collectors: emit log twins for the six Entra decode-and-drop collectors (b0b75ac), closes #114
  • collectors: enforce transport mutual-exclusion - camden shipped every non-interactive + service-principal sign-in twice (7551f59), closes #144
  • collectors: entra.risk emits the risky-SP gauge without WIP capability (#133) (9d50c0b)
  • collectors: live-verify fixes — incidents $top, m365 beta, purview app-only (#109) (5eef26d)
  • dashboards: both domain dashboards were 100% dead - 74 queries filtered on a label that does not exist (59489eb), closes #158
  • dashboards: correct metric names for OTLP->Prometheus normalization (fc7238b), closes #82
  • engines: empty dedupe id no longer poisons SeenIDs in job/log pipelines (0d4bd53), closes #262
  • entra.secure_score: emit the 234 per-control rows fetched and discarded every hour (fd8cb41), closes #243
  • entra: map directoryaudits initiator_service_principal_id (478c1a5), closes #168
  • entra: provisioning emits service-principal attribution from the real object shape (b3f38e5), closes #167
  • entra: reconcile entra.risk gauge against deleted-items tombstones (#155) (1df2370)
  • entra: risk_type was a dead mapper line; emit MITRE techniques and isProcessing (57ac365)
  • entra: securityincidents emits custom_tags/system_tags from the wire (7870b38), closes #169
  • exportjob: omit select for reports that reject localized _loc columns (6041bfc), closes #203
  • intune.endpoint_analytics: an omitted UXA score was published as a real zero (9e2dc45)
  • intune.endpoint_analytics: exclude the -1 "insufficient data" sentinel from timing and score histograms (1577068), closes #224
  • intune.endpoint_analytics: twin every app-health row instead of dropping unlisted apps (b9c594c)
  • intune.settings_catalog: baseline filter matched 1 of 7 security baselines (c3d61d2), closes #223
  • intune.settings_catalog: security-baseline summary never worked — wrong path AND wrong field names (15d2f16), closes #222
  • intune: auditevents log Body renders displayName, not the null activity field (a1cf204), closes #172
  • intune: decode export enum codes - platform=2 was iOS shipping as "windows", ProductStatus bucketed 100% of the fleet to other (3cac762), closes #142
  • intune: decode multi-flag productStatus instead of bucketing it (e701bbd), closes #150
  • intune: drop app_name from the app-install metric, add its missing log twin (8765ea2), closes #83
  • intune: emit id on intune.enrollment_failure logs (00e8e6f), closes #166
  • intune: endpoint_analytics called dead/wrong UXA endpoints (#179) (e64f5a4)
  • intune: malware log twin warned on every healthy device (aae4e69), closes #157
  • intune: scripts decodes runSummary/remediation counts at top level (54489d6), closes #174
  • jobpipeline: adopt in-flight jobs on a cold checkpoint - from has two provenances and equality can never hold (a14f34d), closes #147
  • m365.exchange_connectors: outbound connectors are a different record shape, and six booleans were fabricated (c2feef6), closes #253
  • m365.storage: fail the collector when all four usage reports fail (07d6bb6), closes #240
  • m365: rename user_principal_name to user_id on both audit signals - the name claimed a shape the value does not have (fa3395f), closes #163
  • m365: ship ExtendedProperties values - withholding them was #110's error (417f420)
  • m365: unifiedaudit client_ip reads auditData.ClientIP (2fe6b2c), closes #170
  • m365: user_id meant UserKey on one transport and UserId on the other (5ea620e), closes #151
  • o365: tolerate AF20024 - m365.activity failed on every tick live (55e3999), closes #100
  • obs: route OTEL SDK errors through the app logger (d06cb83), closes #231
  • persist checkpoints in the compose reference and fail fast when the dir is unwritable (aad052d), closes #117
  • purview: a sensitivity-label 403 must fail the collector, and the declared scope was the wrong permission (078b5de), closes #126
  • purview: sensitivitylabels description reads toolTip (0654039), closes #175
  • release: keep the chart README version badge in lockstep with release-please (3967630)
  • release: put each chart version badge on its own line for release-please (be1e3e0)
  • release: use shields query form so release-please can't eat the badge color (22d0afa)
  • scripts: measure AppendBlock ops instead of guessing — storage-report was 4.7x high (fd1531e), closes #228
  • syncerrors: drop the opt-in/beta gate — it's a v1.0-stable, default-on collector (2bcf98d), closes #123
  • telemetry: drop service.version from the metrics resource (#104) (519c002)
  • telemetry: GaugeSnapshot erased every other tenant's series (3acbcc7), closes #236
  • telemetry: relocate backdated log records — the backend silently drops them past ~4h (9a3efc0), closes #226 #230
  • telemetry: revert the backdate clamp — its premise was a measurement artifact (65ce1ff)

Performance

  • collectors: poll entra.mfaregistration hourly, not every 15 minutes (adc6df4), closes #115
  • collectors: request odata.maxpagesize on full-collection walks (#87) (ce7f6e9)
  • collectors: share the managedDevices fleet fetch across collectors (#87) (c0b96b8)

Refactoring

  • purview: split labels into two packages so a signal can be attributed to its collector (504d83b), closes #140
  • telemetry: single attribute-name registry + shared setStr, no-bare-literal gate (edf715d), closes #161