Advanced search: work items of banned authors stay visible because nothing reindexes them on ban
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Parent epic: &23557
Context
GitLab hides issues authored by banned users. The two backends implement this differently, and only one of them stays correct after the ban.
Postgres uses a live anti-join. app/finders/issuable_finder.rb line 259, init_collection, selects klass.without_hidden for users who cannot see all issuables. That scope is defined at app/models/issue.rb lines 265 to 269 as a where_not_exists against Users::BannedUser correlated on the author id. It is evaluated on every query, so banning a user hides their issues on the next page load.
Elasticsearch reads a snapshot. hidden is a boolean in the mapping (ee/lib/search/elastic/types/work_item.rb line 48), written at index time from target.hidden? in build_extra_data (ee/lib/search/elastic/references/work_item.rb line 170), and filtered by Search::Elastic::Filters.by_not_hidden (ee/lib/search/elastic/filters.rb lines 695 to 704), which is registered for work items at ee/lib/search/elastic/work_item_query_builder.rb line 19.
The gap
Nothing reindexes a user's work items when that user is banned.
Documents are only reindexed when the record itself is touched. ee/app/models/concerns/elastic/application_versioned_search.rb lines 48 to 50 registers after_commit hooks on the work item's own create, update and destroy, each calling Elastic::ProcessBookkeepingService.track!. Banning a user does not write to their issues, so no hook fires.
I traced the ban path and found no reindex trigger at any step:
app/models/user.rblines 679 to 695, theafter_transition active: :bannedblock, creates the banned user record, invalidates todo caches, and on GitLab.com drops CI pipelines. No search work.app/services/users/ban_service.rbandapp/services/users/banned_user_base_service.rbcalluser.ban, log, and track an event. No search work.app/models/users/banned_user.rbdeclares associations and validations only. No callbacks.
So the author's issues keep hidden: false in the index indefinitely, and remain visible to every user through any Elasticsearch-served path, while Postgres hides them immediately.
This is live today. glql_es_integration has been enabled globally on GitLab.com since 2026-04-02, so any GLQL embedded view is already served from the index. It is not a rollout risk for the work item list; it is a current defect.
The exposure window is not bounded by ordinary index lag. The usual staleness is roughly a minute, set by the bulk cron in config/gitlab.yml.example lines 819 to 820. This one persists until something unrelated causes the issue to be reindexed, which may never happen.
What to change
When a user transitions to banned, enqueue reindexing of the work items they authored. When they are unbanned, do the same.
Two design points to settle in the merge request rather than assume:
- Batching. A prolific author may have many thousands of issues. Enqueue through a worker that batches rather than tracking every record inline in the transition callback, and follow the batching precedent in
Elastic::ProcessBookkeepingService, whose shard limit is a thousand records. - Where the hook belongs. The state machine transition in
app/models/user.rbis the single choke point for both ban and unban, which argues for putting it there. Confirm that auto-ban paths, such asapp/services/users/auto_ban_service.rb, route through the same transition; if they do not, they need the same treatment.
Apply the smallest fix that addresses the root cause. Do not refactor the indexing pipeline.
What could break
- A prolific author's ban could flood the indexing queue. This is the main risk and the reason to batch. Measure against a realistic author before merging.
- Unban must be symmetric.
app/models/user.rblines 698 to 700 handles the reverse transition. If only the ban side is fixed, unbanned users' issues stay hidden in search, which is the same bug pointing the other way. - A backfill may be required. Any user banned before this ships still has stale documents. Decide whether a migration is warranted and say so explicitly, rather than leaving it implied.
Done when
- Banning a user enqueues reindexing of the work items they authored.
- Unbanning does the same.
- A spec asserts a banned author's work item is absent from Elasticsearch results without any modification to the issue itself.
- The batching behaviour for a high volume author is stated in the merge request with a measured figure.
- The need for a backfill of already banned users is decided and recorded either way.
Dependencies
None.
Provenance
Read at commit 0c2053838c1efb839422477ccfbf7b8d76db2c10 on master. The absence of a reindex trigger was established by reading the state machine transition, both ban services, and the banned user model in full, not by keyword search alone.