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_syncaudit event type (ee/config/audit_events/types/user_blocked_by_ldap_sync.yml), distinct fromuser_blockedso it can be filtered specifically for LDAP-initiated blocks. - Adds a no-op
log_audit_event_for_block(user, reason)hook to CE'sblock_user, called afteruser.ldap_block. - Overrides the hook in
ee/lib/ee/gitlab/auth/ldap/access.rbto create the audit event viaGitlab::Audit::Auditor.audit, usingGitlab::Audit::UnauthenticatedAuthor(this is a system process with no authenticated user), matching the existing pattern already used forldap_group_sync_failedinee/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
bin/rspec ee/spec/lib/gitlab/auth/ldap/access_spec.rb spec/lib/gitlab/auth/ldap/access_spec.rb- All examples pass, including the new cases covering both blocking reasons, the licensing gate, and the read-only-instance no-op.