Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions packages/plugins/plugin-audit/src/audit-log-read-visibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,19 @@
* `config_change` row stored before its writer recorded the settings row,
* an auth event that carried no session id, and an `action_invocation` row
* of an action invoked with no subject record.
* There is no record to judge, and none carries a record's field values
* (the per-writer measurement in `audit-log-field-redaction.ts`), so they
* are OUTSIDE this gate's class and are served under the ledger's own grant
* There is no record to judge, so they are OUTSIDE this gate's class and
* are served under the ledger's own grant
* exactly as before — through a predicate on the ledger's own columns
* ({@link ledgerRowAboutNoRecordWhere}), so a broad read is served whole. This is where the ledger differs from the activity
* stream, which excludes every row naming no parent: the stream has no
* platform producer of such rows, while these have three, and the shipped
* `config_changes` list view reads `import` rows (and the older
* `config_change` rows) through the data door.
* The field-level redaction does not key on `record_id`: a `config_change`
* row naming a settings store as `object_name` carries that setting's
* `value` (readable for a non-secret key) and `digest`, and both are
* dropped for a reader whose field-level security masks the store's
* `value` (`audit-log-field-redaction.ts`), with or without a `record_id`.
* - **A record action that names no record** — a `create` / `read` / `update`
* / `delete` row with no `record_id` (the CRUD mirror stamps `null` when it
* cannot derive the id): about a record the gate cannot name, so excluded
Expand Down
6 changes: 4 additions & 2 deletions packages/plugins/plugin-audit/src/audit-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,10 @@ export class AuditPlugin implements Plugin {
namespace: 'sys',
objects: [SysAuditLog, SysActivity, SysComment, SysCommentReaction],
// The ledger row's record page: its fields, and every ledger row about
// the same record beside it, so a `config_change` row's digest sits next
// to the mirror's row that carries the value (`sys-audit-log.page.ts`).
// the same record beside it, so a `config_change` row sits next to the
// mirror's rows about the same settings row (`sys-audit-log.page.ts`).
// A non-secret key's `config_change` row carries its readable before
// and after itself; a secret-valued key's carries only the digest.
pages: [SysAuditLogDetailPage],
// ADR-0029 D7 — contribute the one Audit Log entry into the Setup app's
// `group_diagnostics` slot. The plugin owns sys_audit_log (K2), so the
Expand Down
19 changes: 10 additions & 9 deletions packages/plugins/plugin-audit/src/sys-audit-log.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import type { Page } from '@objectstack/spec/ui';
*
* ## Why the page exists: the other rows about the same record
*
* A settings write records a `config_change` row whose `new_value` is a
* DIGEST, never the value (`service-settings`' `config-change-audit.ts`), so
* the row alone cannot answer "what was it changed to". The CRUD mirror
* A settings write records a `config_change` row whose `old_value` and
* `new_value` carry the setting's readable before and after for a key that
* is not secret-valued, and only its digest for a secret-valued key
* (`service-settings`' `config-change-audit.ts`). The CRUD mirror
* (`audit-writers.ts`) writes its own row about the same write, on the stored
* settings row, and that row carries the change: a non-secret value's old and
* new state, a secret's only as the mirror's ledger view masks it. Both rows
* name the same settings row as `record_id` (the `config_change` writer
* records the id of the row the write landed on), so this page lists every
* ledger row whose `record_id` is this row's: the `config_change` row and the
* mirror's rows sit side by side, and the value is one row down.
* settings row: a non-secret value's old and new state, a secret's only as
* the mirror's ledger view masks it. Both rows name the same settings row as
* `record_id` (the `config_change` writer records the id of the row the write
* landed on), so this page lists every ledger row whose `record_id` is this
* row's: the `config_change` row and the mirror's rows sit side by side, the
* history of that settings row in one list.
*
* The list is the ledger itself, keyed on the pointer's id half on both sides
* (`relationshipField` and `relationshipValueField` both `record_id`): the
Expand Down
Loading