From 5f1bc7766b77a607866d5e58139be68a6e37b1fc Mon Sep 17 00:00:00 2001
From: Jayakrishnan Mallissery <jmallissery@gitlab.com>
Date: Mon, 10 Mar 2025 17:49:39 +0100
Subject: [PATCH] Track ID Token generation for Secrets Manager

We need to track the various metrics related to
feature usage for Secrets Manager. One of the
metrics is the generation of ID token for accessing the secrets manager.

We define the event and required metrics to track
the ID token generation. We trigger the event when
the ID token is generated in the ProjectSecretsManager.

[Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/428871)
---
 .../project_secrets_manager.rb                | 12 +++++++++
 ...ken_for_secrets_manager_authentication.yml | 15 +++++++++++
 ...ken_for_secrets_manager_authentication.yml | 21 ++++++++++++++++
 ...ken_for_secrets_manager_authentication.yml | 21 ++++++++++++++++
 .../project_secrets_manager_spec.rb           | 25 +++++++++++++++++++
 5 files changed, 94 insertions(+)
 create mode 100644 ee/config/events/generate_id_token_for_secrets_manager_authentication.yml
 create mode 100644 ee/config/metrics/counts_all/count_distinct_project_id_from_generate_id_token_for_secrets_manager_authentication.yml
 create mode 100644 ee/config/metrics/counts_all/count_distinct_user_id_from_generate_id_token_for_secrets_manager_authentication.yml

diff --git a/ee/app/models/secrets_management/project_secrets_manager.rb b/ee/app/models/secrets_management/project_secrets_manager.rb
index d1c0e1563b30e..d633adb109116 100644
--- a/ee/app/models/secrets_management/project_secrets_manager.rb
+++ b/ee/app/models/secrets_management/project_secrets_manager.rb
@@ -2,6 +2,8 @@
 
 module SecretsManagement
   class ProjectSecretsManager < ApplicationRecord
+    include Gitlab::InternalEventsTracking
+
     STATUSES = {
       provisioning: 0,
       active: 1,
@@ -93,6 +95,7 @@ def ci_auth_type
     end
 
     def ci_jwt(build)
+      track_ci_jwt_generation(build)
       Gitlab::Ci::JwtV2.for_build(build, aud: self.class.server_url)
     end
 
@@ -269,5 +272,14 @@ def namespace_path
         project.namespace.id.to_s
       ].join('_')
     end
+
+    def track_ci_jwt_generation(build)
+      track_internal_event(
+        'generate_id_token_for_secrets_manager_authentication',
+        project: project,
+        namespace: project.namespace,
+        user: build.user
+      )
+    end
   end
 end
diff --git a/ee/config/events/generate_id_token_for_secrets_manager_authentication.yml b/ee/config/events/generate_id_token_for_secrets_manager_authentication.yml
new file mode 100644
index 0000000000000..26478bb8206f6
--- /dev/null
+++ b/ee/config/events/generate_id_token_for_secrets_manager_authentication.yml
@@ -0,0 +1,15 @@
+---
+description: Generation of an ID token for a CI job to authenticate with Gitlab Native Secrets Manager to fetch a secret
+internal_events: true
+action: generate_id_token_for_secrets_manager_authentication
+identifiers:
+- project
+- namespace
+- user
+product_group: pipeline_security
+product_categories:
+- secrets_management
+milestone: '17.10'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/184062
+tiers:
+- ultimate
diff --git a/ee/config/metrics/counts_all/count_distinct_project_id_from_generate_id_token_for_secrets_manager_authentication.yml b/ee/config/metrics/counts_all/count_distinct_project_id_from_generate_id_token_for_secrets_manager_authentication.yml
new file mode 100644
index 0000000000000..359f2947c6fb9
--- /dev/null
+++ b/ee/config/metrics/counts_all/count_distinct_project_id_from_generate_id_token_for_secrets_manager_authentication.yml
@@ -0,0 +1,21 @@
+---
+key_path: redis_hll_counters.count_distinct_project_id_from_generate_id_token_for_secrets_manager_authentication
+description: Count of unique projects whose CI Jobs trigger ID token generation to fetch a secret from Gitlab Secrets Manager
+product_group: pipeline_security
+product_categories:
+- secrets_management
+performance_indicator_type: []
+value_type: number
+status: active
+milestone: '17.10'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/184062
+time_frame:
+- 28d
+- 7d
+data_source: internal_events
+data_category: optional
+tiers:
+- ultimate
+events:
+- name: generate_id_token_for_secrets_manager_authentication
+  unique: project.id
diff --git a/ee/config/metrics/counts_all/count_distinct_user_id_from_generate_id_token_for_secrets_manager_authentication.yml b/ee/config/metrics/counts_all/count_distinct_user_id_from_generate_id_token_for_secrets_manager_authentication.yml
new file mode 100644
index 0000000000000..a4df6ec996036
--- /dev/null
+++ b/ee/config/metrics/counts_all/count_distinct_user_id_from_generate_id_token_for_secrets_manager_authentication.yml
@@ -0,0 +1,21 @@
+---
+key_path: redis_hll_counters.count_distinct_user_id_from_generate_id_token_for_secrets_manager_authentication
+description: Count of unique users starting CI Jobs that trigger ID token generation to fetch a secret from Gitlab Secrets Manager
+product_group: pipeline_security
+product_categories:
+- secrets_management
+performance_indicator_type: []
+value_type: number
+status: active
+milestone: '17.10'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/184062
+time_frame:
+- 28d
+- 7d
+data_source: internal_events
+data_category: optional
+tiers:
+- ultimate
+events:
+- name: generate_id_token_for_secrets_manager_authentication
+  unique: user.id
diff --git a/ee/spec/models/secrets_management/project_secrets_manager_spec.rb b/ee/spec/models/secrets_management/project_secrets_manager_spec.rb
index b1b3b57a97263..c38e2e0a290a4 100644
--- a/ee/spec/models/secrets_management/project_secrets_manager_spec.rb
+++ b/ee/spec/models/secrets_management/project_secrets_manager_spec.rb
@@ -91,4 +91,29 @@
       end
     end
   end
+
+  describe '#ci_jwt' do
+    let_it_be(:project) { create(:project) }
+    let_it_be(:secrets_manager) { build(:project_secrets_manager, project: project) }
+    let_it_be(:ci_build) { create(:ci_build, project: project) }
+    let_it_be(:openbao_server_url) { described_class.server_url }
+
+    subject(:ci_jwt) { secrets_manager.ci_jwt(ci_build) }
+
+    before do
+      allow(Gitlab::Ci::JwtV2).to receive(:for_build).with(ci_build, aud: openbao_server_url)
+      .and_return("generated_jwt_id_token_for_secrets_manager")
+    end
+
+    it 'generates a JWT for the build' do
+      expect(ci_jwt).to eq("generated_jwt_id_token_for_secrets_manager")
+    end
+
+    it_behaves_like 'internal event tracking' do
+      let(:event) { 'generate_id_token_for_secrets_manager_authentication' }
+      let(:category) { described_class.name }
+      let(:namespace) { project.namespace }
+      let(:user) { ci_build.user }
+    end
+  end
 end
-- 
GitLab