diff --git a/acton-service/src/audit/event.rs b/acton-service/src/audit/event.rs index 577f7b4..efb8674 100644 --- a/acton-service/src/audit/event.rs +++ b/acton-service/src/audit/event.rs @@ -101,7 +101,17 @@ pub enum AuditEventKind { /// Successful authentication AuthLoginSuccess, /// Failed authentication attempt + /// + /// Reserved for credential-submission failures from application login + /// handlers (e.g. `/auth/login`). The auth middleware no longer emits + /// this kind for missing or invalid bearer tokens on protected routes — + /// see [`Self::AuthTokenMissing`] and [`Self::AuthTokenInvalid`]. AuthLoginFailed, + /// Protected route reached without a bearer token, or with one that was + /// malformed at extraction time + AuthTokenMissing, + /// Bearer token failed validation (bad signature, expired, malformed claims) + AuthTokenInvalid, /// User logout AuthLogout, /// Token refresh @@ -171,6 +181,8 @@ impl std::fmt::Display for AuditEventKind { match self { Self::AuthLoginSuccess => write!(f, "auth.login.success"), Self::AuthLoginFailed => write!(f, "auth.login.failed"), + Self::AuthTokenMissing => write!(f, "auth.token.missing"), + Self::AuthTokenInvalid => write!(f, "auth.token.invalid"), Self::AuthLogout => write!(f, "auth.logout"), Self::AuthTokenRefresh => write!(f, "auth.token.refresh"), Self::AuthTokenRevoked => write!(f, "auth.token.revoked"), diff --git a/acton-service/src/audit/storage/clickhouse_impl.rs b/acton-service/src/audit/storage/clickhouse_impl.rs index accc1b7..8cb1bfd 100644 --- a/acton-service/src/audit/storage/clickhouse_impl.rs +++ b/acton-service/src/audit/storage/clickhouse_impl.rs @@ -139,6 +139,8 @@ impl From for AuditEvent { let kind = match row.kind.as_str() { "auth.login.success" => AuditEventKind::AuthLoginSuccess, "auth.login.failed" => AuditEventKind::AuthLoginFailed, + "auth.token.missing" => AuditEventKind::AuthTokenMissing, + "auth.token.invalid" => AuditEventKind::AuthTokenInvalid, "auth.logout" => AuditEventKind::AuthLogout, "auth.token.refresh" => AuditEventKind::AuthTokenRefresh, "auth.token.revoked" => AuditEventKind::AuthTokenRevoked, diff --git a/acton-service/src/audit/storage/pg.rs b/acton-service/src/audit/storage/pg.rs index 526d0bf..0528c91 100644 --- a/acton-service/src/audit/storage/pg.rs +++ b/acton-service/src/audit/storage/pg.rs @@ -268,6 +268,8 @@ impl From for AuditEvent { let kind = match row.kind.as_str() { "auth.login.success" => AuditEventKind::AuthLoginSuccess, "auth.login.failed" => AuditEventKind::AuthLoginFailed, + "auth.token.missing" => AuditEventKind::AuthTokenMissing, + "auth.token.invalid" => AuditEventKind::AuthTokenInvalid, "auth.logout" => AuditEventKind::AuthLogout, "auth.token.refresh" => AuditEventKind::AuthTokenRefresh, "auth.token.revoked" => AuditEventKind::AuthTokenRevoked, diff --git a/acton-service/src/audit/storage/surrealdb_impl.rs b/acton-service/src/audit/storage/surrealdb_impl.rs index b2b93b5..b91974b 100644 --- a/acton-service/src/audit/storage/surrealdb_impl.rs +++ b/acton-service/src/audit/storage/surrealdb_impl.rs @@ -369,6 +369,8 @@ fn parse_event_kind(s: &str) -> AuditEventKind { match s { "auth.login.success" => AuditEventKind::AuthLoginSuccess, "auth.login.failed" => AuditEventKind::AuthLoginFailed, + "auth.token.missing" => AuditEventKind::AuthTokenMissing, + "auth.token.invalid" => AuditEventKind::AuthTokenInvalid, "auth.logout" => AuditEventKind::AuthLogout, "auth.token.refresh" => AuditEventKind::AuthTokenRefresh, "auth.token.revoked" => AuditEventKind::AuthTokenRevoked, diff --git a/acton-service/src/audit/storage/turso.rs b/acton-service/src/audit/storage/turso.rs index 825880b..53d9729 100644 --- a/acton-service/src/audit/storage/turso.rs +++ b/acton-service/src/audit/storage/turso.rs @@ -361,6 +361,8 @@ fn parse_event_kind(s: &str) -> AuditEventKind { match s { "auth.login.success" => AuditEventKind::AuthLoginSuccess, "auth.login.failed" => AuditEventKind::AuthLoginFailed, + "auth.token.missing" => AuditEventKind::AuthTokenMissing, + "auth.token.invalid" => AuditEventKind::AuthTokenInvalid, "auth.logout" => AuditEventKind::AuthLogout, "auth.token.refresh" => AuditEventKind::AuthTokenRefresh, "auth.token.revoked" => AuditEventKind::AuthTokenRevoked, diff --git a/acton-service/src/middleware/jwt.rs b/acton-service/src/middleware/jwt.rs index 9fb3b70..ca60c4c 100644 --- a/acton-service/src/middleware/jwt.rs +++ b/acton-service/src/middleware/jwt.rs @@ -202,8 +202,8 @@ impl JwtAuth { if logger.config().audit_auth_events { logger .log_auth( - crate::audit::event::AuditEventKind::AuthLoginFailed, - crate::audit::event::AuditSeverity::Warning, + crate::audit::event::AuditEventKind::AuthTokenMissing, + crate::audit::event::AuditSeverity::Informational, audit_source, ) .await; @@ -222,7 +222,7 @@ impl JwtAuth { if logger.config().audit_auth_events { logger .log_auth( - crate::audit::event::AuditEventKind::AuthLoginFailed, + crate::audit::event::AuditEventKind::AuthTokenInvalid, crate::audit::event::AuditSeverity::Warning, audit_source, ) diff --git a/acton-service/src/middleware/paseto.rs b/acton-service/src/middleware/paseto.rs index 6498a9b..838b0c2 100644 --- a/acton-service/src/middleware/paseto.rs +++ b/acton-service/src/middleware/paseto.rs @@ -215,8 +215,8 @@ impl PasetoAuth { if logger.config().audit_auth_events { logger .log_auth( - crate::audit::event::AuditEventKind::AuthLoginFailed, - crate::audit::event::AuditSeverity::Warning, + crate::audit::event::AuditEventKind::AuthTokenMissing, + crate::audit::event::AuditSeverity::Informational, audit_source, ) .await; @@ -235,7 +235,7 @@ impl PasetoAuth { if logger.config().audit_auth_events { logger .log_auth( - crate::audit::event::AuditEventKind::AuthLoginFailed, + crate::audit::event::AuditEventKind::AuthTokenInvalid, crate::audit::event::AuditSeverity::Warning, audit_source, )