From 3c83d987c5335c974c63c403ee74b0dce733e815 Mon Sep 17 00:00:00 2001
From: Kurt <kc13greiner@users.noreply.github.com>
Date: Mon, 2 Dec 2024 07:50:40 -0500
Subject: [PATCH] Adding telemetry for the fips config (#201282)

## Summary

Adding telemetry for the `fipsMode.enabled` config
---
 .../security_usage_collector.test.ts          | 53 +++++++++++++++++++
 .../security_usage_collector.ts               | 14 ++++-
 .../schema/xpack_plugins.json                 |  6 +++
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts
index 19378bfd8488b..72b9e44da3f43 100644
--- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts
+++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts
@@ -26,6 +26,7 @@ describe('Security UsageCollector', () => {
     allowAccessAgreement = true,
     allowAuditLogging = true,
     allowRbac = true,
+    allowFips = true,
     isLicenseAvailable,
   }: Partial<SecurityLicenseFeatures> & { isLicenseAvailable: boolean }) => {
     const license = licenseMock.create();
@@ -34,6 +35,7 @@ describe('Security UsageCollector', () => {
       allowAccessAgreement,
       allowAuditLogging,
       allowRbac,
+      allowFips,
     } as SecurityLicenseFeatures);
     return license;
   };
@@ -44,6 +46,7 @@ describe('Security UsageCollector', () => {
     accessAgreementEnabled: false,
     authProviderCount: 1,
     enabledAuthProviders: ['basic'],
+    fipsModeEnabled: false,
     loginSelectorEnabled: false,
     httpAuthSchemes: ['apikey', 'bearer'],
     sessionIdleTimeoutInMinutes: 4320,
@@ -106,6 +109,7 @@ describe('Security UsageCollector', () => {
       accessAgreementEnabled: false,
       authProviderCount: 0,
       enabledAuthProviders: [],
+      fipsModeEnabled: false,
       loginSelectorEnabled: false,
       httpAuthSchemes: [],
       sessionIdleTimeoutInMinutes: 0,
@@ -426,6 +430,55 @@ describe('Security UsageCollector', () => {
     });
   });
 
+  describe('fipsMode enabled', () => {
+    it('reports when fipsMode is enabled', async () => {
+      const config = createSecurityConfig(
+        ConfigSchema.validate({
+          fipsMode: {
+            enabled: true,
+          },
+        })
+      );
+      const usageCollection = usageCollectionPluginMock.createSetupContract();
+      const license = createSecurityLicense({
+        isLicenseAvailable: true,
+        allowFips: true,
+      });
+      registerSecurityUsageCollector({ usageCollection, config, license });
+
+      const usage = await usageCollection
+        .getCollectorByType('security')
+        ?.fetch(collectorFetchContext);
+
+      expect(usage).toEqual({
+        ...DEFAULT_USAGE,
+        fipsModeEnabled: true,
+      });
+    });
+
+    it('does not report fipsMode when the license does not permit it', async () => {
+      const config = createSecurityConfig(
+        ConfigSchema.validate({
+          fipsMode: {
+            enabled: true,
+          },
+        })
+      );
+      const usageCollection = usageCollectionPluginMock.createSetupContract();
+      const license = createSecurityLicense({ isLicenseAvailable: true, allowFips: false });
+      registerSecurityUsageCollector({ usageCollection, config, license });
+
+      const usage = await usageCollection
+        .getCollectorByType('security')
+        ?.fetch(collectorFetchContext);
+
+      expect(usage).toEqual({
+        ...DEFAULT_USAGE,
+        fipsModeEnabled: false,
+      });
+    });
+  });
+
   describe('http auth schemes', () => {
     it('reports customized http auth schemes', async () => {
       const config = createSecurityConfig(
diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts
index fc761fb13a50e..575fea2bf32c4 100644
--- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts
+++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts
@@ -16,6 +16,7 @@ interface Usage {
   accessAgreementEnabled: boolean;
   authProviderCount: number;
   enabledAuthProviders: string[];
+  fipsModeEnabled: boolean;
   httpAuthSchemes: string[];
   sessionIdleTimeoutInMinutes: number;
   sessionLifespanInMinutes: number;
@@ -93,6 +94,12 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
           },
         },
       },
+      fipsModeEnabled: {
+        type: 'boolean',
+        _meta: {
+          description: 'Indicates if Kibana is being run in FIPS mode.',
+        },
+      },
       httpAuthSchemes: {
         type: 'array',
         items: {
@@ -139,7 +146,8 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
       },
     },
     fetch: () => {
-      const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures();
+      const { allowRbac, allowAccessAgreement, allowAuditLogging, allowFips } =
+        license.getFeatures();
       if (!allowRbac) {
         return {
           auditLoggingEnabled: false,
@@ -147,6 +155,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
           accessAgreementEnabled: false,
           authProviderCount: 0,
           enabledAuthProviders: [],
+          fipsModeEnabled: false,
           httpAuthSchemes: [],
           sessionIdleTimeoutInMinutes: 0,
           sessionLifespanInMinutes: 0,
@@ -171,6 +180,8 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
         WELL_KNOWN_AUTH_SCHEMES.includes(scheme.toLowerCase())
       );
 
+      const fipsModeEnabled = allowFips && config.fipsMode.enabled;
+
       const sessionExpirations = config.session.getExpirationTimeouts(undefined); // use `undefined` to get global expiration values
       const sessionIdleTimeoutInMinutes = sessionExpirations.idleTimeout?.asMinutes() ?? 0;
       const sessionLifespanInMinutes = sessionExpirations.lifespan?.asMinutes() ?? 0;
@@ -202,6 +213,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
         accessAgreementEnabled,
         authProviderCount,
         enabledAuthProviders,
+        fipsModeEnabled,
         httpAuthSchemes,
         sessionIdleTimeoutInMinutes,
         sessionLifespanInMinutes,
diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json
index 257ad9c3af07b..b086844792217 100644
--- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json
+++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json
@@ -15224,6 +15224,12 @@
             }
           }
         },
+        "fipsModeEnabled": {
+          "type": "boolean",
+          "_meta": {
+            "description": "Indicates if Kibana is being run in FIPS mode."
+          }
+        },
         "httpAuthSchemes": {
           "type": "array",
           "items": {