Skip to content

fix(audit): stop emitting auth.login.failed for unauthenticated requests#14

Merged
rrrodzilla merged 1 commit into
mainfrom
fix/audit-token-events
May 28, 2026
Merged

fix(audit): stop emitting auth.login.failed for unauthenticated requests#14
rrrodzilla merged 1 commit into
mainfrom
fix/audit-token-events

Conversation

@rrrodzilla

Copy link
Copy Markdown
Contributor

Summary

  • Adds AuthTokenMissing (Informational) and AuthTokenInvalid (Warning) variants to AuditEventKind.
  • Repoints the four middleware emission sites in paseto.rs and jwt.rs to use them instead of AuthLoginFailed.
  • Reserves AuthLoginFailed for application credential-submission failures (e.g. /auth/login handlers); doc comment updated.
  • Teaches the Postgres, ClickHouse, Turso, and SurrealDB storage backends to round-trip the new event-kind strings.

Closes #13.

Why

The middleware fired auth.login.failed for every request that arrived without a valid bearer token — including unauthenticated health checks. A downstream report showed ~5,758 false-positive auth.login.failed events per day from ALB health checks (vs. 4 real logins), drowning out real signal for SIEM rules and security monitoring.

The new variants let operators filter health-check-shaped noise (auth.token.missing) separately from credential failures (auth.login.failed) and presented-but-bad tokens (auth.token.invalid).

Breaking change

Removes auth.login.failed from the middleware's emission set. Downstream SIEM rules keyed on auth.login.failed from acton-service alone will go quiet for the unauthenticated-request case (the goal). App-level login handlers continue to emit it correctly. Worth a minor-version bump (0.27.0) given the observable behavior change.

Out of scope

  • Reordering middleware so AuditSource is populated before auth runs (so ip/request_id are no longer blank in token-failure events). Bigger refactor; deferred — see issue auth middleware emits auth.login.failed on every unauthenticated request #13 item (3).
  • A config knob like audit_token_failures: bool to silence token-missing entirely. Easy follow-up if the new Informational level isn't filtered enough.

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
  • Downstream verify in schemaforge (Govcraft/schemaforge-dev#66) after bump

The PASETO and JWT middleware emitted AuditEventKind::AuthLoginFailed
whenever a request reached a protected route without a valid token,
conflating real credential-submission failures with routine
unauthenticated probes (health checks, scanners, etc.). Downstream
operators behind ALB health checks reported thousands of false-positive
auth.login.failed events per day, drowning out real signal.

Introduce two new variants — AuthTokenMissing (Informational) and
AuthTokenInvalid (Warning) — and repoint the four middleware emission
sites to use them. AuthLoginFailed is now reserved for application
credential-submission failures (e.g. /auth/login handlers), as
documented in its doc comment.

Storage backends (Postgres, ClickHouse, Turso, SurrealDB) gain
round-trip parsing for the new event-kind strings.

Closes #13
@rrrodzilla rrrodzilla merged commit b038842 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.

auth middleware emits auth.login.failed on every unauthenticated request

1 participant