Audit logging: append-only per-object access log #61

Closed
opened 2026-07-29 23:19:35 +00:00 by Cordy · 0 comments
Owner

Derived from the public-sector analysis (#59, docs/PUBLIC-SECTOR.md). For police/legal records deployments, per-object access logs are routinely a procurement requirement — a system that cannot answer "who accessed this case file, when, from where" is disqualified before price is discussed. This is the most important public-sector feature Cairn lacks.

What exists today is not this. Operational request logs go to stdout: not per-object, not append-only, not retained by policy, not queryable by a non-engineer.

Design sketch (fits the no-database thesis — this is the one place a log file IS the answer):

  • Append-only JSONL on the data volume (e.g. /data/.cairn/audit/YYYY-MM.jsonl): {time, user, action, path, share_token?, remote, result}. Actions: read, write, delete, restore, share-create, share-access, share-revoke, login, admin-op.
  • Hooked at the storage decorator + share handler + auth chokepoints so web, REST, WebDAV, and TUS are covered by one implementation.
  • Rotation monthly; retention config (audit.retainMonths); files are never modified after rotation.
  • Admin surface: GET /api/v1/admin/audit?path=&user=&from=&to= (bounded scan of the JSONL files) + raw file export for the auditor's own tooling.
  • Config audit.enabled (default off), audit.path, audit.retainMonths. Explicitly out of scope: tamper-proof signing/anchoring (can layer later), SIEM push (files are greppable/shippable as-is).

Acceptance: with audit on, a WebDAV read, a web-UI delete, and a share-link download each produce one line; the admin query returns them filtered by path; rotation produces a new file at month boundary; disabled = zero overhead.

Derived from the public-sector analysis (#59, docs/PUBLIC-SECTOR.md). For police/legal records deployments, per-object access logs are routinely a procurement **requirement** — a system that cannot answer "who accessed this case file, when, from where" is disqualified before price is discussed. This is the most important public-sector feature Cairn lacks. **What exists today is not this.** Operational request logs go to stdout: not per-object, not append-only, not retained by policy, not queryable by a non-engineer. **Design sketch (fits the no-database thesis — this is the one place a log file IS the answer):** - Append-only JSONL on the data volume (e.g. `/data/.cairn/audit/YYYY-MM.jsonl`): `{time, user, action, path, share_token?, remote, result}`. Actions: read, write, delete, restore, share-create, share-access, share-revoke, login, admin-op. - Hooked at the storage decorator + share handler + auth chokepoints so web, REST, WebDAV, and TUS are covered by one implementation. - Rotation monthly; retention config (`audit.retainMonths`); files are never modified after rotation. - Admin surface: `GET /api/v1/admin/audit?path=&user=&from=&to=` (bounded scan of the JSONL files) + raw file export for the auditor's own tooling. - Config `audit.enabled` (default off), `audit.path`, `audit.retainMonths`. Explicitly out of scope: tamper-proof signing/anchoring (can layer later), SIEM push (files are greppable/shippable as-is). **Acceptance:** with audit on, a WebDAV read, a web-UI delete, and a share-link download each produce one line; the admin query returns them filtered by path; rotation produces a new file at month boundary; disabled = zero overhead.
Cordy closed this issue 2026-07-30 01:35:35 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#61
No description provided.