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.

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)