Skip to content

Audit-log LinOTP login success/failure (REST and RADIUS) - #462

Open
terryozaki-wq wants to merge 1 commit into
devfrom
feature/linotp-audit-logging
Open

terryozaki-wq wants to merge 1 commit into
devfrom
feature/linotp-audit-logging

Conversation

@terryozaki-wq

Copy link
Copy Markdown

Summary

  • UserResource.loginLinOTP had no security-audit-trail instrumentation at all, unlike loginNative/loginLDAP
  • Adds the same UserAuditTrailUtils.recordLoginFailed calls those methods already make, at every genuine failure outcome: the "LinOTP login is not allowed" gate, a non-200 response (invalid credentials/OTP, RADIUS/LinOTP server unreachable, misconfiguration), and an unexpected exception
  • A plain operational log line is added on success for visibility; the successful login's audit entry is not added explicitly, since addAccessToken -> userTrackingLogin already calls UserAuditTrailUtils.recordLogin for every provider, LinOTP included (confirmed by reading that path, not assumed - avoids double-logging)
  • The intermediate "please enter your OTP" challenge-response step (a 200 response with no token yet) is deliberately not written to the audit trail - it's neither a success nor a failure, only the eventual accept/reject outcome is
  • Neither the submitted pin/password/OTP, nor a RADIUS shared secret, is ever written to any log

Companion PR

This pairs with SEMOSS/Semoss#3192, which adds a RADIUS authentication mode to LinOTPUtil. This change covers both auth modes identically, since both return through the same LinOTPResponse - it is not RADIUS-specific itself.

Test plan

  • mvn compile succeeds against a dev-built SEMOSS jar
  • No dedicated unit tests exist for UserResource in this repo; manual/integration verification of the audit trail rows is still worth doing before relying on this in production

🤖 Generated with Claude Code

UserResource.loginLinOTP had no security-audit-trail instrumentation
at all, unlike loginNative/loginLDAP. Adds the same
UserAuditTrailUtils.recordLoginFailed calls loginNative/loginLDAP
make, at every genuine failure outcome: the "LinOTP login is not
allowed" gate, a non-200 response (invalid credentials/OTP,
RADIUS/LinOTP server unreachable, misconfiguration), and an unexpected
exception.

The successful login's audit entry is not added explicitly -
addAccessToken -> userTrackingLogin already calls
UserAuditTrailUtils.recordLogin for every provider, LinOTP included,
confirmed by reading that path rather than assumed, to avoid double
logging. A plain operational log line is still added on success for
visibility.

The intermediate "please enter your OTP" challenge-response step (a
200 response with no token yet) is deliberately NOT written to the
audit trail - it is neither a success nor a failure, only the eventual
accept/reject outcome is. Neither the submitted pin/password/OTP, nor
a RADIUS shared secret, is ever written to any log.

Companion to the new RADIUS auth mode added to LinOTPUtil in
SEMOSS/Semoss PR #3192 - this covers both auth modes identically since
both return through the same LinOTPResponse.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@terryozaki-wq
terryozaki-wq requested a review from a team as a code owner October 25, 2026 04:08
@snyk-io

snyk-io Bot commented Oct 25, 2026

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

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.

1 participant