Add audit event when a user is blocked by LDAP sync

What does this MR do and why?

Closes #592315 (closed): when LDAP user sync determines a user should be blocked (because they no longer exist in LDAP or are disabled in Active Directory), no audit event was recorded. Admins had no way to see in the Audit Log when or why a user was blocked by LDAP sync, and no audit trail distinguished LDAP-initiated blocks from admin-initiated blocks.

block_user in lib/gitlab/auth/ldap/access.rb already calls user.ldap_block and logs to Gitlab::AppLogger, but never created an audit event — the existing user_blocked event type is only triggered via Users::BlockService, which the LDAP sync path bypasses entirely.

This MR:

  • Adds a new user_blocked_by_ldap_sync audit event type (ee/config/audit_events/types/user_blocked_by_ldap_sync.yml), distinct from user_blocked so it can be filtered specifically for LDAP-initiated blocks.
  • Adds a no-op log_audit_event_for_block(user, reason) hook to CE's block_user, called after user.ldap_block.
  • Overrides the hook in ee/lib/ee/gitlab/auth/ldap/access.rb to create the audit event via Gitlab::Audit::Auditor.audit, using Gitlab::Audit::UnauthenticatedAuthor (this is a system process with no authenticated user), matching the existing pattern already used for ldap_group_sync_failed in ee/lib/ee/gitlab/auth/ldap/sync/group.rb.
  • Guards on user.ldap_blocked? so no event is created when the block doesn't actually take effect (for example, on a read-only instance).

Disclosure

This merge request was prepared with the assistance of Claude Code (Anthropic), including root-cause analysis (which matched the issue's own detailed proposal), the implementation, and the test changes above. All changes have been reviewed and verified (81 examples across both the CE and EE Access specs, 0 failures, including a red→green check) prior to submission.

Screenshots or screen recordings

N/A — backend logic and audit event addition, no UI changes.

How to set up and validate locally

  1. bin/rspec ee/spec/lib/gitlab/auth/ldap/access_spec.rb spec/lib/gitlab/auth/ldap/access_spec.rb
  2. All examples pass, including the new cases covering both blocking reasons, the licensing gate, and the read-only-instance no-op.

Merge request reports

Loading
Loading