v0.3.0
Tenancy you can trust. v0.2 secured the read side — login, roles,
per-project grants, SSO. v0.3 closes the write side and makes the project
itself a thing you administer: create, rename and delete projects from the UI,
then mint per-project ingest keys so a sender no longer just claims a
tenant — in enforce mode the key decides where its telemetry lands,
overriding anything the payload says. Around that: a one-click read-only
demo anyone can click through, green energy on RAPL-less cloud VMs (the
majority of real fleets), the groundwork for runtime collection control, and
the deploy layer renamed to match the project — avuruops → avuruobs
(breaking; see Changed).
Added
-
Per-project ingest API keys (Phase 2). Telemetry can now be
authenticated at the write side, replacing topology-based trust of a
client-suppliedavuru.tenant. Admins mint keys in Settings → General →
Ingest API keys (orPOST /api/v1/projects/{project}/keys); the raw secret is
shown exactly once and only its SHA-256 is stored. The gateway validates
keys through a new in-repo collector extension (avuruingestauth) against a
hub control-plane endpoint — the hub is never in the telemetry byte-path —
with a 30 s verdict cache and a 5 min stale grace so a hub blip cannot drop
traffic.
Rolled out throughauth.ingest.mode:off— no key checking.log(default) — validate and count would-be denials, reject nothing.
The pipeline is byte-identical to a pre-ingest-keys install, so the
drop-in OTLP promise survives the upgrade: existing unkeyed senders keep
landing unchanged.enforce— unkeyed or invalid OTLP is rejected, and the key's project
becomes the authoritative tenant, overriding anything the sender claims.
A sender that lies about its tenant lands where its key says.
The chart provisions and seeds the sensor's own key, so enabling
enforce
never silences avuru's own agent. The internal token and sensor key are
generated once, reused across upgrades, and live only in a Secret — asserted
at render time. -
UI-managed projects (Phase 1). Projects now have a persistent identity you
control from the app. Admins create, rename, and delete projects in
Settings → General; the switcher and General tab reflect them immediately,
while the built-indefaultand deployment-config projects stay read-only
(clearly labelled). A project's id is an immutable tenant slug; only its
display name is editable, so no telemetry is ever rewritten or lost — delete
removes the entry and its data ages out by retention. New admin endpoints:
POST/PUT/DELETE /api/v1/projects(global-admin only);GET /api/v1/projects
now returns each project'slabel,source, andeditableflag. Groundwork
for per-project ingest keys and multi-cluster aggregates (Phases 2–3). -
One-click read-only demo. A "Try the demo" button on the login page signs
a visitor in as a scoped viewer (viewer@demo) — the shared password stays
server-side (a rate-limited/api/v1/auth/demo), never in the browser.
Opt-in viaauth.demo.enabled; pair with the OpenTelemetry Astronomy Shop
overlay (deploy/demo/astronomy) tagged
avuru.tenant=demofor live data across every module. -
Runtime collection control — control-plane groundwork. The hub can now
store and serve a bounded, schema-validated collection overlay
(GET/PUT/DELETE /api/v1/collection/overlay): whole-signal on/off plus the
shared namespace-exclusion list, as a closed schema — no free-form collector
YAML is ever accepted from a client, so the API adds no injection surface.
Gated bycollection.runtimeControl.enabled(default off), which also
provisions a dedicated ServiceAccount and a namespaced Role scoped to the
four named sensor ConfigMaps and the one named sensor DaemonSet — nothing
cluster-wide. This release ships the storage, validation, API and RBAC only:
the applier is a logging no-op and Settings → Collection stays read-only, so
an overlay is persisted but does not yet change what the sensor
collects. Editing collection at runtime lands in a later release; keep using
Helm values. See the
AEP. -
Licensing clarity. LICENSING.md states the model in
full: AGPL-3.0 community edition forever (backed by the CLA §2.2 pledge),
the node agent as upstream Apache-2.0 OBI, a planned commercial enterprise
edition that only ever adds, and dual licensing for embedders.
make noticesgenerates THIRD-PARTY-NOTICES.md
(Apache §4 attribution for bundled dependencies) and is now a release
checklist step. The UI package now declaresAGPL-3.0-onlyexplicitly. -
Contributor License Agreement live. Every first-time contributor signs
the Individual CLA via a one-comment bot flow; §2.2 pledges all
contributions remain available under AGPL-3.0 forever. -
Green TDP estimation for RAPL-less nodes. The green module now works on
the infrastructure most teams actually run: on a node with no RAPL/powercap
— the overwhelming majority of public-cloud VMs — a new opt-in estimator
models CPU power from utilization instead of leaving/greenempty. Every
number it produces is stamped estimated end to end (SQL, API, UI, and
the CSRD export's methodology block) and is never blended with real
RAPL-measured numbers, so what you see is always honestly labeled — trend
and regression grade (±30-50% typical error), never presented as
audit-grade./greengains a coverage panel (known/measured/estimated/
absent nodes) that finally makes the RAPL-less share visible instead of
silently invisible, and carbon budgets include estimated energy (so an
all-VM fleet's budget can still trip) while flagging how much of a
threshold breach is modeled versus measured. Opt in with
sensor.green.estimation.enabled(requiressensor.green.enabled); the
bundled CPU power-coefficient table is sourced and cited (Cloud Carbon
Footprint, cross-checked against the original SPECpower-derived notebook).
See the AEP.
Changed
-
BREAKING —
avuruopsis nowavuruobseverywhere. The deploy layer and
the env-var contract now match the project's actual name. Renamed: the Helm
chart (deploy/helm/avuruobs, published at
oci://ghcr.io/<org>/charts/avuruobs), theAVURUOPS_*environment-variable
prefix (→AVURUOBS_*), the config mount paths, the generated Kubernetes
resource names, and the green-quality telemetry attribute
avuruops_quality(→avuruobs_quality).Upgrading from 0.2.x is not a plain
helm upgrade. Chart resource names
and theapp.kubernetes.io/nameselector label derive from the chart name,
and selector labels are immutable — an in-place upgrade of a release
installed asavuruopswould try to rename every object and fail. Two
supported paths:- Keep the existing release:
helm upgrade avuruops oci://ghcr.io/<org>/charts/avuruobs --version 0.3.0 --set nameOverride=avuruops, which pins the old name and fullname so no object
is renamed. - Start clean:
helm uninstall avuruopsthen install asavuruobs. The
ClickHouse PVC is not deleted with the release, so retained telemetry
survives if you re-point the new release at it; otherwise data starts
fresh.
If you set any
AVURUOPS_*variable yourself (Compose, baredocker run,
your own manifests), rename it — the chart handles its own. Green series
written before the upgrade carryavuruops_qualityand therefore read as
unknown quality (the same tier as pre-AEP data), never as measured; they
age out by retention. - Keep the existing release:
Fixed
- A fresh install with demo mode on could end up with no admin account. The
admin bootstrap only ran when the install had no users at all, and the demo
viewer — which the server creates itself, from a sibling goroutine — could be
written first. The bootstrap then read that as "already provisioned" and
skipped the admin, on that boot and every boot after:admindid not exist,
so every sign-in attempt failed withInvalid email or passwordeven with the
correct password from the release Secret. The demo viewer no longer counts
toward that check, so the admin is created whichever write lands first — and
an install already stuck in this state repairs itself on the next restart. - The demo visitor lands on the demo project, not
default. A one-click
demo sign-in now opens on the project the viewer can actually see, and the
active project is re-validated against the signed-in identity — so a project
left over from a previous session can no longer stick and produce an empty
view.GET /api/v1/projectsis markedno-storeso one user's project list
is never served from cache to the next. - Helm install could fail on a fresh cluster. The auth and ingest Secret
templates indexed into the result oflookupbefore checking it found
anything, so rendering broke when the Secret did not exist yet — precisely
the first-install case. - Login behind a reverse proxy. The UI now forwards the client
Host
with its port, so sign-in works when the port is not the scheme default. - Settings Users tab no longer hides the tab bar. It is now an in-place tab
(?tab=users) instead of a separate page, so the tab navigation stays put;
/settings/usersis kept as a redirect for deep links. - Login page brand casing ("avuru obs" → "Avuru Obs"), matching every other
surface.
Security
- Gateway: pinned
golang.org/x/textto v0.39.0 (CVE-2026-56852).