Audit Log
Buoy keeps a local, append-only record of every cluster mutation it issues. The audit log makes it possible to answer “what changed, when, who did it, and what did the object look like before?” without leaving the app.
What Is Logged
Every write Buoy performs against a cluster gets one audit row:
- Single-object actions: delete, scale, restart rollout, evict, cordon, uncordon, drain, edit labels, edit annotations, edit YAML.
- Bulk actions: one row per affected object (the bulk action runs serially client-side, so each row is logged independently).
- YAML apply (
Applybutton on the YAML editor, or the multi-doc apply flow): one row per document. - Argo Workflows: stop, terminate, retry, resume, submit.
- Argo Rollouts: pause, resume, restart, promote, promote-full, abort, retry.
- ArgoCD: sync, refresh, hard-refresh, terminate sync, ApplicationSet refresh.
- Helm: rollback, uninstall.
Read-only operations (watches, GETs, log streams, exec sessions, port-forwards) are not logged.
What Each Row Captures
| Field | Meaning |
|---|---|
| Time | When the mutation ran (millisecond precision). |
| Context | Kubeconfig context — which cluster the mutation hit. |
| Object | API group, version, kind, namespace, name. |
| Operation | The verb (e.g. scale, argocdSync, helmRollback). |
| Command | The originating Tauri command, for traceability. |
| Impersonation | The as: <user> identity when /as was active, plus groups and uid. |
| Params | Mutation arguments (replicas, restartAt, patch payload, sync options, etc.). |
| Before | Full object JSON immediately before the mutation. |
| After | Full object JSON returned by the patch (or null for delete / evict). |
| Status | OK, Error, or Partial. Drain and Helm rollback report Partial when some children failed. |
| Error | Stringified error from the apiserver when the mutation failed. |
| Duration | Wall-clock milliseconds spent in the kube call. |
| Parent | For drain, each child eviction’s parentId points back at the drain’s audit row. |
Where The Data Lives
A single SQLite file, audit.db, sits next to prefs.json in the app config dir:
- macOS:
~/Library/Application Support/com.buoy.app/audit.db - Linux:
~/.config/buoy/audit.db - Windows:
%APPDATA%\buoy\audit.db
The database is local-only. Buoy never uploads it anywhere.
Secret Redaction
The audit log lives in plaintext on disk, so for objects of kind Secret the data and stringData field values are replaced with the literal string <redacted> before persistence. Keys and everything else (metadata, type, etc.) are stored verbatim — you can still see which secret keys were touched, just not their decoded contents.
If you need true secret history, integrate with an external audit log; Buoy’s local DB intentionally won’t store decryptable credentials.
Retention
The DB is bounded by three caps applied on every insert:
- 100 000 row soft cap — the oldest rows are dropped first.
- 1 GB total byte cap (sum of stored before/after blob sizes) — same FIFO eviction.
- 256 KB per blob cap — any single before/after snapshot larger than this is replaced with a
{"_truncated": true, "bytes": N}marker so a single ConfigMap with a giant embedded payload can’t blow past a reasonable per-row footprint.
These bounds are not configurable today. Clear the log manually via the Clear All button in the /audit view if you want a clean slate.
How To View
/auditin the command bar opens the unfiltered log.- From any detail page’s Actions ▾ menu, choose View Audit History to open the log filtered to that object (context + kind + namespace + name).
- The filter chips on the audit view let you narrow by context, kind, operation, status, or a free-text search over name / error / impersonation user.
- Click a row to expand it. The expanded panel has four tabs:
- Diff — unified YAML diff between before and after.
- Before — full pre-mutation object YAML.
- After — full post-mutation object YAML.
- Params — the mutation arguments (replicas, patch payload, drain options, etc.).
How To Clear
The audit view has a Clear All button that wipes the entire log after a confirmation. There is no UI for selective deletion today — the retention caps will eventually evict old rows on their own.
To clear from outside the app, quit Buoy and delete the audit.db file. On the next launch Buoy will create a fresh empty database.
Command Bar History
The command bar’s submission history is stored in the same database (a separate command_history table). The first launch after upgrading migrates the prior history from prefs.json into SQLite, then clears the field in the JSON so the two stores don’t drift. The frontend’s behavior is unchanged — up-arrow walks history exactly as before.
What Audit Does Not Cover
- Mutations issued outside Buoy (kubectl, other clients, controllers) — Buoy only knows about its own writes.
- Apiserver-side audit — your cluster’s apiserver audit configuration is the source of truth for all writes, regardless of client. Use that for compliance.
- Secret payloads — see “Secret Redaction” above.
- Watches / reads — only mutations are logged.