From 692472a0f280e537360cfabaa1cf4063a50902bf Mon Sep 17 00:00:00 2001 From: Jio Castillo Date: Mon, 23 Jun 2025 13:16:03 -0700 Subject: [PATCH] Add add_ssh_key audit event type Changelog: changed EE: true --- .../gitlab/rspec/misplaced_ee_spec_file.yml | 1 - .rubocop_todo/rspec/named_subject.yml | 1 - doc/user/compliance/audit_event_types.md | 1 + ee/app/services/ee/keys/create_service.rb | 16 ++-- ee/config/audit_events/types/add_ssh_key.yml | 10 +++ .../services/ee/keys/create_service_spec.rb | 79 +++++++++++++++++++ ee/spec/services/keys/create_service_spec.rb | 23 ------ spec/support/rspec_order_todo.yml | 2 +- 8 files changed, 99 insertions(+), 34 deletions(-) create mode 100644 ee/config/audit_events/types/add_ssh_key.yml create mode 100644 ee/spec/services/ee/keys/create_service_spec.rb delete mode 100644 ee/spec/services/keys/create_service_spec.rb diff --git a/.rubocop_todo/gitlab/rspec/misplaced_ee_spec_file.yml b/.rubocop_todo/gitlab/rspec/misplaced_ee_spec_file.yml index 33bba1c905d842..8f36af26d1d987 100644 --- a/.rubocop_todo/gitlab/rspec/misplaced_ee_spec_file.yml +++ b/.rubocop_todo/gitlab/rspec/misplaced_ee_spec_file.yml @@ -279,7 +279,6 @@ Gitlab/RSpec/MisplacedEeSpecFile: - 'ee/spec/services/ide/schemas_config_service_spec.rb' - 'ee/spec/services/issues/build_service_spec.rb' - 'ee/spec/services/issues/export_csv_service_spec.rb' - - 'ee/spec/services/keys/create_service_spec.rb' - 'ee/spec/services/lfs/lock_file_service_spec.rb' - 'ee/spec/services/lfs/unlock_file_service_spec.rb' - 'ee/spec/services/merge_requests/approval_service_spec.rb' diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml index 979c0d961401c1..562406de9f534a 100644 --- a/.rubocop_todo/rspec/named_subject.yml +++ b/.rubocop_todo/rspec/named_subject.yml @@ -910,7 +910,6 @@ RSpec/NamedSubject: - 'ee/spec/services/iterations/update_service_spec.rb' - 'ee/spec/services/jira/jql_builder_service_spec.rb' - 'ee/spec/services/jira/requests/issues/list_service_spec.rb' - - 'ee/spec/services/keys/create_service_spec.rb' - 'ee/spec/services/lfs/lock_file_service_spec.rb' - 'ee/spec/services/lfs/unlock_file_service_spec.rb' - 'ee/spec/services/llm/chat_service_spec.rb' diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index 78d9af2078d320..be44acd8dab8b8 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -682,6 +682,7 @@ Audit event types belong to the following product categories. | Type name | Event triggered when | Saved to database | Introduced in | Scope | |:----------|:---------------------|:------------------|:--------------|:------| +| [`add_ssh_key`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/195379) | An SSH key is added to a user's profile. Group scope is only available for enterprise users. | {{< icon name="check-circle" >}} Yes | GitLab [18.2](https://gitlab.com/gitlab-org/gitlab/-/issues/361778) | User, Group | | [`email_confirmation_sent`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129261) | Users add or change an email address and it must be confirmed | {{< icon name="dotted-circle" >}} No | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/377625) | User | | [`remove_ssh_key`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65615) | An SSH key is removed from a user's profile. Group scope was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/195390) for enterprise users in GitLab 18.2. | {{< icon name="check-circle" >}} Yes | GitLab [14.1](https://gitlab.com/gitlab-org/gitlab/-/issues/220127) | User, Group | | [`user_admin_status_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65168) | A user is either made an administrator or removed as an administrator | {{< icon name="check-circle" >}} Yes | GitLab [14.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323905) | User | diff --git a/ee/app/services/ee/keys/create_service.rb b/ee/app/services/ee/keys/create_service.rb index 8a8384ca4dd34b..3aa5201377431b 100644 --- a/ee/app/services/ee/keys/create_service.rb +++ b/ee/app/services/ee/keys/create_service.rb @@ -10,15 +10,15 @@ def execute end def log_audit_event(key) - audit_event_service.for_user(full_path: key.title, entity_id: key.id).security_event - end + audit_context = { + name: 'add_ssh_key', + author: current_user, + scope: user&.enterprise_group.presence || user, + target: key, + message: 'Added SSH key' + } - def audit_event_service - ::AuditEventService.new(current_user, - user, - action: :custom, - custom_message: 'Added SSH key', - ip_address: @ip_address) # rubocop:disable Gitlab/ModuleWithInstanceVariables + ::Gitlab::Audit::Auditor.audit(audit_context) end end end diff --git a/ee/config/audit_events/types/add_ssh_key.yml b/ee/config/audit_events/types/add_ssh_key.yml new file mode 100644 index 00000000000000..07a6517bf866aa --- /dev/null +++ b/ee/config/audit_events/types/add_ssh_key.yml @@ -0,0 +1,10 @@ +--- +name: add_ssh_key +description: An SSH key is added to a user's profile. Group scope is only available for enterprise users. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/361778 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/195379 +feature_category: user_profile +milestone: '18.2' +saved_to_database: true +streamed: true +scope: [User, Group] \ No newline at end of file diff --git a/ee/spec/services/ee/keys/create_service_spec.rb b/ee/spec/services/ee/keys/create_service_spec.rb new file mode 100644 index 00000000000000..81539306587640 --- /dev/null +++ b/ee/spec/services/ee/keys/create_service_spec.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Keys::CreateService, feature_category: :user_profile do + let_it_be(:user) { create(:user) } + + let(:params) { attributes_for(:key).merge(user: user) } + + subject(:service) { described_class.new(user, params) } + + describe 'audit events' do + context 'when licensed' do + before do + stub_licensed_features(admin_audit_log: true, audit_events: true, extended_audit_events: true) + end + + context 'when user adds an SSH key' do + it 'creates a user audit event' do + expect { service.execute }.to change { AuditEvent.count }.by(1) + + expect(AuditEvent.last).to have_attributes( + author: user, + entity_type: "User", + entity_id: user.id, + details: include(custom_message: 'Added SSH key') + ) + end + + context 'when on SaaS', :saas do + context 'when user is an Enterprise User' do + let_it_be(:enterprise_group) { create(:group) } + let_it_be(:user) do + create(:enterprise_user, :with_namespace, enterprise_group: enterprise_group) + end + + it 'creates a group audit event' do + expect { service.execute }.to change { AuditEvent.count }.by(1) + + expect(AuditEvent.last).to have_attributes( + author: user, + entity_type: "Group", + entity_id: enterprise_group.id, + details: include(custom_message: 'Added SSH key') + ) + end + end + end + end + + context 'when an admin adds an SSH key to a user' do + let_it_be(:admin) { create(:admin) } + + subject(:service) { described_class.new(admin, params) } + + it 'creates a user audit event' do + expect { service.execute }.to change { AuditEvent.count }.by(1) + + expect(AuditEvent.last).to have_attributes( + author: admin, + entity_type: "User", + entity_id: user.id, + details: include(custom_message: 'Added SSH key') + ) + end + end + end + + context 'when unlicensed' do + before do + stub_licensed_features(admin_audit_log: false, audit_events: false, extended_audit_events: false) + end + + it 'does not track audit event' do + expect { service.execute }.not_to change { AuditEvent.count } + end + end + end +end diff --git a/ee/spec/services/keys/create_service_spec.rb b/ee/spec/services/keys/create_service_spec.rb deleted file mode 100644 index 34aa4db0bdc72c..00000000000000 --- a/ee/spec/services/keys/create_service_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Keys::CreateService, feature_category: :source_code_management do - let_it_be(:admin) { create(:admin) } - let_it_be(:user) { create(:user) } - - let(:params) { attributes_for(:key).merge(user: user) } - - subject { described_class.new(admin, params) } - - it 'creates' do - stub_licensed_features(extended_audit_events: true) - - expect { subject.execute }.to change { AuditEvent.count }.by(1) - - event = AuditEvent.last - - expect(event.author_name).to eq(admin.name) - expect(event.entity_id).to eq(user.id) - end -end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index e778c2726ec179..2fba34d6ef7aa6 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -1955,6 +1955,7 @@ - './ee/spec/services/ee/issues/after_create_service_spec.rb' - './ee/spec/services/ee/issues/create_service_spec.rb' - './ee/spec/services/ee/issues/update_service_spec.rb' +- './ee/spec/services/ee/keys/create_service_spec.rb' - './ee/spec/services/ee/keys/destroy_service_spec.rb' - './ee/spec/services/ee/labels/promote_service_spec.rb' - './ee/spec/services/ee/members/create_service_spec.rb' @@ -2096,7 +2097,6 @@ - './ee/spec/services/iterations/update_service_spec.rb' - './ee/spec/services/jira/jql_builder_service_spec.rb' - './ee/spec/services/jira/requests/issues/list_service_spec.rb' -- './ee/spec/services/keys/create_service_spec.rb' - './ee/spec/services/keys/last_used_service_spec.rb' - './ee/spec/services/ldap_group_reset_service_spec.rb' - './ee/spec/services/lfs/lock_file_service_spec.rb' -- GitLab