Skip to content

Commit 560c200

Browse files
chore(release): cut v0.2.0-rc.12 (version + CHANGELOG) (#627)
Bumps packaging/version.env to 0.2.0-rc.12 (Eyrie) and adds the CHANGELOG entry covering the 17 PRs since rc.11 (#610-#626): - Activity & audit readability initiative (#615-#624): human-readable titles across all five feed legs, host-scoped Activity + Audit tabs, readable Settings audit rows, CSV/JSON audit export (AU-7), 'The system' attribution. - Host Management fixes (#611, #613): card scan link + working Group/Filters + server-persisted view preference; hostname/IP on scan-detail header. - Pre-release security hardening (#625, #626): CSV formula-injection + silent-truncation guards, keyset-cursor data-loss fix, bounded audit detail. Also drops the now-fixed cursor-pagination data-loss row from BACKLOG.md (resolved by #626). Release tests (changelog/version/package) green. The git tag push that triggers the signed release pipeline remains the operator's step.
1 parent 0abe84b commit 560c200

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

BACKLOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
| **Activity readability Phase 4 — grouping / dedup / noise control** | P2 | Fast-follow to the merged Phases 0-3 (`docs/engineering/activity_readability_plan.md` §Phase 4). Collapse bursts (e.g. "12 packages updated on web-01" instead of 12 rows), suppress monitoring flaps (the NULL→online dev-restart noise above is one case), severity rollups, "N similar events". **Most visible target:** the feed + settings audit log are dominated by `scheduler.tick.dispatched` (~7k) and `system.package.installed` (~7k). Design fork to settle: group at query time (backend, scales) vs client-side (page-only) — recommend backend. **Coupled taxonomy question:** should routine `scheduler.tick.dispatched` be an *audit* event at all? It bloats the AU-compliance audit trail; consider demoting it to a non-audit metric/log |
6666
| **Activity readability Phase 5 — audit compliance hardening** | P2 | Fast-follow, committed track (`activity_readability_plan.md` §Phase 5), for the FedRAMP/CMMC/NIST-800-53 **AU** family. (a) **Tamper-evidence**: populate the `signature` column already reserved on `audit_events` (Ed25519 per-event signing or a hash-chain over the log) — AU-9. (b) **Retention/archival** policy for `audit_events` (none today; relate to the host soft-delete sweep below) — AU-11. (c) An explicit **AU-control mapping doc** stating which capability satisfies AU-2/3/6/7/9/12 (export already covers AU-7) |
6767
| Dashboard "Top failing hosts" widget shows a host UUID | P3 | `WidgetTopFailingHosts` (`frontend/src/pages/dashboard/widgets.tsx`) renders `nameOf(h.host_id)` which falls back to a truncated UUID (`019eccd8…`) when the host isn't in the loaded hosts list. Same "no UUIDs" goal as the activity-readability work, but a non-activity widget. Resolve the name (the widget already has, or can fetch, the host list) so it never shows a UUID |
68-
| Cursor pagination drops rows that share the boundary timestamp | P1 | **Pre-existing** (predates rc.11; surfaced by the pre-release review, not a regression from these changes). The activity feed (`internal/activity/service.go:72-75` + `:156-158`) and the audit-events list (`internal/server/handlers.go` queryEvents) encode the cursor as `occurred_at` alone and filter `occurred_at < cursor` with `ORDER BY occurred_at DESC` (audit adds `, id DESC` to the order but NOT the cursor predicate). If the row trimmed at a `limit` boundary shares the same `occurred_at` as the last returned row, it (and any peers at that instant) are **silently skipped on the next page** — real data loss, made likely on the activity feed because the 5-leg UNION + batch inserts (intelligence/monitoring) produce timestamp ties. Both `TestList_CursorPagination` and `TestAPI_AuditEvents_CursorPagination` use unique per-row timestamps, so the tie path is untested. **Fix:** compound cursor `(occurred_at, id)` with a row-value predicate `(occurred_at, id) < ($ts, $id)` and `ORDER BY occurred_at DESC, id DESC`. Non-trivial for the activity feed: the monitoring leg's `id` is synthesized in the SELECT (not WHERE-able), so the compound predicate must be applied in an outer query wrapping the UNION. Add a tie-straddling test (two rows, identical `occurred_at`, across a limit boundary) |
6968

7069
---
7170

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,62 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1212

1313
---
1414

15+
## [0.2.0-rc.12] Eyrie — 2026-06-20
16+
17+
The fleet activity stream and audit trail are now readable end to end: every
18+
event renders a plain-language title instead of a raw dotted code, enum, or
19+
resource UUID. Host detail gains live Activity and Audit tabs, Settings shows
20+
readable audit rows, and the filtered audit trail can be exported to CSV or
21+
JSON (NIST 800-53 AU-7). The Host Management page got its scan link, Group, and
22+
Filters working with a server-persisted view preference, and a pre-release
23+
security pass hardened the new export and fixed a cursor data-loss bug.
24+
25+
### Added
26+
27+
- Activity & audit readability: the unified feed and the audit list now render
28+
a server-built, human-readable title + summary for all five legs. The three
29+
legs that previously leaked machine codes (compliance/transaction,
30+
intelligence, audit) are humanized — a rule's catalog title instead of its
31+
id, "Package updated" instead of `system.package.updated`, "alice@example.com
32+
created a host" instead of `host.created` over a UUID. Unmapped codes degrade
33+
structurally (dots/underscores to spaces) so a newly-added code can never
34+
surface as a raw dotted enum. (#616, #617)
35+
- Host detail: a live **Activity** tab (host-scoped unified feed) and a
36+
readable **Audit log** tab, with audit `message`/`resource` filters so you can
37+
pull one host's lifecycle trail. (#618, #619)
38+
- Settings: a readable **Audit log** view with plain-language rows. (#622)
39+
- Audit export: `GET /api/v1/audit/events/export` streams the filtered audit
40+
trail as a downloadable CSV (default) or JSON attachment, capped at 10000
41+
rows, `audit:read`-gated (NIST 800-53 AU-7). (#623)
42+
43+
### Changed
44+
45+
- Host Management: the host card's scan link now opens the latest scan, Group
46+
and Filters work, and the list/grid view toggle is persisted **per user**
47+
server-side instead of per browser. (#611)
48+
- Scan detail: the header shows the host's hostname (falling back to its IP)
49+
instead of a raw host UUID. (#613)
50+
- Automated, schedule-driven events are now attributed to **"The system"**
51+
instead of the misleading "Someone", which implied a logged-in operator
52+
clicked a button. (#620)
53+
54+
### Security
55+
56+
- Hardened the audit CSV export against spreadsheet formula injection
57+
(CWE-1236): a cell beginning with `=`, `+`, `-`, `@`, tab, or CR is prefixed
58+
with a single quote so it renders as literal text. A truncated export (at the
59+
10000-row cap) now sets an `X-OpenWatch-Export-Truncated` header and logs a
60+
warning, so a capped export is never mistaken for the complete trail. (#625)
61+
- Fixed a cursor-pagination data-loss bug in the activity feed and audit list:
62+
the cursor encoded `occurred_at` alone, so rows sharing a boundary timestamp
63+
could be silently skipped on the next page (likely on the 5-leg UNION with
64+
batch inserts). Both now use a compound keyset cursor `(occurred_at, id)` with
65+
a row-value predicate. Bounded the attacker-controlled User-Agent and
66+
submitted-username strings recorded in audit detail (256-rune cap +
67+
control-char strip), neutralizing log forging. (#626)
68+
69+
---
70+
1571
## [0.2.0-rc.11] Eyrie — 2026-06-19
1672

1773
The bundled Kensa scan engine moves to v0.5.2, which corrects a class of false

packaging/version.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
#
33
# The Go binary's ldflags read this file via the Makefile; build scripts
44
# in packaging/{rpm,deb}/ source it for spec macros.
5-
VERSION="0.2.0-rc.11"
5+
VERSION="0.2.0-rc.12"
66
CODENAME="Eyrie"

0 commit comments

Comments
 (0)