Skip to content

Changelog

All notable changes to this project are documented below. This project uses Semantic Versioning and Conventional Commits. This page is generated from the repository CHANGELOG.md.

5.2.1 (2026-10-21)

Bug Fixes

  • deps: enforce Go 1.27.3 and distrusted CA bundles (862bd1e)
  • deps: update module github.com/knadh/koanf/v2 to v2.4.0 (#719) (7160cfe)
  • deps: update module github.com/prometheus/prometheus to v0.315.1 (#730) (e2dabdf)
  • deps: update module modernc.org/sqlite to v1.61.0 (#729) (d8c7975)

5.2.0 (2026-10-13)

Features

  • config: acknowledge the flow store at rest; skip perm advisory on kubelet RO mounts (45d541f)
  • nodemetrics: curate sampled Service throughput with scoped dashboard (3393e3c)
  • probe: inspect OTLP HTTP acknowledgements safely (d5f023f)
  • settings: emit bounded route-selection modes and preserve absent values (84ab7ca)

Bug Fixes

  • alerts: exempt devices that cannot self-update from auto-update coverage (a7123cf)
  • alerts: scope auto-update posture rule; surface config advisories in Loki (98d4f39)
  • ci: provision existing just tool for client-library tests (9bb62a0)
  • deps: update module github.com/klauspost/compress to v1.20.3 (#708) (a4c9e68)
  • deps: update module github.com/oschwald/maxminddb-golang/v2 to v2.8.0 (#707) (453e9c8)
  • deps: update module github.com/prometheus/common to v0.72.1 (#706) (627a537)
  • deps: update module golang.org/x/sys to v0.49.0 (#699) (c854778)
  • docs: gate README overview capability counts (c071d91)
  • grafana: anchor empty fleet summaries to observed inventory sources (373608d)
  • grafana: consolidate current cardinality and overflow views (8ce801c)
  • grafana: count distinct metric families across reporters (01f65be)
  • grafana: distinguish missing cardinality reports from healthy zeros (0ee91ed)
  • grafana: distinguish missing exporter telemetry from healthy zeros (2cd8d44)
  • grafana: enforce applicable selectors across dashboard queries (00a9936)
  • grafana: label route mode as historical observations (2480a1f)
  • grafana: make OS pie legend readable with expanded navigation (963635c)
  • grafana: scope node metrics by tailnet and provider (67c5bf0)
  • grafana: show neutral missing process telemetry on runtime stats (6f1797b)
  • ingress: bound permanent rejection retries and count data loss (c30c532)
  • review: require complete finding totals to match events (50cb41a)
  • scripts: report CodeRabbit finding counts in sharded review summary (02f11c2)
  • telemetry: attribute runtime traces and correct dashboard ownership (760fda5)
  • telemetry: bind delivery-health diagnostics in every provider (7977987)
  • telemetry: decouple ingress WAL completion from metric collection (3f2b465)
  • telemetry: distrust malformed HTTP response classification (07acc0e)
  • telemetry: log only bounded classes in export failure diagnostics (303616b)
  • telemetry: report hung ingress exports as retrying (df6cd72)

5.1.0 (2026-10-08)

Features

  • dashboards: add fleet and security visual views (48731fd)
  • dashboards: add flow topology views (4065d0e)
  • dashboards: add specialist panel primitives (f2ee3d4)
  • dashboards: add state and cost visualisations (25971a7)
  • dashboards: diversify dashboard visualisations (bc2fd2a)
  • dashboards: track visualisation diversity audit (6872e54)

Bug Fixes

  • deps: update go dependencies to v0.37.1 (#652) (2617306)
  • deps: update module github.com/grafana/otel-profiling-go to v0.7.0 (#687) (6880dbd)
  • deps: update module github.com/grafana/pyroscope-go to v1.4.3 (#673) (1076aa4)
  • deps: update module github.com/knadh/koanf/providers/env/v2 to v2.0.2 (#682) (7fa38fa)
  • deps: update module github.com/knadh/koanf/v2 to v2.3.7 (#654) (7ea4916)
  • deps: update module github.com/knadh/koanf/v2 to v2.3.8 (#689) (d4298fb)
  • deps: update module github.com/oschwald/maxminddb-golang/v2 to v2.7.0 (#669) (d7c4afe)
  • deps: update module github.com/prometheus/common to v0.72.0 (#664) (c885c40)
  • deps: update module go.opentelemetry.io/proto/otlp to v1.11.1 (#671) (324e504)
  • deps: update module modernc.org/sqlite to v1.60.1 (#668) (cc1bab7)
  • deps: update opentelemetry to v1.47.0 and stable logs v1 (677a905)
  • portservice: refresh the IANA service registry (b4faa1d), closes #678

5.0.4 (2026-09-18)

Bug Fixes

  • alerts: close the severity contract - validate it, and document advisory (8f04a03)
  • deps: pin google.golang.org/grpc to v1.83.2 (CVE-2026-84445) (f58018e)

5.0.3 (2026-09-18)

Bug Fixes

  • deps: update go dependencies (#618) (cd0b961)
  • deps: update module github.com/oschwald/maxminddb-golang/v2 to v2.6.0 (#616) (56334cc)
  • deps: update module google.golang.org/grpc to v1.84.0 (#635) (951443e)
  • deps: update module modernc.org/sqlite to v1.59.0 (#632) (9b87e46)
  • wal: allow complete batched metric flushes before retrying (423c3ae)

5.0.2 (2026-09-07)

⚠ BREAKING CHANGES

  • helm: stop version-varying labels on the checkpoint claim template

Bug Fixes

  • helm: pin volumeMode on the checkpoint claim template (d24ef9c)
  • helm: stop version-varying labels on the checkpoint claim template (3658371)

Documentation

  • helm: chart 0.36.0 needs a one-time StatefulSet delete with persistence enabled (9416f6a)

5.0.1 (2026-09-07)

Bug Fixes

  • app: stop the ingress WAL startup drain blacking out a promoted leader (9e72581)

5.0.0 (2026-09-06)

⚠ BREAKING CHANGES

  • config: Enabled non-loopback streaming and webhook receivers now fail startup unless every legacy or routed endpoint has its required token or secret. Credential-free loopback listeners remain supported for local-only use and warn about local injection risk. Go consumers must use github.com/rknightion/tailscale2otel/v5.

Features

  • admin: harden Wave 3 storage and access (6d9c23c)
  • alerts: cover coordination leadership health (74a8c92)
  • alerts: watch five signals that nothing alerted on (7841543)
  • app: wire wave 1 runtime controls (1de673f)
  • checkpoint: persist cursors in Kubernetes (ed38f70)
  • collectors: configure dedup capacities (1209ff3)
  • collectors: quiet expiry warning cadence (72fb042)
  • config: add fleet discovery and operator forecasts (882b4cf)
  • config: freeze PAM tailnet and session-log configuration seams (7f4cbfa)
  • config: freeze wave 1 configuration (f54548a)
  • config: freeze Wave 3 configuration seams (992c3e3)
  • config: require credentials for network receivers (69ca527)
  • console: adopt design system v2 (05a1c9c)
  • coordination: add Kubernetes Lease leadership (1195f4b)
  • coordination: label the leader pod and let standbys be Ready (06522af)
  • dashboards: regroup operational surfaces (1ea4b8b)
  • devices: bound posture attribute cardinality (06e7fc7)
  • dev: shard CodeRabbit pre-commit review (322f1e8)
  • headscale: honor retry and rate limits (7292f5a)
  • helm: add extraContainers for sidecars alongside the exporter (31b7c31)
  • helm: per-replica persistent state for coordinated replicas (5d966fe)
  • helm: route leader-only Services by the role label (522f662)
  • helm: support coordinated replicas (aea526d)
  • logstream: expose bounded destination configuration per log type (dbaeeb4)
  • node-metrics: support per-tag port overrides (e4c9e46)
  • observability: complete Wave 2 lifecycle coverage (fa6a465)
  • pam: add Border0 telemetry collector (9994c0a)
  • pam: opt-in per-session log record behind pii_filter (c94ba92)
  • pam: select the tailnet runtime that hosts PAM telemetry (076ac92)
  • resilience: harden Wave 3 ingestion and runtime (f35b6ab)
  • snapshot: freeze Wave 2 snapshot and config seams (27c92b4)
  • telemetry: apply per-tailnet cardinality limits (175e3ce)

Bug Fixes

  • alerts: bound a dead leader's vote in the coordination rules (2c40439)
  • alerts: emit the absolute deploy/alerts README link from the generator (76a0b8f)
  • alerts: match Grafana runtime status shape (f2e221e)
  • alerts: verify post-publication evaluations (eb5c7fd)
  • app,tsapi: close flow stores on failed construction and pin the org path segment (2167354)
  • app: bound concurrent flow store shutdown (2d84e51)
  • app: emit the scope-preflight metric from the heartbeat (8634816)
  • audit: classify new configuration audit values (102333f)
  • audit: classify PAM configuration changes (f339e17)
  • auth: implement workload identity exchange contract (5b55617)
  • auto-rc: restore checks:read — reusable permissions validate at startup (86c3e84)
  • checkpoint: reconcile markerless rollback writes (0513e63)
  • checkpoint: reconcile rollback-era legacy writes (47f16b8)
  • checkpoint: restart after uncertain Kubernetes writes (976cc00)
  • checkpoint: shard Kubernetes checkpoint state (2901c12)
  • ci: give the tailnet-join workflows their own WIF secret (810ef36)
  • ci: make clientlib drift verdicts explicit (37c941b)
  • ci: repin rknightion/.github refs to v1.9.7 so Renovate can track them (35ddeb1)
  • ci: unbreak the release pipeline and stop :main freezing on infra failure (daf81d8)
  • config: make secret source conflicts explicit (1513eb1)
  • config: reject oversized Kubernetes checkpoints (b0eb87a)
  • coordination: deduplicate handover observations (fe3c3cc)
  • coordination: expose standby process metrics (15e4777)
  • coordination: self-fence on lease replacement (8477683)
  • coordination: validate retry jitter bound (0e212ab)
  • deploy: close starter and verification gaps (d3af40f)
  • deps: update go dependencies (#600) (3ae7cb8)
  • deps: update go dependencies (#610) (7809c8b)
  • deps: update module github.com/rknightion/tailscale2otel/v4 to v4.0.1 (#584) (274dafe)
  • deps: update module modernc.org/sqlite to v1.58.0 (#606) (50f4e77)
  • deps: update v5 self-module matcher (ef9f5ea)
  • docs: gate alert panel-link counts (f9a9ad4)
  • flowstore: keep legacy flow database usable (22a023b)
  • headscale: classify configured tailnet prefixes (1fbb579)
  • helm: default coordination to release namespace (ff444ba)
  • helm: give kubeconform the CRD schemas for ServiceMonitor (4f60b87)
  • helm: restore the doubled braces in the CRD schema URL (7c680b6)
  • ingest: close cancellation races (16f25e1)
  • observability: address Wave 2 review findings (a18a5dd)
  • observability: scope the dedup overlap horizon to the poll path (e3caac4)
  • stream: restore flow capture delay telemetry (f825e5d)
  • telemetry: guard stable instrumentation scope (86f4b5e)
  • tooling: select Grafana verification context (630b1d7)

4.0.1 (2026-08-27)

Bug Fixes

  • acl: persist revision provenance (8b510f6)
  • ci: follow GitSync dashboard path (e0d20a2)
  • dashboards: repair live signal accuracy (d00c0ce)
  • release: stream the latest-release response instead of buffering 64 KiB (59bae17)
  • state: separate evidence durability from poll cursors (66fcb05)

4.0.0 (2026-08-27)

⚠ BREAKING CHANGES

  • improve first-run delivery experience
  • move the Go module path to /v4 ahead of the 4.0.0 release
  • flowstore: rename flows.store.path to directory and surface backend health

Features

  • admin: add a bounded audit and webhook event explorer (8b655e9), closes #300
  • admin: add a per-tailnet selector to the status page (306a161), closes #325
  • admin: add defensive HTTP headers to every admin response (7d4aa8f), closes #322
  • admin: export the complete effective redacted configuration (fffa889), closes #320
  • admin: generate a privacy-safe support bundle (a7b49a6), closes #321
  • admin: list active configuration advisories on the status page and API (8491a31), closes #319
  • admin: make both embedded UIs keyboard-operable and screen-reader-legible (66ac88d), closes #327
  • admin: make UI polling single-flight, visibility-aware and backoff-capable (1b3176a), closes #328
  • admin: report actual OTLP delivery state instead of a collector proxy (5c38fd2), closes #317
  • admin: show update availability on the status page (e736ba2), closes #330
  • alerts: canonical recording rules, SLO burn-rate alerts, and approval-workflow alerts (623240e), closes #406 #398 #410
  • alerts: close the notification gap on object-store, receiver, drop and posture faults (99c1226), closes #399 #401 #402 #404 #405
  • alerts: enable ConfigInvalid by default, and record standing Grafana push authorization (fec022a)
  • alerts: per-rule evaluation policy, runbook and panel links, and a real PromQL parser gate (e54a4cd)
  • annotations: publish curated tailnet events to Grafana as annotations (8d2ab97), closes #518
  • api: freeze availability-state, scope-class and entity-age seams (da772f5)
  • api: restore dropped telemetry dimensions and classify API availability (7445cc6), closes #411 #412 #413 #414 #415 #416 #417 #418 #419 #420 #421 #425 #426 #427 #428 #429 #430
  • api: version and publish the admin status/flows API contract (fde409f), closes #323
  • auditlogs: ingest the configuration-log S3 export (2018f07), closes #288
  • catalog: gate every signal on a declared dashboard/rule disposition (1d2203b), closes #390
  • catalog: gate that every emitted signal reaches a panel (4617b10), closes #526
  • checkpoint: use a platform-appropriate state path on native runs (3ce3461), closes #336
  • ci: authenticate the live-contract lane with workload identity federation (8de36d5), closes #355
  • ci: check documented install commands against the real schemas (123fe72), closes #445
  • ci: review the Tailscale changelog for new observability surfaces (cfc60b9), closes #446
  • ci: watch the committed IANA service registry for staleness (a0fdd75), closes #440
  • cli: add -preflight and -once single-cycle execution modes (ee7e206), closes #311
  • cli: add a native -healthcheck readiness probe (4cc1bb3), closes #337
  • cli: print the effective redacted configuration and where each key came from (355c8b1), closes #309
  • config: add log_format for one-record-per-line JSON logs (c156ccd), closes #312
  • config: advise when a flow-cardinality key is inert under the current metrics_mode (681fe1e), closes #525
  • config: generate a standalone JSON Schema for the application config (b15156f), closes #308
  • config: report every configuration diagnostic in one pass (95da889), closes #307
  • dashboards: add the Kubernetes Audit tab (0e02a05)
  • deploy: add file-based Docker Compose secrets, and fix audit objectstore (a544576), closes #334
  • deploy: ship a validated Alloy gateway recipe (5c422ab), closes #363
  • docs: take the fleet project icon for the site logo and favicon (a6db322)
  • docs: take the fleet-generated social card (4bffb6b)
  • enrichment: add optional local GeoIP and ASN enrichment (47d9e49), closes #461
  • flows: export the filtered connection list as CSV and JSON (cebb89d), closes #299
  • flows: filter and paginate connections server-side (86833de), closes #296
  • flows: make flow-store capacity and memory policy configurable (ead2f47), closes #329
  • flows: put the flow view's state in shareable URLs (1f32b15), closes #298
  • flowstore: optional SQLite persistence for multi-day /flows history (4b25580), closes #294
  • github: replace free-form issue templates with structured forms (ea9f9bf), closes #444
  • grafana: group the flagship's ten flat tabs into a two-level navigation (e0e20b9), closes #495
  • grafana: rebuild the health dashboard around pipeline stages (6a16821), closes #526
  • grafana: rebuild the product dashboard around domains and sub-tabs (b3572e8), closes #526
  • helm: add an opt-in Prometheus Operator PodMonitor (e01d6c6), closes #345
  • helm: add an opt-in Prometheus ServiceMonitor (9ade22f), closes #458
  • helm: add default-off, per-listener Services (1e5d29a), closes #344
  • helm: add first-class projected Workload Identity Federation tokens (30589c4), closes #343
  • helm: add image digests, configurable probes, and a NetworkPolicy baseline (15cd177), closes #349 #350 #351
  • helm: add opt-in Ingress and Gateway API routes for the receivers (9993b50), closes #346
  • helm: add typed extraEnv and extraEnvFrom with a reserved-name policy (b188b9a), closes #348
  • helm: support externally managed application config resources (098dbb3), closes #347
  • improve first-run delivery experience (2cf4644)
  • ingest: add optional durable receiver WAL (04384a2), closes #279
  • ingest: expose trust and harden receiver edges (e88c1c5), closes #262 #263 #265 #266 #270 #275 #276 #281
  • ingest: make event ingestion trustworthy (6561eb7), closes #258 #259 #260 #261 #264 #267 #268 #269 #272 #273 #274 #278 #280 #282
  • k8saudit: export metrics and logs from tsrecorder Kubernetes audit data (b61fe7a), closes #462
  • mint release-please token from the OpenBao broker (fec703d)
  • mint the docs-sync token from the OpenBao broker (b618f04)
  • oas: detect parameter, success-status and media-type drift (ffb7a95), closes #432
  • objectstore: expose provider request and cursor-health telemetry (6709c54), closes #451
  • objectstore: support flat copied-export layouts (0794f61), closes #293
  • objectstore: support per-tailnet storage destinations and credentials (ddef918), closes #284
  • observability: installable alert profiles, dashboard a11y and budget gates, and deployment drift verification (ea53c30), closes #389 #396 #397 #408
  • observability: move alerts to gcx-native manifests and close the 71-signal coverage gap (9a3674c)
  • observability: stop rendering unchecked security signals as healthy zeros, and compare ingestion across sources (db37106), closes #395 #400
  • rdns: serve a resolved PTR name past its TTL while refreshing (e17a3cc), closes #297
  • release: read the published release back and fail when it is incomplete (3c413e1), closes #442
  • s3: support AWS container credential providers (26bb03c), closes #452
  • telemetry: bound log records, trace dark clients, harden /metrics (3858408), closes #356 #366 #367 #369 #371 #374 #375 #376 #377 #378 #379
  • telemetry: finish the OTLP exporter core, sampling and profiling work (0084290), closes #357 #358 #359 #360 #361 #362 #365 #370 #372 #373 #380 #383 #384
  • tls: reload listener certificates in place and expose expiry health (9b92b48), closes #316

Bug Fixes

  • acl: send the policy to /acl/validate, and stop 4xx reading as transient (1e488ef), closes #523
  • admin: derive the status verdict from the same component state as /readyz (3aaab59), closes #318
  • admin: make the /events explorer keyboard- and screen-reader-legible (25e5b2b), closes #512
  • admin: make the default landing page safely usable (3584827), closes #314
  • alerts: 10m pending window on exporter-down and config-invalid (b399957), closes #529
  • alerts: correct the three stale rule counts that have had CI red (b27ed99)
  • alerts: execErrState spells its OK state "Ok", not "OK" — corrected by a real push (5eead5b)
  • alerts: key credential and auth alerts off semantics, not raw counts (2b48098)
  • api: complete API fidelity drift contracts (fb4f877), closes #422 #423 #424
  • apply CodeRabbit auto-fixes (b8634c4)
  • author is Rob Knight, not Rob Knighton (54ef3c7)
  • catalog: a template variable is not a panel (c54e0df)
  • ci: aggregate matrix failures before filing, so one defect files one issue (b695f27), closes #435
  • ci: satisfy workflow contracts (d8a56ad)
  • ci: stop two version/timing-fragile tests failing correct code (cb07b5d), closes #521
  • ci: the dashboard sync reported success while publishing nothing (f167a1c), closes #526
  • ci: use a plain if in the live-contract negative case (2aa2e03)
  • config: canonicalize listener addresses and feed bind failures to readiness (6a113d9), closes #306
  • config: only require a positive prometheus.max_requests_in_flight while the endpoint is on (9df928e)
  • config: protect object-store credentials (3260963), closes #449
  • config: reject global objectstore in multi-tailnet mode (c6f66b0), closes #283
  • config: reject unknown YAML configuration keys (96c5e9b), closes #303
  • config: resolve relative file paths against the config file's directory (8154192), closes #310
  • config: validate complete, loadable TLS keypairs for every listener (a3b96be), closes #305
  • deploy: align Compose and Kubernetes shutdown budgets with the staged drain (ac58014), closes #332
  • deploy: move the Compose config-file mount to an override file (a9311a3), closes #333
  • deploy: split the published-image Compose from the developer build (1faaa5e), closes #335
  • deps: update github.com/tailscale/hujson digest to b80ff77 (#508) (6ca7c86)
  • deps: update go dependencies (#572) (34589ff)
  • deps: update module github.com/knadh/koanf/parsers/yaml to v1.1.1 (#535) (7480415)
  • deps: update module github.com/knadh/koanf/providers/env/v2 to v2.0.1 (#536) (1ecd7dd)
  • deps: update module github.com/knadh/koanf/providers/structs to v1.0.1 (#537) (44f863d)
  • deps: update module github.com/knadh/koanf/v2 to v2.3.6 (#538) (66e0992)
  • deps: update module github.com/prometheus/prometheus to v0.313.2 (#522) (2a032d4)
  • deps: update module go.opentelemetry.io/proto/otlp to v1.11.0 (#499) (f4bf065)
  • deps: update module google.golang.org/grpc to v1.83.0 (#520) (924be79)
  • deps: update module google.golang.org/grpc to v1.83.2 (#576) (391dfa0)
  • deps: update module modernc.org/sqlite to v1.56.0 (#530) (93c61f5)
  • deps: update opentelemetry to v1.46.0 / log v0.22.0 (613d0a3)
  • dev: make cloud setup cross-agent compatible (34f8f78)
  • flowlogs: preserve node identity through poll dedup (622773c), closes #257
  • flowstore: give pre-4.0.0 flow databases a way to be adopted (0741792)
  • flowstore: order recent rows by event time and scope them to the query window (3de4fc7), closes #295 #301
  • flows: version policy verdicts so retained traffic cannot join to the wrong rules (a6d14c9), closes #302
  • grafana: give boolean panels semantic polarity and stop zero-filling absence (be4fc7d), closes #385
  • grafana: panels referenced variables that were not in scope (c300199), closes #526
  • grafana: the degradation row rendered on a healthy exporter (a273aa7), closes #526
  • helm: make liveness/readiness probes follow admin TLS (82e43b5), closes #342
  • helm: reject unknown values with a strict chart schema (69d7746), closes #304
  • helm: render every Secret-typed config field into a Secret, not a ConfigMap (a51d901), closes #518
  • helm: stop teaching credentials on the command line (7cd9a84), closes #341
  • helm: stop the chart README drifting on every release PR (a78961e), closes #521
  • metrics: make Prometheus authentication fail closed (5a0be19), closes #315
  • oas: parse OpenAPI 3.1 type arrays and typed maps in drift analysis (607b32a), closes #431
  • objectstore: accept .json.zstd and .json.gzip export keys (3df1b32), closes #496
  • objectstore: bound decoded ingestion work (f969025), closes #292
  • objectstore: commit objects only after complete preparation (f3e871e), closes #448
  • objectstore: fail an object whose every row fails to decode (4f670ab), closes #497
  • objectstore: persist bounded listing progress (8c951e2), closes #285
  • objectstore: persist failed ingestion gaps (bf7e92d), closes #286
  • objectstore: stop erasing durable listing progress under a leading-slash prefix (2fb0c45), closes #498
  • objectstore: support official export keys (9b9f7a3), closes #447
  • pass the JWT role explicitly for docs-sync (cb91b11)
  • receivers: carry trace context onto streamed flow, audit and webhook logs (0a3536e)
  • release: wait for the module proxy before GoReleaser rebuilds from it (f59c6f4), closes #254
  • s3: preserve configured endpoint base paths (1e716e1), closes #290
  • s3: stream list responses and refuse oversized ones explicitly (7ebdb9c), closes #291
  • security: close 14 advisories across credentials, admission control and cache trust (6b65274)
  • security: close the EPIC-10 follow-ups across decode budgets, retries, and checkpoints (15b1038), closes #488 #489 #490 #491
  • security: close the public hardening backlog across privacy, credentials, and build context (476f236), closes #464 #465 #466 #467 #468 #469 #470 #471 #472 #473 #474 #475 #476
  • security: remediate 19 scan findings (45e489c)
  • selfobs: correct object-store ingest source and byte semantics (cc6e498), closes #450
  • status: light up api-availability for every collector, and make the status page say why (6acd70f), closes #524
  • status: show the state of collectors that have no matrix row of their own (8b674af), closes #524
  • telemetry: bound OTLP metric export batches (6b1093a), closes #494
  • telemetry: stop identical target_info duplicating on every Prometheus scrape (844f267), closes #519

Refactoring

  • catalog: delete pending_panel now that every signal has a panel (e726aad), closes #526
  • config: extract the effective-config projection to a leaf package (0d31d9f)
  • flowstore: rename flows.store.path to directory and surface backend health (5b25a5e), closes #294
  • grafana: split the dashboard generator into builder, variables and tab modules (8f36ffd), closes #495
  • grafana: split the flagship dashboard into a tailnet and a health artifact (372b169), closes #526
  • objectstore: add provider-neutral ingestion engine (d701ebe), closes #453
  • telemetry: freeze one Options seam per outstanding EPIC-04 child (1e63883)

Build System

  • move the Go module path to /v4 ahead of the 4.0.0 release (4374b06), closes #521

3.0.0 (2026-07-25)

⚠ BREAKING CHANGES

  • move the module path to /v3 and guard the next major
  • flowlog: cardinality.flow.destination_service is removed and tailscale.dst.service is emitted unconditionally on both flow metric families. The rollup families already carried it ungated, so the toggle only ever governed the raw ones — the same dimension appeared or vanished with metrics_mode. Its value space is a fixed IANA registry rather than the ephemeral port range, so gating it bought little. An existing destination_service: in a config file is silently ignored (unknown YAML keys are); a stale TS2OTEL_CARDINALITY__FLOW__DESTINATION_SERVICE raises the unknown-variable advisory at startup. Deployments on metrics_mode all/both gain the label on tailscale.network.io/packets, which changes those series' identity.
  • admin: pii_filter no longer applies to the /flows view or /api/flows.json. An operator who set e.g. pii_filter.emails: false previously saw no user attached to any flow on the admin page, and will now see them; the same holds for hostnames, tailscale_ips and external_ips. Exported telemetry is unchanged — the filter governs it exactly as before. The admin token is now the only control over who can read tailnet identity from this process: if the set of people holding it is wider than the set who may see your users' email addresses, set a narrower admin.auth.token or bind admin.listen to loopback.
  • admin: with an empty admin.auth.token, the admin status page and its JSON APIs (/, /api/status.json, /api/cardinality.json, /api/config.json, /api/rdns/purge) now return HTTP 403 on any non-loopback admin.listen instead of serving unauthenticated. The default listen is the wildcard :9091, so a default deployment is affected. Set admin.auth.token (e.g. TS2OTEL_ADMIN__AUTH__TOKEN) or bind admin.listen to loopback. The process still starts, and /healthz and /readyz remain open on every bind, so container and Kubernetes probes are unaffected.
  • stream: an enabled streaming receiver with an empty streaming.token on a non-loopback streaming.listen now refuses every request with HTTP 403 instead of accepting unauthenticated POSTs. Log ingestion stops until streaming.token is set (e.g. TS2OTEL_STREAMING__TOKEN) or the listener is moved to a loopback address. The default listen is the wildcard :8088, so a receiver previously running without a token is affected. A loud ERROR naming both remedies is logged at startup.
  • config: a config with a polling flowlogs/auditlogs max_window that is positive and <= interval now fails startup validation instead of only warning.
  • nodemetrics: two node_metrics static targets resolving to the same effective identity (same normalized URL and instance label) now fail config validation instead of being silently double-scraped.
  • stream: a corrupt or partially undecodable stream batch is now rejected with a 4xx (sender retries) instead of being partially ingested and acknowledged 200. The valid-prefix salvage behaviour is removed.
  • helm: Helm installs/upgrades with replicaCount != 1 now fail rendering instead of deploying multiple pollers.

Features

  • aclpolicy: compile and evaluate a tailnet policy against observed flows (a0a986e), closes #237
  • admin: built-in network flow visualiser at /flows (4427507), closes #237
  • admin: emitted-throughput and collector-fleet trend charts (a1c1fe9), closes #223
  • admin: enable admin server by default on :9091 (730d467)
  • admin: identity views on /flows — tag matrix, split tags, identity on connections (dd81b6b), closes #237
  • admin: show identity in full on /flows, unfiltered by pii_filter (b0616a9), closes #241 #237
  • admin: the path-quality section on /flows (6037e1c), closes #237
  • admin: the policy section on /flows (51937e3), closes #237
  • app: add read-only cardinality and config JSON export endpoints (30d0672)
  • app: build cardinality suite, collector freshness and API auth panels (372627f)
  • app: extend status DTO for cardinality suite, freshness and API auth (71449f3)
  • app: feed the ACL evaluator from the acl and users collectors (5587695), closes #237
  • app: retain per-metric active-series history for cardinality growth view (d072aac)
  • collector: track last successful run time for status freshness (13f60e4)
  • config: add cardinality warning/critical thresholds and label-value sample cap (00b0a65)
  • config: reject positive max_window <= interval for polling log collectors (376b47d), closes #202
  • console: configurable status-page refresh interval (default 5s) (9b13a84), closes #215
  • deploy: expose cardinality threshold + label-cap knobs in Helm chart (5991d21), closes #208
  • flowlog: carry path, DERP region and identity on the rollup families (cb73daa), closes #243
  • flowlog: decode embedded node identity for self-enrichment (8cb3f7b), closes #235
  • flowlog: name IP protocol 99 tsmp and explain what a TSMP flow means (0971527), closes #249
  • flowlog: reconcile each connection against the tailnet policy (c114f92), closes #237
  • flowlogs: read the S3 export as a third ingestion source (a8ce1aa), closes #238
  • flowstore: aggregate the policy verdict, unexplained relationships and rule use (ce15572), closes #237
  • flowstore: bounded in-memory store of recent flow activity (cb40c29), closes #237
  • flowstore: classify how each peer was actually reached on the wire (08d1724), closes #237
  • pyroscope: collect all profile types by default incl. goroutine-leak (fec8915), closes #185
  • stream: make HEC batch delivery atomic instead of ACKing partial loss (cfa330a), closes #201
  • telemetry: capture bounded per-label distinct values and plumb the cap from config (c301413)
  • ui: tabbed layout, light/dark theme, real charts, cardinality suite (55cc1e6), closes #208

Bug Fixes

  • admin: record the fail-closed status page as a breaking change (5656149)
  • admin: refuse the status page on a network-reachable bind with no token (effb816), closes #227
  • alerts: page on tagged device key expiry only, not untagged user devices (15bf0ba), closes #250
  • api: bound successful JSON responses before decoding (054ee09), closes #210 #211
  • deps: update github.com/tailscale/hujson digest to 10d7940 (#213) (2a278df)
  • deps: update github.com/tailscale/hujson digest to 78b5b16 (#225) (e38676c)
  • deps: update module github.com/klauspost/compress to v1.19.1 (#216) (c8fe2f4)
  • deps: update module github.com/prometheus/client_golang to v1.24.0 (#217) (a22617a)
  • deps: update module github.com/prometheus/client_golang to v1.24.1 (#247) (10c5e01)
  • deps: update module github.com/rknightion/tailscale2otel/v2 to v2.0.2 (#188) (9325849)
  • deps: update module google.golang.org/grpc to v1.82.1 (#192) (6d9c74d)
  • flowlog: omit absent flow endpoints instead of fabricating them (b6629a2), closes #236
  • flowlog: read Tailscale's ":0" as the absent port it is (7d36026), closes #248
  • flowlog: stop naming the DERP relay marker as a destination (2004791), closes #245
  • flowlog: timestamp flow logs by window start, not capture time (a0cce89), closes #234
  • flowstore: keep underlay ports out of the destination-services table (e8156bf), closes #246
  • helm: re-sync the chart config block with the app's config surface (c817573), closes #242
  • helm: reject any replicaCount other than 1 (93cb2d5), closes #203
  • nodemetrics: key delta baselines by source series, not post-drop labels (b3217f6), closes #199
  • pii: classify host:port IP values before falling back to hostnames (a206df4), closes #198
  • stream: bound record count, unwrap depth and concurrent bodies; fail closed without a token (992d7f6), closes #209 #228 #229
  • stream: derive the listener write window from the process deadline (f8dab4b), closes #232
  • stream: record fail-closed receiver auth as a breaking change (cd90397)
  • telemetry: apply the PII filter to span attributes (0550813), closes #212
  • telemetry: drop service.version from the metrics resource (#187) (1658133)
  • telemetry: give telemetry pipelines independent shutdown budgets (c7f4f1e), closes #204
  • telemetry: redact PII from log bodies, not only attributes (5441abf), closes #197
  • tsapi: bound OAuth/workload-identity token fetches through the body read (4d5afa1), closes #200
  • tsapi: cap Retry-After backoff at the configured max_delay (d581993), closes #206
  • webhook: reject signed timestamps too far in the future (94774c7), closes #205

Build System

  • move the module path to /v3 and guard the next major (1739277), closes #244

2.0.2 (2026-07-14)

Bug Fixes

  • deps: update module github.com/rknightion/tailscale2otel/v2 to v2.0.1 (#177) (ac0e152)

2.0.1 (2026-07-13)

Bug Fixes

  • build: bump module path to /v2 so v2.x releases can build (c252d50), closes #174

2.0.0 (2026-07-13)

⚠ BREAKING CHANGES

  • the telemetry attributes above (and their Prometheus label normalizations) are renamed with no compatibility window; update external queries per the docs/upgrading.md v2.0.0 table.

Features

  • add -version and -validate flags to the release binary (86c2e35), closes #162
  • align telemetry attributes with OTel semantic conventions (e59642d), closes #161
  • auth: workload identity federation (auth.method: workload_identity) (d55341a), closes #168
  • ci: report which live-contract ops actually ran (550f84d)
  • collector: OAuth Apps collector + OpenAPI spec re-vendor (8f2c3ca), closes #167
  • config: file-based secrets (*_file) for all credentials (a474fb9), closes #169
  • deploy: alert + dashboard pack for the v2.0.0 program (25aa62b), closes #172
  • devices: emit multipleConnections, blocksIncomingConnections, postureIdentity.disabled (e5551fc), closes #163
  • devices: posture-attribute expiry telemetry (de0c50c), closes #164
  • keys: key owner (userId) and auto-applied device tags (e548e5e), closes #165
  • nodemetrics: curate key tailscaled client metrics into the named catalog (c362a92), closes #171
  • security: fuzz the untrusted-input decoders, add a vuln-reporting policy (ba82856), closes #144
  • services: resolve service-VIP flow peers to service names (f3669cd), closes #166
  • TLS support for the admin and Prometheus listeners (63c02a1), closes #170

Bug Fixes

  • ci: don't fail fuzz jobs on Go's benign -fuzztime shutdown race (c42b28d)
  • ci: run the live API contract lane on ubuntu-latest (0acd799), closes #160
  • deps: update module github.com/grafana/pyroscope-go to v1.4.1 (#142) (b7f83df)
  • deps: update module github.com/klauspost/compress to v1.19.0 (#41) (15a754d)
  • deps: update module google.golang.org/grpc to v1.82.0 (#42) (8abf4ce)
  • renovate: stop raising invalid major bumps of tools/* indirect deps (688a7a6)

1.0.0 (2026-07-05)

⚠ BREAKING CHANGES

  • v1.0.0 stabilises the public interface (config, metric names, HTTP endpoints, Helm values). There are no new breaking changes over 0.6.0; docs/upgrading.md carries the consolidated pre-1.0 to v1.0.0 migration notes for anyone upgrading from an earlier 0.x.

Features

  • declare stable v1.0.0 release (eba5996)

0.6.0 (2026-07-04)

Features

  • app,config: readiness, cache reuse, User-Agent, rate-limit visibility, secret headers + collector fixes (5d43509), closes #66 #76 #57 #85 #70 #79 #73 #61 #63 #67
  • deploy: add fsGroup, extra volumes/mounts, and baseline alert rules (250b4c5), closes #82 #83 #123
  • docs: align docs site with m7kni.io brand + server-side SEO/LLM metadata (77e7c4f), closes #46
  • helm: add conditional liveness/readiness probes to deployment (3210c9b)
  • telemetry: add GaugeSnapshot observable-gauge facade for churn-safe per-entity gauges (ac22409), closes #55

Bug Fixes

  • app: emit enrich.cache_age at export time so staleness is detectable (e3ef49e), closes #108
  • app: join receivers before shutdown; attribute tailnet client failures; static node_metrics once (f0e20d1), closes #53 #125 #59
  • app: report dedup self-obs for every tailnet runtime, not just runtimes[0] (eb2700d), closes #60
  • app: status page reads per-tailnet identity in multi-tailnet (list) mode (796c75b), closes #116
  • app: stop double-counting self-obs under provider=headscale (543b336), closes #54
  • auditlogs: include action/target in the grouped boundary-dedup key (47f0eb1), closes #97
  • collector: checkpoint resilience + effective-store reporting + compile-time registry check (38dfcaa), closes #69 #105 #58
  • collector: don't count shutdown cancellation as a collector scrape failure (0dc5ec0), closes #93
  • collector: errors.As 403 classification (flowlogs) + Headscale adapter fidelity (3b4cbbb), closes #95 #64
  • collector: posture-log PII routing, posture status.error signal, device tags on status page (6035361), closes #56 #99 #102
  • collectors: migrate churning per-entity gauges to observable snapshots (fixes ghost series) (479575e), closes #55
  • config: close validation gaps + backfill tailnet HTTP defaults (4781a88), closes #52 #104 #106
  • config: headscale receiver guard/warnings + least-privilege tailnet OAuth scopes (45d73b8), closes #117 #127
  • config: validate receiver paths, grpc endpoint shape, required tailnet; align Helm defaults (030b185)
  • deploy: correct broken PromQL in shipped alerts + flagship dashboard (08d0b87), closes #107 #109 #110 #111
  • deps: update module github.com/grafana/pyroscope-go to v1.4.0 (#45) (be6e1d9)
  • ingestion: bound wire-derived metric attribute values (audit action/origin, flow proto) (742e6c1), closes #77
  • nodemetrics: bound per-tick scrape time (worker pool + interval deadline) (ff47ce3), closes #80
  • nodemetrics: stable, batch-independent instance-label disambiguation (403dd98), closes #98
  • pii: register user identity keys so per-user gauges suppress instead of collapsing (7126f31), closes #74
  • rdns: enforce cache bound under concurrency + fix Close()/LookupName WaitGroup race (ec63303), closes #118 #121
  • rdns: pick PTR name deterministically to stop flow-metric label flap (158b29f), closes #119
  • security/telemetry: OTLP skip-verify knob, scrub lab identifiers, correct stale comments/descriptions (33942fe), closes #94 #89 #51 #65 #68
  • stream: salvage the valid decoded prefix from a corrupted HEC batch (829c09a), closes #96
  • telemetry: stop /metrics 500 on tailnet_name=false; classify instrument-name errors; guard const-attr collisions (16246da), closes #103 #91 #62
  • tsapi: bound the OAuth token fetch so a hung refresh can't stall collectors forever (086c9b5), closes #84
  • tsapi: tolerate empty device timestamps; fix ServiceHost stableNodeID tag (bb4d575), closes #48 #72

Performance

  • telemetry: alloc-free label-collision fast path; harden portservice gen; document Headscale (4984ad6), closes #86 #128 #71

0.5.0 (2026-06-26)

Features

  • app: auto-resolve tailnet name from the "-" placeholder (f660faa)
  • ci: adversarial Tailscale API drift detection suite (e1e5e20)
  • metrics: add opt-in Prometheus /metrics pull endpoint (e63e4b0)
  • telemetry: emit tailnet/provider as signal attributes, off the Resource (6cfbb52)

Bug Fixes

  • app: hostname-free instance ID under pii_filter; validate and clamp OTLP metric interval (81accad)
  • audit: bound audit-change metric labels; keep identifiers out of ACL/key log bodies (21cd0f9)
  • ci: vendor OpenAPI spec to committed spec/ baseline (drift lanes need it in CI) (4f5f665)
  • config: redact Secret under JSON/YAML marshaling + permissions/cardinality advisories (82d620d)
  • grafana: query tailnet/provider as direct labels, drop target_info joins (78b80a0)
  • helm: never render empty secret keys; serve multi-tailnet config from a Secret (chart 0.7.3) (bffe3f1)
  • http: bound request/response lifetimes on the admin and metrics servers (f5a3340)
  • lint: suppress SA5011 false-positive on t.Fatal nil-guards in tests (15a3096)
  • nodemetrics: restrict discovery to Tailscale address ranges and cap delta baselines (cc990fb)
  • telemetry: respect pii_filter.tailnet_name on universal const attrs; cap collision diagnostics (79a35a7)
  • tsapi: elide variable path segments from API endpoint labels (91ef35a)
  • tsapi: keep OAuth token-endpoint response bodies out of traces and status (d4276a5)

Performance

  • telemetry: drop exemplar reservoirs for synchronous non-histogram instruments (c31d7ba)

0.4.0 (2026-06-08)

Features

  • app: multi-tailnet/MSP via per-tailnet OTEL providers (6648327)
  • pii: configurable redaction filter + identifier backfill (J+K) (8ed3ede)
  • provider: add Headscale control-plane provider (a5e48a4)
  • telemetry: OTLP export-duration self-observability histogram (C2) (0ff4437)
  • viz: drain dashboard/alert backlog — panels, PII rendering, multi-tailnet, taxonomy (096ebec)

Refactoring

  • logs: keep redactable PII identifiers out of log bodies (dfe001a)

0.3.0 (2026-06-07)

Features

  • acl: policy risk-scoring gauges (wildcard/unrestricted/autoapprover/ssh/posture) (de8100c)
  • audit: curated security/lifecycle change counter + device churn (98bcc48)
  • collector: per-collector scrape staleness + budget-headroom gauges (f43fdd8)
  • devices,flowlogs: connectivity quality + exit-node/subnet-router analytics (B3+B4) (f58b73b)
  • devices: fleet hygiene roll-ups (untagged/ephemeral/version/tag distributions + key-expiry histogram) (da158e3)
  • devices: inventory outstanding device-share invites (5bdfa85)
  • dns: unified DNS configuration with override-local + per-resolver exit-node visibility (b51b5dc)
  • keys: inventory OAuth clients & API tokens via the unified key model (4a8a3f7)
  • selfobs: API request latency histogram (api.duration) (756b042)
  • selfobs: ingestion volume + OTLP export-cost self-observability (C8) (d517fa0)
  • selfobs: receiver in-flight/duration, dedup hits, checkpoint/process/config health (C6/C7/C9) (e09ffcc)
  • telemetry: cardinality headroom — series.limit + series.overflowing self-obs gauges (be7be05)
  • telemetry: OTEL traces pillar — scrape/API/receiver spans + exemplars (e8b78ee)
  • version: self update-available + device version-skew via shared release fetcher (02a47d1)

Bug Fixes

  • docs: remove glightbox slide_effect option (rejected by zensical 0.0.44) (5083835)
  • keys: correct stale docs and keys-by-type dashboard aggregation (b9420c9)
  • selfobs: drop unnecessary int64 conversion in tvToSeconds (unconvert) (012307f)

0.2.0 (2026-06-06)

⚠ BREAKING CHANGES

  • config: restructure schema, env-driven loader, generated env-var reference
  • node-metrics series now carry the scraped node's identity on the tailscale_node label instead of instance (which on Grafana Cloud always held the collector host); update node-metrics dashboards/queries accordingly. The per-device posture log now defaults to on-change; set

Features

  • admin: add status landing page, JSON API endpoint, and opt-in profiling (pprof + Pyroscope) (282a333)
  • admin: authenticate status page + pprof with a shared token (bbfea01)
  • admin: per-collector info tooltip on status page (5bfd025)
  • alerts: add Grafana-managed alert + recording rules (a49dab0)
  • app: derive overall health + enrich collector status rows (e3f86b8)
  • app: redesign admin status page — health, sparklines, API panel, live tables (e7a26d5)
  • app: sample runtime/cardinality trends for status sparklines (b03d4a1)
  • app: start the series.active cardinality reporter, gated by self-obs (a9db840)
  • app: surface per-endpoint API health and window checkpoint state (66359f6)
  • app: tag subsystem loggers with component for per-subsystem filtering (da75818)
  • app: wire dynamic node-metrics discovery from the devices API (3900f89)
  • app: wire node-metrics passthrough filters into nodeMetricsOptions (1c42f81)
  • bounded top-N flow-metric rollups (default) with other + unique counts (d8bcbb8)
  • cardinality cap, stream feature.enabled, posture metric, node-label fix (d3e5494)
  • cardinality: per-entity gauge toggles for devices/users/keys (389352f)
  • collector: track per-collector run history and consecutive failures (4f7e5ca)
  • config: add node_metrics.discovery schema (7b29868)
  • config: document new collectors + cardinality toggles (config + Helm chart) (fb55c8c)
  • config: redact credential fields via a Secret type (987de8f)
  • config: restructure schema, env-driven loader, generated env-var reference (0891d26)
  • config: warn on undefined ${ENV} references at load (d10b3cb)
  • contacts: add tailnet contact verification collector (9ddbc66)
  • devices: add tailnet-lock errors + per-DERP-region rollup (dbbcd19)
  • devices: add tailscale.tags label to per-device gauges (3c8c5d1)
  • devices: expose MDM/posture attributes as queryable metrics (e3eb199)
  • flow-log service-name mapping, independent port toggles, external reverse-DNS (0835122)
  • grafana: add Cardinality & Cost tab (1a93a1e)
  • grafana: add comprehensive v2-schema multi-tab dashboard (generated) (843f1e0)
  • grafana: add DERP-vs-direct connection-path row to Node Metrics tab (0a47685)
  • grafana: add Security & Audit tab (027c9fb)
  • grafana: add tag filter and Devices-by-tag panel to Fleet tab (ce86f71)
  • grafana: dashboard coverage for new collectors (3131e672+) (ec527f6)
  • grafana: surface alloc churn, heap objects, GC next-target in Diagnostics (e4c52f1)
  • helm: expose collectors.devices.attribute_namespaces (1dfa89e)
  • logstream: add log-stream delivery-health collector (a0b259b)
  • nodemetrics: add metric_allow/metric_deny/drop_labels passthrough filters (603790c)
  • nodemetrics: emit discovery-health gauges (cbb4831)
  • nodemetrics: support dynamic target discovery (1b86831)
  • posture: add device-posture integration sync-health collector (3131e67)
  • rdns: observability, purge control, and larger defaults for the PTR cache (a8b8867)
  • ringbuf: add generic thread-safe bounded ring buffer (14c01c7)
  • selfobs: add runtime, dedup, and component-error self-observability metrics (b0fa95f)
  • services: add Tailscale Services (VIP) collector (30900f4)
  • settings: surface httpsEnabled, aclsExternallyManaged & external-tailnets role (667e4e7)
  • telemetry: add tailscale2otel.series.active cardinality self-metric (918ca76)
  • tsapi: add equal-jitter to retry backoff (62f73ca)
  • tsapi: decode per-device tags from /devices?fields=all (6e7906a)
  • tsapi: honor HTTP-date form of Retry-After (8e0ce6e)
  • tsapi: per-attempt timeout so long Retry-After is honored (85c3584)
  • tsapi: rate-limit retries, not just first attempt (87107a1)
  • tsapi: status-aware retry logging (429 INFO, 5xx DEBUG, 401 ERROR) (65403c8)
  • tsapi: widen request hook to RequestInfo (latency + error) (4d89430)
  • webhooks: add webhook-endpoint inventory collector (8931eb9)

Bug Fixes

  • app: don't log receiver clean shutdown as ERROR (0db54c8)
  • ci: authenticate cosign to ghcr.io before signing the chart (c363142)
  • ci: bump Go to 1.26.4 to clear govulncheck stdlib findings (5345bce)
  • ci: bump tool modules to go 1.26.4 to match root module (50cb7db)
  • ci: clear govulncheck stdlib findings + fix broken action versions (62ace00)
  • ci: cosign snapshot image digest (#12) (5bf2fa0)
  • ci: make snapshot chart prerelease version valid SemVer (ba12049)
  • ci: pin cosign installer action (#10) (8ae03eb)
  • ci: pin cosign-installer to @v3 (no moving v4 tag exists) (37c9f7f)
  • ci: pin cosign-installer to @v4.1.2 (required for cosign v3+) (0bf6156)
  • ci: rename helm-values-schema-json input -> values (0a0b900)
  • ci: use correct losisin/helm-docs-github-action@v2 repo (2680758)
  • collector: run first collector tick promptly at startup (2c72ee3)
  • config: scope the undefined-${ENV} advisory to active config values (d6809f8)
  • deps: update github.com/tailscale/hujson digest to ecc657c (d9843a0)
  • docker: copy per-platform binary in dockers_v2 multi-arch build (f780ca5)
  • docs: redact live tailnet recon details from tracked files (5ded0e6)
  • flowlog: bound rollup accumulator memory between flushes (629b111)
  • grafana: correct policy/config, network & diagnostics panels (4bfd717)
  • grafana: show 0 not "No data" for empty audit-count stats (a0c26a2)
  • grafana: stabilize panels across redeploys (strip service_version) (2224bce)
  • guard main snapshot publishing (44ee52e)
  • helm: disable ServiceAccount token automount by default (289a0fd)
  • nodemetrics: bound discovered scrape work (2770030)
  • nodemetrics: unique short MagicDNS instance labels + collision guard (f578e54)
  • reserve node metrics identity label (#16) (d439c38)
  • restrict main snapshot publishing to main ref (1e58858)
  • security: harden receivers, scraper, TLS, and Helm from security review (b743858)
  • selfobs: guard cardinality reporter against non-positive interval to prevent panic (cf1d7f4)
  • stream: cap zstd decoder back-reference window at the body limit (bfde16b)
  • telemetry: drop OTLP→Prometheus colliding labels and log export errors (874cf1b)
  • telemetry: stop emitting redundant service.version on build_info (d82d71d)
  • webhook: bound request bodies pre-auth and add server timeouts (92348f4)
  • webhook: stop user cross-dedup over-suppressing distinct changes (D11) (75a2c98)
  • webhook: wire replay-protection tolerance from config (default 5m) (7ce9cf6)

Performance

  • telemetry: disable unused metric exemplars, add GC tuning knobs (5e6fce3)

Refactoring

  • config: remove dead oauth token_url field (d21f11c)
  • config: remove legacy cardinality.flow_include_ports toggle (6bc1a56)
  • tsapi: use min() in computeBackoff (3e58f5f)

Miscellaneous

  • release: make 0.2.0 the first complete release (ec62fb1)
  • release: set initial release version to 0.1.0 (8f1a18e)