v0.2.0
Depth and control. v0.1 proved the wedge — a live service map in under
five minutes with zero app changes. v0.2 makes that install safe to run for
real teams: the hub is secure by default (login, roles, per-project
grants, OIDC SSO), signals are modular (a traces-only install carries no
log or profile weight), the sensor is provably safe to leave on, and four
new modules — error tracking, service health groups, alerting, and green
energy/carbon — turn the data you already collect into triage, status and
accountability. The project is now licensed AGPL-3.0.
Added
- Authentication & per-project access control (secure by default). The hub
now requires login: local users with fixed roles — Admin, Editor, Viewer —
granted per project (or*for all), enforced server-side on every API
route. TheX-Avuru-Tenantheader is validated against the caller's grants,
turning projects into a real security boundary: a user granted only
staginggets 403 anywhere else and a switcher that lists onlystaging.
Fresh installs bootstrap anadminuser (password in the release Secret —
see the install NOTES);auth.enabled=falserestores the previous open
behavior. Opt-in anonymous access grants visitors a role on an explicit
project list only — a public demo can share one project while every other
project stays invisible. Sessions are server-side (revocation is
immediate); logins are rate-limited; state lives in ClickHouse — no new
components. Per-project ingest keys land next on the same seam
(AEPdesign/2026-07-21-auth-oidc-rbac.md). - Enterprise SSO via OpenID Connect. Any OIDC IdP works — Keycloak, Entra,
Okta, Google, Dex (LDAP/AD by federating through the IdP) — and it ships in
OSS, not behind an enterprise tier. The hub runs the authorization-code +
PKCE flow itself (/api/v1/auth/oidc/start→ IdP →
/api/v1/auth/oidc/callback) — no oauth2-proxy, no extra pod — and an SSO
login ends in the same server-side session as a local one, so revocation
stays immediate. IdP groups map to per-project grants declaratively
(auth.oidc.mapping: group → role on projects, plus adefaultRole
fallback), applied at read time on every request — moving a user between
IdP groups re-scopes their access on their next request, no re-login.
forceSSOhides the local password form for IdP-only fleets (the local
admin API login stays available as break-glass). Configured entirely from
Helm values (auth.oidc.*; the client secret comes from your own Secret or
a chart-managed one, never the config file): the mapping is hot-reloaded
(~15s, no restart), and IdP discovery is fail-loud at hub startup so a wrong
issuer stops the rollout instead of shipping a broken login. An opt-in e2e
profile drives the full flow against a real mock IdP through the compose
stack (deploy/compose/docker-compose.oidc-e2e.yaml). - Module framework — pick your signals. One switch per signal family
(modules.<name>.enabled) gates it end to end: its ClickHouse schema
(hub migrateskips the DDL), its Hub API routes (404 when off), its gateway
pipeline, its sensor collection, and its UI entry — so a traces-only install
carries no log or profile weight. The service map + traces + REDcoreis
always on and has no switch. Everything defaults on, so an existing install
upgrades unchanged; turning a module on later is a values change plus
helm upgrade(the migrator is idempotent and applies the newly-active DDL,
and disabling never drops tables). An install advertises its active set at
GET /api/v1/capabilities: the UI sidebar follows it, and a module-off page
prints the exacthelm upgrade --sethint for direct links and bookmarks.
Seedesign/2026-07-15-module-framework.md. - Error tracking — a new module (
modules.errorTracking.enabled, default
on). Exceptions already reaching avuru-obs as span events, error spans and
ERROR/FATAL logs are grouped into deduplicated, triageable issues: a
stack trace, an occurrence timeline and histogram, a link to the originating
trace, and a triage lifecycle (resolved/ignored) that flags a regression when
a resolved issue recurs. Derived in-database from the OTLP you already send,
so it needs no code change and no extra collection. See
design/2026-07-16-error-tracking.md. - Sentry-protocol ingest — opt-in (
gateway.sentry.enabled, off by
default; it opens a network surface). A gateway receiver on:4319accepts
existing Sentry SDKs — browser JavaScript especially, which eBPF cannot
reach — so an app reports by changing its DSN, with no SDK swap. Requires the
error-trackingandlogsmodules (events are stored as log records);
accepted browser origins are configurable viagateway.sentry.allowedOrigins. - Service-map edges derived from OBI network flows. The sensor now builds
topology from OBI's network-flow data, widening the map beyond the protocols
zero-code instrumentation parses. - Service health groups — a new module (
modules.serviceHealth.enabled,
default on). Operator-declared service groups with criticality tiers
(T0/T1/T2), a composite status per group derived from the RED data already
collected, critical-dependency propagation, and a/healthtier-lane board
in the UI. Config is hot-reloadable (a ConfigMap edit re-tiers services with
no restart); unmatched services auto-group by namespace so a zero-config
install still gets a useful board. See
design/2026-07-18-service-health-groups.md. - Alerting — a new module (
modules.alerting.enabled, default on).
Webhook notifications when a service or group crosses into a bad state,
driven by the service-health status stream: declarative rules in values, an
evaluator with firing/resolved transitions, alert history, and a read-only
/alertsUI page. Outbound webhooks are SSRF-guarded
(alerting.webhookAllow). See
design/2026-07-19-alerting.md. - Network health on the service-map edges — per-edge RTT and failed/reset
connection counts from OBI's TCP-stats metrics
(sensor.obi.network.stats, on withsensor.obi.network.enabled),
surfaced as edge tooltips and health styling on the map. The exact OBI
stats key still needs confirmation in a real eBPF environment before prod
use. See
design/2026-07-19-network-health.md. - Green energy & carbon — a new module (
modules.green.enabled, off by
default: the signal depends on RAPL/powercap hardware). Per-service energy
(Wh) and carbon (gCO2e) computed from the energy counters of CNCF Kepler —
an opt-in fourth sensor container (sensor.green.enabled), pinned like every
upstream we reuse — correlated with the pod→workload map the platform
already collects: zero code changes, no data leaves the cluster, no external
API. Ships monthly carbon budgets per service group (warn at 80%, exceeded
at 100%, month-end projection) delivered through the existing alerting
channels, per-request carbon intensity, a/greendashboard with a
service-map energy overlay, and a CSRD-ready CSV/JSON export whose
methodology block states the formula, factor provenance and measurement
coverage — numbers an auditor can reproduce. Grid-intensity factors are
bundled per-country annual averages with operator overrides (air-gap
friendly); all math runs at query time over tables that already exist, so
there is no migration. On nodes without RAPL the module reports honestly
instead of estimating (coverage ratio + a teaching empty state), and the
Kepler container carries no probes so it can never destabilize the sensor
pod. Kepler's metric names, config keys and port are CI-validated against
the pinned image but must be confirmed on real RAPL hardware before
production use. See
design/2026-07-22-green-carbon.md. - The sensor is now provably safe to leave on. The e2e wedge gate keeps a
probe-sensitive canary — tight CPU limit, aggressive liveness probe, real
traffic — Ready with zero restarts through a soak with the sensor attached,
so "installing avuru-obs does no harm" is CI-enforced where it actually
bites. For cautious fleets,sensor.obi.discovery.mode=optInattaches
uprobes only to pods labeledavuru.obs/instrument: "true"(logs, infra
metrics and the inventory keep flowing), and a staged-rollout runbook
(docs/runbooks/sensor-rollout.md) covers canary node pools, soak, and the
escape-hatch ladder. See
design/2026-07-17-sensor-safe-by-default.md.
Changed
- Relicensed from Apache-2.0 to AGPL-3.0.
Removed
- The cancelled Rust eBPF L4 flow tracer (
agent/), together with the
proto/cross-language contract that existed to carry itsflow.proto.
Service-map topology now derives from OBI network flows instead, so the
custom tracer, its flows schema and its codegen are no longer planned.
Security
- UI image OS packages patched at build. The nginx-alpine base lagged behind
Alpine's security fixes (Harbor flagged OpenSSL/zlib/libexpat CVEs); the UI
Dockerfile now runsapk upgradeso each build ships the patched packages. A
new CIimage-scanjob builds every image and fails on fixable HIGH/CRITICAL
CVEs (Trivy,--ignore-unfixed) to keep it from regressing.