From cca3e274680dcbc1cc89bbdb926ab773b0a03d80 Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 1 Nov 2024 20:20:22 +1100
Subject: [PATCH] [8.x] [ResponseOps][Cases] Make deprecated APIs internal in
 serverless (#198378) (#198640)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Cases] Make deprecated APIs internal in serverless
(#198378)](https://github.com/elastic/kibana/pull/198378)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Christos
Nasikas","email":"christos.nasikas@elastic.co"},"sourceCommit":{"committedDate":"2024-11-01T07:38:32Z","message":"[ResponseOps][Cases]
Make deprecated APIs internal in serverless (#198378)\n\n## Summary\r\n
\r\nFixes: https://github.com/elastic/kibana/issues/198407\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n### For
maintainers\r\n\r\n- [x] This was checked for breaking API changes and
was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels)","sha":"2ae6333b1b6c004b1daa534cdab9418758593b02","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","v9.0.0","Feature:Cases","backport:prev-minor","ci:project-deploy-observability","v8.17.0"],"title":"[ResponseOps][Cases]
Make deprecated APIs internal in
serverless","number":198378,"url":"https://github.com/elastic/kibana/pull/198378","mergeCommit":{"message":"[ResponseOps][Cases]
Make deprecated APIs internal in serverless (#198378)\n\n## Summary\r\n
\r\nFixes: https://github.com/elastic/kibana/issues/198407\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n### For
maintainers\r\n\r\n- [x] This was checked for breaking API changes and
was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels)","sha":"2ae6333b1b6c004b1daa534cdab9418758593b02"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/198378","number":198378,"mergeCommit":{"message":"[ResponseOps][Cases]
Make deprecated APIs internal in serverless (#198378)\n\n## Summary\r\n
\r\nFixes: https://github.com/elastic/kibana/issues/198407\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n### For
maintainers\r\n\r\n- [x] This was checked for breaking API changes and
was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels)","sha":"2ae6333b1b6c004b1daa534cdab9418758593b02"}},{"branch":"8.x","label":"v8.17.0","branchLabelMappingKey":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
---
 x-pack/plugins/cases/server/plugin.ts         |  7 +-
 .../server/routes/api/cases/get_case.test.ts  | 62 +++++++++++++
 .../cases/server/routes/api/cases/get_case.ts | 92 ++++++++++---------
 .../api/comments/get_all_comment.test.ts      | 22 +++++
 .../routes/api/comments/get_all_comment.ts    | 75 +++++++--------
 .../server/routes/api/get_external_routes.ts  | 10 +-
 .../routes/api/stats/get_status.test.ts       | 22 +++++
 .../server/routes/api/stats/get_status.ts     | 65 ++++++-------
 .../user_actions/get_all_user_actions.test.ts | 22 +++++
 .../api/user_actions/get_all_user_actions.ts  | 73 +++++++--------
 .../common/lib/api/index.ts                   | 10 +-
 .../api_integration/services/svl_cases/api.ts | 14 +--
 .../observability/cases/get_all_comments.ts   | 45 +++++++++
 .../cases/get_all_user_actions.ts             | 45 +++++++++
 .../observability/cases/get_case.ts           | 19 +++-
 .../observability/cases/get_status.ts         | 45 +++++++++
 .../test_suites/observability/cases/index.ts  |  3 +
 .../test_suites/security/cases/get_case.ts    | 19 +++-
 18 files changed, 481 insertions(+), 169 deletions(-)
 create mode 100644 x-pack/plugins/cases/server/routes/api/cases/get_case.test.ts
 create mode 100644 x-pack/plugins/cases/server/routes/api/comments/get_all_comment.test.ts
 create mode 100644 x-pack/plugins/cases/server/routes/api/stats/get_status.test.ts
 create mode 100644 x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.test.ts
 create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_comments.ts
 create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_user_actions.ts
 create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/get_status.ts

diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts
index fa172b48520a7..b40089ff75050 100644
--- a/x-pack/plugins/cases/server/plugin.ts
+++ b/x-pack/plugins/cases/server/plugin.ts
@@ -122,9 +122,14 @@ export class CasePlugin
     const router = core.http.createRouter<CasesRequestHandlerContext>();
     const telemetryUsageCounter = plugins.usageCollection?.createUsageCounter(APP_ID);
 
+    const isServerless = plugins.cloud?.isServerlessEnabled;
+
     registerRoutes({
       router,
-      routes: [...getExternalRoutes(), ...getInternalRoutes(this.userProfileService)],
+      routes: [
+        ...getExternalRoutes({ isServerless }),
+        ...getInternalRoutes(this.userProfileService),
+      ],
       logger: this.logger,
       kibanaVersion: this.kibanaVersion,
       telemetryUsageCounter,
diff --git a/x-pack/plugins/cases/server/routes/api/cases/get_case.test.ts b/x-pack/plugins/cases/server/routes/api/cases/get_case.test.ts
new file mode 100644
index 0000000000000..45ee5e8f47163
--- /dev/null
+++ b/x-pack/plugins/cases/server/routes/api/cases/get_case.test.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createCasesClientMock } from '../../../client/mocks';
+import { getCaseRoute } from './get_case';
+import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks';
+
+describe('getCaseRoute', () => {
+  const casesClientMock = createCasesClientMock();
+  const logger = loggingSystemMock.createLogger();
+  const response = httpServerMock.createResponseFactory();
+  const kibanaVersion = '8.17';
+  const context = { cases: { getCasesClient: jest.fn().mockResolvedValue(casesClientMock) } };
+
+  it('throws a bad request if the includeComments is set in serverless', async () => {
+    const router = getCaseRoute({ isServerless: true });
+    const request = httpServerMock.createKibanaRequest({
+      path: '/api/cases/{case_id}/?includeComments=true',
+      query: { includeComments: true },
+      params: { case_id: 'foo' },
+    });
+
+    await expect(
+      // @ts-expect-error: no need to create the context
+      router.handler({ response, request, logger, kibanaVersion, context })
+    ).rejects.toThrowErrorMatchingInlineSnapshot(`
+      "Failed to retrieve case in route case id: foo 
+      include comments: true: Error: includeComments is not supported"
+    `);
+  });
+
+  it('does not throw a bad request if the includeComments is set in non-serverless', async () => {
+    const router = getCaseRoute({ isServerless: false });
+    const request = httpServerMock.createKibanaRequest({
+      path: '/api/cases/{case_id}/?includeComments=true',
+      query: { includeComments: true },
+      params: { case_id: 'foo' },
+    });
+
+    await expect(
+      // @ts-expect-error: no need to create the context
+      router.handler({ response, request, logger, kibanaVersion, context })
+    ).resolves.not.toThrow();
+  });
+
+  it('does not throw a bad request if the includeComments is not set in serverless', async () => {
+    const router = getCaseRoute({ isServerless: true });
+    const request = httpServerMock.createKibanaRequest({
+      path: '/api/cases/{case_id}',
+      params: { case_id: 'foo' },
+    });
+
+    await expect(
+      // @ts-expect-error: no need to create the context
+      router.handler({ response, request, logger, kibanaVersion, context })
+    ).resolves.not.toThrow();
+  });
+});
diff --git a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts
index 831a7be129f70..158360ff7b23f 100644
--- a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts
+++ b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts
@@ -5,6 +5,7 @@
  * 2.0.
  */
 
+import Boom from '@hapi/boom';
 import { schema } from '@kbn/config-schema';
 
 import type { caseApiV1 } from '../../../../common/types/api';
@@ -26,53 +27,58 @@ const params = {
   }),
 };
 
-export const getCaseRoute = createCasesRoute({
-  method: 'get',
-  path: CASE_DETAILS_URL,
-  params,
-  routerOptions: {
-    access: 'public',
-    summary: `Get a case`,
-    tags: ['oas-tag:cases'],
-  },
-  handler: async ({ context, request, response, logger, kibanaVersion }) => {
-    try {
-      const isIncludeCommentsParamProvidedByTheUser =
-        request.url.searchParams.has('includeComments');
+export const getCaseRoute = ({ isServerless }: { isServerless?: boolean }) =>
+  createCasesRoute({
+    method: 'get',
+    path: CASE_DETAILS_URL,
+    params,
+    routerOptions: {
+      access: 'public',
+      summary: `Get a case`,
+      tags: ['oas-tag:cases'],
+    },
+    handler: async ({ context, request, response, logger, kibanaVersion }) => {
+      try {
+        const isIncludeCommentsParamProvidedByTheUser =
+          request.url.searchParams.has('includeComments');
 
-      if (isIncludeCommentsParamProvidedByTheUser) {
-        logDeprecatedEndpoint(
-          logger,
-          request.headers,
-          `The query parameter 'includeComments' of the get case API '${CASE_DETAILS_URL}' is deprecated`
-        );
-      }
+        if (isServerless && isIncludeCommentsParamProvidedByTheUser) {
+          throw Boom.badRequest('includeComments is not supported');
+        }
 
-      const caseContext = await context.cases;
-      const casesClient = await caseContext.getCasesClient();
-      const id = request.params.case_id;
+        if (isIncludeCommentsParamProvidedByTheUser) {
+          logDeprecatedEndpoint(
+            logger,
+            request.headers,
+            `The query parameter 'includeComments' of the get case API '${CASE_DETAILS_URL}' is deprecated`
+          );
+        }
 
-      const res: caseDomainV1.Case = await casesClient.cases.get({
-        id,
-        includeComments: request.query.includeComments,
-      });
+        const caseContext = await context.cases;
+        const casesClient = await caseContext.getCasesClient();
+        const id = request.params.case_id;
 
-      return response.ok({
-        ...(isIncludeCommentsParamProvidedByTheUser && {
-          headers: {
-            ...getWarningHeader(kibanaVersion, 'Deprecated query parameter includeComments'),
-          },
-        }),
-        body: res,
-      });
-    } catch (error) {
-      throw createCaseError({
-        message: `Failed to retrieve case in route case id: ${request.params.case_id} \ninclude comments: ${request.query.includeComments}: ${error}`,
-        error,
-      });
-    }
-  },
-});
+        const res: caseDomainV1.Case = await casesClient.cases.get({
+          id,
+          includeComments: request.query.includeComments,
+        });
+
+        return response.ok({
+          ...(isIncludeCommentsParamProvidedByTheUser && {
+            headers: {
+              ...getWarningHeader(kibanaVersion, 'Deprecated query parameter includeComments'),
+            },
+          }),
+          body: res,
+        });
+      } catch (error) {
+        throw createCaseError({
+          message: `Failed to retrieve case in route case id: ${request.params.case_id} \ninclude comments: ${request.query.includeComments}: ${error}`,
+          error,
+        });
+      }
+    },
+  });
 
 export const resolveCaseRoute = createCasesRoute({
   method: 'get',
diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.test.ts b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.test.ts
new file mode 100644
index 0000000000000..9687e73d1f7c8
--- /dev/null
+++ b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.test.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getAllCommentsRoute } from './get_all_comment';
+
+describe('getAllCommentsRoute', () => {
+  it('marks the endpoint internal in serverless', async () => {
+    const router = getAllCommentsRoute({ isServerless: true });
+
+    expect(router.routerOptions?.access).toBe('internal');
+  });
+
+  it('marks the endpoint public in non-serverless', async () => {
+    const router = getAllCommentsRoute({ isServerless: false });
+
+    expect(router.routerOptions?.access).toBe('public');
+  });
+});
diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts
index 6e8ac79bffec9..0f84ed29dce29 100644
--- a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts
+++ b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts
@@ -15,41 +15,42 @@ import type { attachmentDomainV1 } from '../../../../common/types/domain';
 /**
  * @deprecated since version 8.1.0
  */
-export const getAllCommentsRoute = createCasesRoute({
-  method: 'get',
-  path: CASE_COMMENTS_URL,
-  params: {
-    params: schema.object({
-      case_id: schema.string(),
-    }),
-  },
-  options: {
-    deprecated: true,
-  },
-  routerOptions: {
-    access: 'public',
-    summary: `Gets all case comments`,
-    tags: ['oas-tag:cases'],
-    // description: 'You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you\'re seeking.',
-    // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
-    deprecated: true,
-  },
-  handler: async ({ context, request, response }) => {
-    try {
-      const caseContext = await context.cases;
-      const client = await caseContext.getCasesClient();
-      const res: attachmentDomainV1.Attachments = await client.attachments.getAll({
-        caseID: request.params.case_id,
-      });
+export const getAllCommentsRoute = ({ isServerless }: { isServerless?: boolean }) =>
+  createCasesRoute({
+    method: 'get',
+    path: CASE_COMMENTS_URL,
+    params: {
+      params: schema.object({
+        case_id: schema.string(),
+      }),
+    },
+    options: {
+      deprecated: true,
+    },
+    routerOptions: {
+      access: isServerless ? 'internal' : 'public',
+      summary: `Gets all case comments`,
+      tags: ['oas-tag:cases'],
+      // description: 'You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you\'re seeking.',
+      // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
+      deprecated: true,
+    },
+    handler: async ({ context, request, response }) => {
+      try {
+        const caseContext = await context.cases;
+        const client = await caseContext.getCasesClient();
+        const res: attachmentDomainV1.Attachments = await client.attachments.getAll({
+          caseID: request.params.case_id,
+        });
 
-      return response.ok({
-        body: res,
-      });
-    } catch (error) {
-      throw createCaseError({
-        message: `Failed to get all comments in route case id: ${request.params.case_id}: ${error}`,
-        error,
-      });
-    }
-  },
-});
+        return response.ok({
+          body: res,
+        });
+      } catch (error) {
+        throw createCaseError({
+          message: `Failed to get all comments in route case id: ${request.params.case_id}: ${error}`,
+          error,
+        });
+      }
+    },
+  });
diff --git a/x-pack/plugins/cases/server/routes/api/get_external_routes.ts b/x-pack/plugins/cases/server/routes/api/get_external_routes.ts
index bd990deefbdfa..4412d0b695079 100644
--- a/x-pack/plugins/cases/server/routes/api/get_external_routes.ts
+++ b/x-pack/plugins/cases/server/routes/api/get_external_routes.ts
@@ -31,18 +31,18 @@ import { postCaseConfigureRoute } from './configure/post_configure';
 import { getAllAlertsAttachedToCaseRoute } from './comments/get_alerts';
 import { findUserActionsRoute } from './user_actions/find_user_actions';
 
-export const getExternalRoutes = () =>
+export const getExternalRoutes = ({ isServerless }: { isServerless?: boolean }) =>
   [
     deleteCaseRoute,
     findCaseRoute,
-    getCaseRoute,
+    getCaseRoute({ isServerless }),
     resolveCaseRoute,
     patchCaseRoute,
     postCaseRoute,
     pushCaseRoute,
     findUserActionsRoute,
-    getUserActionsRoute,
-    getStatusRoute,
+    getUserActionsRoute({ isServerless }),
+    getStatusRoute({ isServerless }),
     getCasesByAlertIdRoute,
     getReportersRoute,
     getTagsRoute,
@@ -50,7 +50,7 @@ export const getExternalRoutes = () =>
     deleteAllCommentsRoute,
     findCommentsRoute,
     getCommentRoute,
-    getAllCommentsRoute,
+    getAllCommentsRoute({ isServerless }),
     patchCommentRoute,
     postCommentRoute,
     getCaseConfigureRoute,
diff --git a/x-pack/plugins/cases/server/routes/api/stats/get_status.test.ts b/x-pack/plugins/cases/server/routes/api/stats/get_status.test.ts
new file mode 100644
index 0000000000000..9376a46b76808
--- /dev/null
+++ b/x-pack/plugins/cases/server/routes/api/stats/get_status.test.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getStatusRoute } from './get_status';
+
+describe('getStatusRoute', () => {
+  it('marks the endpoint internal in serverless', async () => {
+    const router = getStatusRoute({ isServerless: true });
+
+    expect(router.routerOptions?.access).toBe('internal');
+  });
+
+  it('marks the endpoint public in non-serverless', async () => {
+    const router = getStatusRoute({ isServerless: false });
+
+    expect(router.routerOptions?.access).toBe('public');
+  });
+});
diff --git a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts
index dce369e4a0f45..0889644f6a80a 100644
--- a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts
+++ b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts
@@ -15,37 +15,38 @@ import type { statsApiV1 } from '../../../../common/types/api';
 /**
  * @deprecated since version 8.1.0
  */
-export const getStatusRoute: CaseRoute = createCasesRoute({
-  method: 'get',
-  path: CASE_STATUS_URL,
-  options: { deprecated: true },
-  routerOptions: {
-    access: 'public',
-    summary: `Get case status summary`,
-    tags: ['oas-tag:cases'],
-    description:
-      'Returns the number of cases that are open, closed, and in progress in the default space.',
-    // You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.
-    // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
-    deprecated: true,
-  },
-  handler: async ({ context, request, response }) => {
-    try {
-      const caseContext = await context.cases;
-      const client = await caseContext.getCasesClient();
+export const getStatusRoute = ({ isServerless }: { isServerless?: boolean }): CaseRoute =>
+  createCasesRoute({
+    method: 'get',
+    path: CASE_STATUS_URL,
+    options: { deprecated: true },
+    routerOptions: {
+      access: isServerless ? 'internal' : 'public',
+      summary: `Get case status summary`,
+      tags: ['oas-tag:cases'],
+      description:
+        'Returns the number of cases that are open, closed, and in progress in the default space.',
+      // You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.
+      // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
+      deprecated: true,
+    },
+    handler: async ({ context, request, response }) => {
+      try {
+        const caseContext = await context.cases;
+        const client = await caseContext.getCasesClient();
 
-      const res: statsApiV1.CasesStatusResponse = await client.metrics.getStatusTotalsByType(
-        request.query as statsApiV1.CasesStatusRequest
-      );
+        const res: statsApiV1.CasesStatusResponse = await client.metrics.getStatusTotalsByType(
+          request.query as statsApiV1.CasesStatusRequest
+        );
 
-      return response.ok({
-        body: res,
-      });
-    } catch (error) {
-      throw createCaseError({
-        message: `Failed to get status stats in route: ${error}`,
-        error,
-      });
-    }
-  },
-});
+        return response.ok({
+          body: res,
+        });
+      } catch (error) {
+        throw createCaseError({
+          message: `Failed to get status stats in route: ${error}`,
+          error,
+        });
+      }
+    },
+  });
diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.test.ts b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.test.ts
new file mode 100644
index 0000000000000..d99b90c29bbb4
--- /dev/null
+++ b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.test.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getUserActionsRoute } from './get_all_user_actions';
+
+describe('getUserActionsRoute', () => {
+  it('marks the endpoint internal in serverless', async () => {
+    const router = getUserActionsRoute({ isServerless: true });
+
+    expect(router.routerOptions?.access).toBe('internal');
+  });
+
+  it('marks the endpoint public in non-serverless', async () => {
+    const router = getUserActionsRoute({ isServerless: false });
+
+    expect(router.routerOptions?.access).toBe('public');
+  });
+});
diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts
index 17fe0dcdb9012..19d7f1f8956ac 100644
--- a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts
+++ b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts
@@ -15,41 +15,42 @@ import { createCasesRoute } from '../create_cases_route';
 /**
  * @deprecated since version 8.1.0
  */
-export const getUserActionsRoute = createCasesRoute({
-  method: 'get',
-  path: CASE_USER_ACTIONS_URL,
-  params: {
-    params: schema.object({
-      case_id: schema.string(),
-    }),
-  },
-  options: { deprecated: true },
-  routerOptions: {
-    access: 'public',
-    summary: 'Get case activity',
-    description: `Returns all user activity for a case.`,
-    // You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.
-    tags: ['oas-tag:cases'],
-    // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
-    deprecated: true,
-  },
-  handler: async ({ context, request, response }) => {
-    try {
-      const caseContext = await context.cases;
-      const casesClient = await caseContext.getCasesClient();
-      const caseId = request.params.case_id;
+export const getUserActionsRoute = ({ isServerless }: { isServerless?: boolean }) =>
+  createCasesRoute({
+    method: 'get',
+    path: CASE_USER_ACTIONS_URL,
+    params: {
+      params: schema.object({
+        case_id: schema.string(),
+      }),
+    },
+    options: { deprecated: true },
+    routerOptions: {
+      access: isServerless ? 'internal' : 'public',
+      summary: 'Get case activity',
+      description: `Returns all user activity for a case.`,
+      // You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.
+      tags: ['oas-tag:cases'],
+      // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
+      deprecated: true,
+    },
+    handler: async ({ context, request, response }) => {
+      try {
+        const caseContext = await context.cases;
+        const casesClient = await caseContext.getCasesClient();
+        const caseId = request.params.case_id;
 
-      const res: userActionApiV1.CaseUserActionsDeprecatedResponse =
-        await casesClient.userActions.getAll({ caseId });
+        const res: userActionApiV1.CaseUserActionsDeprecatedResponse =
+          await casesClient.userActions.getAll({ caseId });
 
-      return response.ok({
-        body: res,
-      });
-    } catch (error) {
-      throw createCaseError({
-        message: `Failed to retrieve case user actions in route case id: ${request.params.case_id}: ${error}`,
-        error,
-      });
-    }
-  },
-});
+        return response.ok({
+          body: res,
+        });
+      } catch (error) {
+        throw createCaseError({
+          message: `Failed to retrieve case user actions in route case id: ${request.params.case_id}: ${error}`,
+          error,
+        });
+      }
+    },
+  });
diff --git a/x-pack/test/cases_api_integration/common/lib/api/index.ts b/x-pack/test/cases_api_integration/common/lib/api/index.ts
index ea0f66affdc35..59d91a388f6ea 100644
--- a/x-pack/test/cases_api_integration/common/lib/api/index.ts
+++ b/x-pack/test/cases_api_integration/common/lib/api/index.ts
@@ -460,7 +460,7 @@ export const getAllCasesStatuses = async ({
 export const getCase = async ({
   supertest,
   caseId,
-  includeComments = false,
+  includeComments,
   expectedHttpCode = 200,
   auth = { user: superUser, space: null },
 }: {
@@ -470,10 +470,12 @@ export const getCase = async ({
   expectedHttpCode?: number;
   auth?: { user: User; space: string | null };
 }): Promise<Case> => {
+  const basePath = `${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}`;
+  const path =
+    includeComments != null ? `${basePath}?includeComments=${includeComments}` : basePath;
+
   const { body: theCase } = await supertest
-    .get(
-      `${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}?includeComments=${includeComments}`
-    )
+    .get(path)
     .set('kbn-xsrf', 'true')
     .set('x-elastic-internal-origin', 'foo')
     .auth(auth.user.username, auth.user.password)
diff --git a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts
index c01365861c2d3..6886c894c1110 100644
--- a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts
+++ b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts
@@ -159,22 +159,22 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) {
       {
         caseId,
         space = 'default',
-        includeComments = false,
         expectedHttpCode = 200,
+        includeComments,
       }: {
         caseId: string;
         space?: string;
-        includeComments?: boolean;
         expectedHttpCode?: number;
+        includeComments?: boolean;
       },
       roleAuthc: RoleCredentials
     ): Promise<Case> {
+      const basePath = `${this.getSpaceUrlPrefix(space)}${CASES_URL}/${caseId}`;
+      const path =
+        includeComments != null ? `${basePath}?includeComments=${includeComments}` : basePath;
+
       const { body: theCase } = await supertestWithoutAuth
-        .get(
-          `${this.getSpaceUrlPrefix(
-            space
-          )}${CASES_URL}/${caseId}?includeComments=${includeComments}`
-        )
+        .get(path)
         .set(svlCommonApi.getInternalRequestHeader())
         .set(roleAuthc.apiKeyHeader)
         .expect(expectedHttpCode);
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_comments.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_comments.ts
new file mode 100644
index 0000000000000..5672b084d465c
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_comments.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CASE_COMMENTS_URL } from '@kbn/cases-plugin/common/constants';
+import type { RoleCredentials } from '../../../../shared/services';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default ({ getService }: FtrProviderContext): void => {
+  const svlCases = getService('svlCases');
+  const svlUserManager = getService('svlUserManager');
+  const supertestWithoutAuth = getService('supertestWithoutAuth');
+  const svlCommonApi = getService('svlCommonApi');
+
+  describe('get_all_comments', () => {
+    let roleAuthc: RoleCredentials;
+
+    before(async () => {
+      roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
+    });
+
+    after(async () => {
+      await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
+    });
+
+    afterEach(async () => {
+      await svlCases.api.deleteCases();
+    });
+
+    it('should fetch the status correctly with internal request headers', async () => {
+      await supertestWithoutAuth
+        .get(CASE_COMMENTS_URL)
+        .set(svlCommonApi.getInternalRequestHeader())
+        .set(roleAuthc.apiKeyHeader)
+        .expect(200);
+    });
+
+    it('should not fetch the status correctly with no internal request headers', async () => {
+      await supertestWithoutAuth.get(CASE_COMMENTS_URL).set(roleAuthc.apiKeyHeader).expect(400);
+    });
+  });
+};
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_user_actions.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_user_actions.ts
new file mode 100644
index 0000000000000..54221f23256c6
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_all_user_actions.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CASE_USER_ACTIONS_URL } from '@kbn/cases-plugin/common/constants';
+import type { RoleCredentials } from '../../../../shared/services';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default ({ getService }: FtrProviderContext): void => {
+  const svlCases = getService('svlCases');
+  const svlUserManager = getService('svlUserManager');
+  const supertestWithoutAuth = getService('supertestWithoutAuth');
+  const svlCommonApi = getService('svlCommonApi');
+
+  describe('get_all_user_actions', () => {
+    let roleAuthc: RoleCredentials;
+
+    before(async () => {
+      roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
+    });
+
+    after(async () => {
+      await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
+    });
+
+    afterEach(async () => {
+      await svlCases.api.deleteCases();
+    });
+
+    it('should fetch the status correctly with internal request headers', async () => {
+      await supertestWithoutAuth
+        .get(CASE_USER_ACTIONS_URL)
+        .set(svlCommonApi.getInternalRequestHeader())
+        .set(roleAuthc.apiKeyHeader)
+        .expect(200);
+    });
+
+    it('should not fetch the status correctly with no internal request headers', async () => {
+      await supertestWithoutAuth.get(CASE_USER_ACTIONS_URL).set(roleAuthc.apiKeyHeader).expect(400);
+    });
+  });
+};
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts
index 8b1cb4a2561fe..5e38b9153f611 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts
@@ -36,7 +36,7 @@ export default ({ getService }: FtrProviderContext): void => {
       const theCase = await svlCases.api.getCase(
         {
           caseId: postedCase.id,
-          includeComments: true,
+          expectedHttpCode: 200,
         },
         roleAuthc
       );
@@ -47,7 +47,22 @@ export default ({ getService }: FtrProviderContext): void => {
 
       expect(data).to.eql(expectedData);
       expect(createdBy).to.have.keys('full_name', 'email', 'username');
-      expect(data.comments?.length).to.eql(0);
+    });
+
+    it('should throw a 400 if the query param includeComments is being used', async () => {
+      const postedCase = await svlCases.api.createCase(
+        svlCases.api.getPostCaseRequest('observability'),
+        roleAuthc
+      );
+
+      await svlCases.api.getCase(
+        {
+          caseId: postedCase.id,
+          includeComments: true,
+          expectedHttpCode: 400,
+        },
+        roleAuthc
+      );
     });
   });
 };
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_status.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_status.ts
new file mode 100644
index 0000000000000..39527cb12f4ba
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_status.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CASE_STATUS_URL } from '@kbn/cases-plugin/common/constants';
+import type { RoleCredentials } from '../../../../shared/services';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default ({ getService }: FtrProviderContext): void => {
+  const svlCases = getService('svlCases');
+  const svlUserManager = getService('svlUserManager');
+  const supertestWithoutAuth = getService('supertestWithoutAuth');
+  const svlCommonApi = getService('svlCommonApi');
+
+  describe('get_status', () => {
+    let roleAuthc: RoleCredentials;
+
+    before(async () => {
+      roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin');
+    });
+
+    after(async () => {
+      await svlUserManager.invalidateM2mApiKeyWithRoleScope(roleAuthc);
+    });
+
+    afterEach(async () => {
+      await svlCases.api.deleteCases();
+    });
+
+    it('should fetch the status correctly with internal request headers', async () => {
+      await supertestWithoutAuth
+        .get(CASE_STATUS_URL)
+        .set(svlCommonApi.getInternalRequestHeader())
+        .set(roleAuthc.apiKeyHeader)
+        .expect(200);
+    });
+
+    it('should not fetch the status correctly with no internal request headers', async () => {
+      await supertestWithoutAuth.get(CASE_STATUS_URL).set(roleAuthc.apiKeyHeader).expect(400);
+    });
+  });
+};
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
index 97e56b4220124..8a4ba7258b04d 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
@@ -12,5 +12,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
     loadTestFile(require.resolve('./get_case'));
     loadTestFile(require.resolve('./find_cases'));
     loadTestFile(require.resolve('./post_case'));
+    loadTestFile(require.resolve('./get_status'));
+    loadTestFile(require.resolve('./get_all_comments'));
+    loadTestFile(require.resolve('./get_all_user_actions'));
   });
 }
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts
index 6886ade38ad78..052a1f9bf9d3a 100644
--- a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts
@@ -31,7 +31,7 @@ export default ({ getService }: FtrProviderContext): void => {
       const theCase = await svlCases.api.getCase(
         {
           caseId: postedCase.id,
-          includeComments: true,
+          expectedHttpCode: 200,
         },
         roleAuthc
       );
@@ -41,7 +41,22 @@ export default ({ getService }: FtrProviderContext): void => {
       const { created_by: _, ...expectedData } = svlCases.api.postCaseResp('securitySolution');
       expect(data).to.eql(expectedData);
       expect(createdBy).to.have.keys('full_name', 'email', 'username');
-      expect(data.comments?.length).to.eql(0);
+    });
+
+    it('should throw a 400 if the query param includeComments is being used', async () => {
+      const postedCase = await svlCases.api.createCase(
+        svlCases.api.getPostCaseRequest('securitySolution'),
+        roleAuthc
+      );
+
+      await svlCases.api.getCase(
+        {
+          caseId: postedCase.id,
+          includeComments: true,
+          expectedHttpCode: 400,
+        },
+        roleAuthc
+      );
     });
   });
 };