Data handling & retention¶
What the Dashboard's local store holds, how long it keeps it, what's exposed in a backup, and the limits on deletion. The short version: the store holds operator-attributed activity and presentation state — never platform secrets — and two tables (audit log and launch history) currently grow without automatic pruning.
What the store holds¶
Everything is in the dashboard state store (SQLite by default, or Postgres). Grouped by sensitivity:
| Data | Contains | Operator-identifying? | Free-text / sensitive? |
|---|---|---|---|
| Sessions | opaque id → operator identity · role · timestamps | yes (identity) | no |
| Audit log | operator · action · environment · target · outcome · timestamp | yes | no (structured fields) |
| Launch history | spec_path · label · content-digest · env · run_id · created_by (reference-only — no inline spec since 0.4.0) |
yes (created_by) |
label is free text |
| Annotations / tags | run_id → note body + tags + created_by |
yes (created_by) |
body is free operator text |
| Saved filters | named RunFilters blobs + created_by |
yes | no |
| Config › Connections | env → kneo-client profile ref + free-text label |
no | label is free text |
| Config › Access | role → capability map + per-role env grants | no | no |
| Config › Pricing | blended per-1,000-token rate | no | no |
| Config › Preferences | keyed by the operator's identity → an opaque preferences blob + created_by |
yes (identity) | opaque JSON blob |
Not in the store — by design:
- Platform API keys live in the
kneo-clientprofile store, never here (Connections stores only a profile reference). - OIDC client secret + session signing key live in BFF config / env, never the store.
- Credential inventory surfaces references + presence metadata only — secret values are never read into the BFF or the browser.
- Run inputs/outputs / traces are the platform's data (kneo-serv), fetched live and not persisted by the Dashboard.
Retention¶
| Data | Retention today |
|---|---|
| Sessions | auto-purged — a background loop removes expired rows (KNEO_DASH_SESSION_PURGE_INTERVAL_SECONDS), plus absolute + idle expiry; logout deletes immediately |
| Audit log | append-only; no automatic prune by design — retention is the operator-safe kneo-dash prune CLI (0.8.0): export-before-delete + a self-audit record |
| Launch history | the UI shows the recent ~20 (an MRU read cap); old rows persist until an operator runs kneo-dash prune (0.8.0) |
| Annotations · saved filters · config | kept until an operator edits/deletes them (ordinary CRUD) |
Metering + retention pruning (0.8.0)
Audit-log and launch-history rows accumulate on disk (append-only by design). Since
0.8.0, bound them with the operator-safe kneo-dash prune
CLI — export-before-delete (versioned + checksummed) with a self-audit record — and
watch growth via kneo_dash_store_state_bytes plus the row-count gauges
kneo_dash_store_rows{table="audit_log"|"launches"}
(deployment › state-store growth).
The audit log is best-effort, not compliance-grade¶
The local audit log is best-effort: an append that fails is counted and swallowed, and
the action still completes — so the log can have gaps under store pressure and is not a
lossless/compliance-grade record. It exists for per-operator attribution (kneo-serv only
sees the shared service account), not as a legal audit of record. Exact coverage + the failure
signal (kneo_dash_audit_write_failures_total) are the normative audit
contract
(ADR-012). Alert on the failure counter if attribution completeness matters to you.
Backups & deletion¶
- A backup captures the whole store — operator identities, annotation text, and the audit trail included (but no secrets — those aren't in it). Protect backups accordingly; see Backup & recovery.
- Deletion limits. Annotations and saved filters are deletable through the app (ordinary CRUD). Among config, only Connections has an in-app delete; Access, Pricing, and Preferences are edit/overwrite-only (no delete route) — you change their values, you don't remove the row. The audit log is append-only — there is no in-app delete path for audit rows (deliberate, for attribution integrity); launch history likewise has no in-app delete. Purging either today is a direct DB operation against the store.
- Right-to-erasure / operator offboarding that must remove an identity's audit/launch rows is a manual DB task today (no app affordance) — plan for it if your compliance regime requires it.
Related¶
- State store — design — the full schema + the normative audit contract.
- Security hardening — auth, sessions, and the capability model.
- Backup & recovery — backing up + restoring the store.
- Deployment — sizing the state volume.