← All config-management frames
Flow 3 · Secrets & audit · Frame (i) · /admin/config/keys/:key/history

Change history — who turned this off

Append-only. Every set, unset, lock and unlock with its actor, scope, reason and time. Revert is not a delete — it replays an earlier value as a new change, so the revert is itself in the history.

notifications.digest.frequency org Acme Corp · 5 entries

History

newest first
WhenOperationValueActor & reason
2026-08-09 14:22 set weekly → daily a.riveraorg Acme Corp · "reverting the EU rollout, too slow for support"
2026-08-02 09:05 set revert of #2 hourly → weekly j.okafororg Acme Corp · "restoring the value from 2026-07-02"
2026-07-28 16:40 lock hourly 🔒 platform-opsportal Acme Portal · "pinned during the incident window"
2026-07-19 11:12 unset override removed — resolved from portal Acme Portal (weekly) a.riveraorg Acme Corp · "tracking the portal default again"
2026-07-02 08:31 set — → weekly j.okafororg Acme Corp · "aligning with EU digest policy"
A · Revert confirmation — states what will actually happen

The dialog shows the current value, the target value, and that a new entry will be written. It carries a reason field, because an unexplained revert is the change people most want explained later.

B · A secret key's history — redacted, both sides

The trail records that it changed, never what it was — an audit log holding secret values is a secret store with worse access control. Neither the old nor the new value appears, and "Revert to this" is absent, not disabled: there is no stored plaintext to revert to. Reveals are themselves audited entries.

notifications.provider.apiKey

secret
WhenOperationValueActor & reason
2026-08-10 10:04 reveal [redacted — value not stored in the audit trail] a.riveraportal Acme Portal · "rotating provider credentials"
2026-07-14 13:50 set [redacted] → [redacted] j.okaforportal Acme Portal · "quarterly rotation"
2026-05-02 09:00 set — → [redacted] j.okaforportal Acme Portal · "initial provisioning"
C · Never changed here

Not an error and not a gap in the record — the key has simply never been written at this scope. It names where the value does come from, so the reader knows where to look next.

No changes recorded at this scope

notifications.retry.maxAttempts has never been set, unset or locked at org Acme Corp. Its value comes from the definition default (5).

View the resolution chain
D · Loading
WhenOperationValueActor & reason
E · Load failed, and F · not permitted

Kept apart deliberately: E is retryable and says the record is intact; F is a decision and offers no retry. A compliance reviewer must never read "history unavailable" and wonder whether the trail was lost.

Anticipated contract (FF-EPIC-18-S2 / S3). Append-only config_value_history written in the same transaction as the value change, so a change can never exist without its audit row. The read and revert surfaces are not in the frozen services/config-service/openapi.yaml today — these frames commission them, and revert is modelled as a replayed set/unset through PUT /v1/config, never as a delete.
Every actor and scope is a typed reference — a history row names scopeType + scopeId, never a bare id (identifier-standard).

← Secret values Back to the index →
Review · config-management approve or reject each flow ↓
settings-editorapproved · izzywdev
key-catalogapproved · izzywdev
secret-auditapproved · izzywdev