Skip to content

Security & OWASP

Authentication logging is the control that turns a silent account takeover into an incident somebody can see — and, when the user is notified, into one they can stop themselves.

Why it matters

Stolen credentials rarely announce themselves. The attacker knows the password, so authentication succeeds: nothing fails, nothing errors, nothing appears in your logs. What changes is the context — a different IP address, country or browser. Recording it is the only way to see it.

OWASP lists the absence of this control in its Top 10. A09:2021 – Security Logging and Monitoring Failures opens on it:

Auditable events, such as logins, failed logins, and high-value transactions, are not logged.

and A07:2021 – Identification and Authentication Failures adds the alerting side: alert administrators when credential stuffing, brute force, or other attacks are detected.

How this bundle helps

OWASP concernWhat the bundle does
Auditable events are not loggedPersists every successful login — identity, IP address, user agent, timestamp and location
No real-time detectionCompares each login against known contexts and reacts on the spot, synchronously or via Messenger
No alertingNotifies the account owner by email, or through any transport you plug in
Nobody reviews the logsPuts the decision in the user's hands with signed "It was me / It wasn't me" links

The last row matters most in practice. Security teams rarely have the capacity to review authentication logs; the account owner knows instantly whether they just signed in from Lyon on a Mac. Login confirmation turns them into the reviewer.

Design decisions

  • Signed, single-use, expiring links. Replaying a used link shows an "already handled" page instead of acting twice.
  • No action from a link preview. Clicking opens an intermediate page whose button issues a POST, so email scanners that follow every URL cannot answer on the user's behalf.
  • Identity, not just an identifier. Logs record the user class alongside the identifier, so two accounts of different classes are never conflated.
  • No outbound call by default. Geolocation is off unless you configure a provider, and the recommended one (geoip2) resolves the IP against a local database. The ipApi provider is the exception — it sends the user's IP to a third party in clear text and trusts the reply, so it is documented as development-only.
  • Sensible defaults, no surprises. Disavowal revokes the user's known contexts; invalidating sessions or forcing a password reset stays opt-in.

What this bundle is not

It is an audit-log and alerting component, not a complete authentication defence. It provides no MFA, no rate limiting or lockout, no credential-stuffing detection, no bot protection — all of which A07 also calls for. Symfony's login throttling and MFA belong alongside it, not after it.

It also records successful logins only: failures never reach LoginSuccessEvent.

Built and maintained by Spiriit — released under the MIT License.