Support denylist filters for instance audit event streaming

What does this MR do and why?

Instance streaming destinations only support allowlist event type filters, so an instance can't exclude a single high-volume event type (for example repository_git_operation) without allowlisting every other type. This MR brings instance filters in line with group filters:

  • Adds a kind column (allow: 0, deny: 1, default allow) to audit_events_instance_streaming_event_type_filters. Existing rows become allow, so current allowlists behave the same.
  • Adds the kind enum and allowlist/denylist scopes to AuditEvents::Instance::EventTypeFilter. On the instance destination, event_type_filters now returns allowlist filters only, and a new event_type_denylist_filters association returns deny filters. preload_filters loads both.
  • Removes the respond_to? guards in ExternallyStreamable, since both destination types now support filter kinds. Denylisted events are then skipped at the enqueue gate for instance destinations too.

Managing instance deny filters through GraphQL or the API is left for a follow-up. Until then, they can only be created in the Rails console. Pass kind: :deny explicitly, because creating through event_type_denylist_filters doesn't set it. The group denylist service does the same.

Depends on !261781 (merged), which this MR targets.

Migration output
main: == 20261013104217 AddKindToAuditEventsInstanceStreamingEventTypeFilters: migrating
main: -- add_column(:audit_events_instance_streaming_event_type_filters, :kind, :integer, {:limit=>2, :default=>0, :null=>false})
main:    -> 0.0433s
main: == 20261013104217 AddKindToAuditEventsInstanceStreamingEventTypeFilters: migrated (0.0530s)

main: == 20261013104217 AddKindToAuditEventsInstanceStreamingEventTypeFilters: reverting
main: -- remove_column(:audit_events_instance_streaming_event_type_filters, :kind, :integer, {:limit=>2, :default=>0, :null=>false})
main:    -> 0.0343s
main: == 20261013104217 AddKindToAuditEventsInstanceStreamingEventTypeFilters: reverted (0.0440s)

The table is table_size: small, and a constant default doesn't rewrite the table, so this is a regular migration. This table is empty on GitLab.com and is only a self managed feature.

Query change (instance destinations)
SELECT 1 AS one FROM audit_events_instance_external_streaming_destinations d
WHERE d.active = TRUE
  AND ((NOT EXISTS (SELECT 1 FROM audit_events_instance_streaming_event_type_filters f
                    WHERE f.external_streaming_destination_id = d.id AND f.kind = 0))
       OR (EXISTS (SELECT 1 FROM audit_events_instance_streaming_event_type_filters f
                   WHERE f.external_streaming_destination_id = d.id AND f.kind = 0
                     AND f.audit_event_type = 'repository_git_operation')))
  AND (NOT EXISTS (SELECT 1 FROM audit_events_instance_streaming_event_type_filters f
                   WHERE f.external_streaming_destination_id = d.id AND f.kind = 1
                     AND f.audit_event_type = 'repository_git_operation'))
LIMIT 1;

The subqueries use the existing unique index uniq_audit_instance_event_filters_destination_id_and_event_type on (external_streaming_destination_id, audit_event_type).

References

Screenshots or screen recordings

Not applicable, no UI changes.

How to set up and validate locally

  1. Run the migration: bundle exec rails db:migrate.

  2. In a Rails console, create an instance destination that denylists repository_git_operation:

    dest = AuditEvents::Instance::ExternalStreamingDestination.create!(
      name: 'instance-deny-test', category: :http,
      config: { 'url' => 'https://example.test/instance-deny-test' }
    )
    dest.event_type_denylist_filters.create!(audit_event_type: 'repository_git_operation', kind: :deny)
  3. Check the enqueue gate:

    event = AuditEvents::InstanceAuditEvent.new
    AuditEvents::Streaming::Instance::Streamer.new('repository_git_operation', event).streamable?
    # => false
    AuditEvents::Streaming::Instance::Streamer.new('user_created', event).streamable?
    # => true

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Huzaifa Iftikhar

Merge request reports

Loading
Loading