From 44056b305a76af5c4c83fba285e67811ca9838e9 Mon Sep 17 00:00:00 2001 From: Kasia Misirli Date: Thu, 4 Sep 2025 18:08:44 +0200 Subject: [PATCH] Add streaming audit events --- .../groups/settings/ci_cd_controller.rb | 20 +++++++++++++++ .../projects/settings/ci_cd_controller.rb | 21 ++++++++++++++++ .../types/group_ci_cd_settings_accessed.yml | 10 ++++++++ .../types/project_ci_cd_settings_accessed.yml | 10 ++++++++ doc/user/compliance/audit_event_types.md | 2 ++ .../groups/settings/ci_cd_controller_spec.rb | 25 +++++++++++++++++++ .../settings/ci_cd_controller_spec.rb | 21 ++++++++++++++++ 7 files changed, 109 insertions(+) create mode 100644 config/audit_events/types/group_ci_cd_settings_accessed.yml create mode 100644 config/audit_events/types/project_ci_cd_settings_accessed.yml diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 875c2d521e2a83..f32adc6b05782f 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -23,6 +23,8 @@ class CiCdController < Groups::ApplicationController def show @entity = :group @variable_limit = ::Plan.default.actual_limits.group_ci_variables + + audit_group_cicd_settings_access end def update @@ -51,6 +53,24 @@ def update_auto_devops private + def audit_group_cicd_settings_access + audit_context = { + name: 'group_ci_cd_settings_accessed', + author: current_user, + scope: group, + target: group, + message: 'User accessed CI/CD settings for a group', + additional_details: { + group_path: group.full_path, + group_id: group.id, + timestamp: Time.current.iso8601, + action: 'group_ci_cd_settings_page_viewed' + } + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + def authorize_show_cicd_settings! return if can_any?(current_user, [ :admin_cicd_variables, diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 778d4d276df45e..6ca167d1b69eaa 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -36,6 +36,8 @@ def show @triggers_json = Gitlab::Json.dump(triggers) + audit_project_cicd_settings_access + render end @@ -100,6 +102,25 @@ def export_job_token_authorizations private + def audit_project_cicd_settings_access + audit_context = { + name: 'project_ci_cd_settings_accessed', + author: current_user, + scope: project, + target: project, + message: 'User accessed CI/CD settings for project', + additional_details: { + project_path: project.full_path, + project_id: project.id, + ip_address: request.remote_ip, + timestamp: Time.current.iso8601, + action: 'project_ci_cd_settings_page_viewed' + } + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + def authorize_reset_cache! return if can_any?(current_user, [ :admin_pipeline, diff --git a/config/audit_events/types/group_ci_cd_settings_accessed.yml b/config/audit_events/types/group_ci_cd_settings_accessed.yml new file mode 100644 index 00000000000000..0b6c94ad68503f --- /dev/null +++ b/config/audit_events/types/group_ci_cd_settings_accessed.yml @@ -0,0 +1,10 @@ +--- +name: group_ci_cd_settings_accessed +description: Log an audit event when a user loads the CI/CD Settings page of a group. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/555959 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203540 +feature_category: ci_variables +milestone: '18.4' +saved_to_database: false +streamed: true +scope: [Group] diff --git a/config/audit_events/types/project_ci_cd_settings_accessed.yml b/config/audit_events/types/project_ci_cd_settings_accessed.yml new file mode 100644 index 00000000000000..488dd613f17552 --- /dev/null +++ b/config/audit_events/types/project_ci_cd_settings_accessed.yml @@ -0,0 +1,10 @@ +--- +name: project_ci_cd_settings_accessed +description: Log an audit event when a user loads the CI/CD Settings page of a project. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/555959 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203540 +feature_category: ci_variables +milestone: '18.4' +saved_to_database: false +streamed: true +scope: [Project] diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index 538e1a676a37c2..06cc564dfaab64 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -124,6 +124,8 @@ Audit event types belong to the following product categories. | Type name | Event triggered when | Saved to database | Introduced in | Scope | |:----------|:---------------------|:------------------|:--------------|:------| | [`variable_viewed_api`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/197385) | A CI/CD variable is accessed with the API | {{< icon name="dotted-circle" >}} No | GitLab [18.3](https://gitlab.com/gitlab-org/gitlab/-/issues/555960) | Project, Group | +| [`group_ci_cd_settings_accessed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203540) | Log an audit event when a user loads the CI/CD Settings page of a group. | {{< icon name="dotted-circle" >}} No | GitLab [18.4](https://gitlab.com/gitlab-org/gitlab/-/issues/555959) | Group | +| [`project_ci_cd_settings_accessed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/203540) | Log an audit event when a user loads the CI/CD Settings page of a project. | {{< icon name="dotted-circle" >}} No | GitLab [18.4](https://gitlab.com/gitlab-org/gitlab/-/issues/555959) | Project | ### Code review diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb index 20a04c59bcfcc2..45939720e4336a 100644 --- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb @@ -50,6 +50,31 @@ expect(response).to have_gitlab_http_status(:ok) end end + + context 'when accessing CI/CD Settings page for a group' do + before do + enable_external_authorization_service_check + group.add_owner(user) + end + + it 'creates a streaming audit event' do + expect(::Gitlab::Audit::Auditor).to receive(:audit).with({ + name: 'group_ci_cd_settings_accessed', + author: user, + scope: group, + target: group, + message: 'User accessed CI/CD settings for a group', + additional_details: hash_including( + group_path: group.full_path, + group_id: group.id, + timestamp: kind_of(String), + action: 'group_ci_cd_settings_page_viewed' + ) + }) + + get :show, params: { group_id: group } + end + end end describe 'PATCH #update_auto_devops' do diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index e1ef738b240cb1..be15427d52d94c 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -142,6 +142,27 @@ def show expect(response).to have_gitlab_http_status(:not_found) end end + + context 'when accessing CI/CD Settings page for a project' do + it 'creates a streaming audit event' do + expect(::Gitlab::Audit::Auditor).to receive(:audit).with({ + name: 'project_ci_cd_settings_accessed', + author: user, + scope: project, + target: project, + message: 'User accessed CI/CD settings for project', + additional_details: hash_including( + project_path: project.full_path, + project_id: project.id, + ip_address: '0.0.0.0', + timestamp: kind_of(String), + action: 'project_ci_cd_settings_page_viewed' + ) + }) + + get :show, params: { namespace_id: project.namespace, project_id: project } + end + end end describe 'POST reset_cache' do -- GitLab