Skip to content

fix(audit): parse config.*, account.*, and lockout event strings back to typed variants#21

Merged
rrrodzilla merged 1 commit into
mainfrom
fix/audit-storage-parser-coverage
May 28, 2026
Merged

fix(audit): parse config.*, account.*, and lockout event strings back to typed variants#21
rrrodzilla merged 1 commit into
mainfrom
fix/audit-storage-parser-coverage

Conversation

@rrrodzilla

Copy link
Copy Markdown
Contributor

Summary

All four audit storage backends (pg, clickhouse, turso, surrealdb) reconstruct AuditEventKind from a stored string via a match. Three whole event families that the framework actively emits had no parser arms and silently round-tripped as AuditEventKind::Custom(...):

  • config.loaded / config.drift_detected — emitted by audit/config_audit.rs (NIST CM-3)
  • All account.* (created/disabled/enabled/locked/unlocked/expired/deleted/updated) — emitted by accounts/mod.rs under the accounts feature
  • auth.account.locked / auth.account.unlocked — emitted by lockout/mod.rs under the login-lockout feature

Adds the missing arms in each backend, gated to match the variant cfgs in audit/event.rs. Extends the existing ClickHouse roundtrip coverage test to assert the new arms under their respective feature flags — that test fails by-design if any arm regresses to the Custom catch-all (string would render as custom.config.loaded instead of config.loaded).

Closes #15.

Why

Rust consumers pattern-matching on AuditEventKind were silently seeing Custom("account.locked") instead of AccountLocked. SIEM queries keyed on the stored string still worked; the bug was at the typed-deserialization boundary. This is the same shape as #14's bug but spread across three more event families that PR didn't touch.

Out of scope

Test plan

  • cargo clippy -p acton-service --all-targets --features full -- -D warnings — clean
  • cargo clippy -p acton-service --all-targets --no-default-features --features "full,crypto-ring" -- -D warnings — clean
  • cargo nextest run -p acton-service --features full — 520/520 pass (extended roundtrip test exercises the new arms)

… to typed variants

All four storage backends (pg, clickhouse, turso, surrealdb) reconstruct
AuditEventKind from a stored string via a match expression. Three whole
event families that the framework actively emits had no parser arms and
silently round-tripped as AuditEventKind::Custom on query:

- config.loaded / config.drift_detected (audit/config_audit.rs — NIST CM-3)
- account.* (accounts/mod.rs, gated on the `accounts` feature)
- auth.account.locked / auth.account.unlocked
  (lockout/mod.rs, gated on the `login-lockout` feature)

Add the missing arms to each backend, gated to match the variant cfgs
in audit/event.rs. Extend the existing ClickHouse roundtrip coverage
test to assert the new arms under their respective feature flags.

Closes #15
@rrrodzilla rrrodzilla merged commit b1848aa into main May 28, 2026
2 checks passed
rrrodzilla added a commit that referenced this pull request May 28, 2026
Reflects the audit-event work that landed in #14, #21, #22 and is
queued in #23, #25:

- audit/page.md: rewrite the "Auth Events (Automatic)" table to match
  the new emission set (AuthLoginSuccess at Notice; AuthTokenMissing /
  AuthTokenInvalid added; AuthTokenRevoked notes jti metadata;
  AuthPermissionDenied and HttpRequestDenied added); update the
  syslog and OTLP example severities to Notice; expand the "Event
  Kinds" reference table; add a migration callout for AuthLoginFailed.
- cedar-auth/page.md: add "Audit Integration" section describing
  automatic AuthPermissionDenied emission on Decision::Deny.
- rate-limiting/page.md: add "Audit Integration" section describing
  automatic HttpRequestDenied emission on RateLimitExceeded.
- token-auth/page.md: add "Audit Emission" section covering the four
  middleware-emitted kinds, the jti correlation field, and the
  AuthLoginFailed migration.

Refs #13 #15 #16 #18 #19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit: storage parsers silently downgrade config.*, account.*, and lockout events to Custom

1 participant