Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .buildkite/ftr_security_serverless_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ disabled:
defaultQueue: 'n2-4-spot'
enabled:
- x-pack/solutions/security/test/serverless/api_integration/configs/config.ts
- x-pack/solutions/security/test/serverless/api_integration/configs/config.graph.ts
- x-pack/solutions/security/test/serverless/api_integration/configs/config.graph_essentials.ts
- x-pack/platform/test/serverless/api_integration/configs/security/config.group1.ts
- x-pack/solutions/security/test/serverless/api_integration/test_suites/fleet/config.ts
- x-pack/solutions/security/test/serverless/functional/configs/config.screenshots.ts
Expand Down
1 change: 1 addition & 0 deletions .buildkite/ftr_security_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ enabled:
- x-pack/solutions/security/test/security_solution_endpoint/configs/integrations.config.ts
- x-pack/solutions/security/test/api_integration/apis/cloud_security_posture/config.ts
- x-pack/solutions/security/test/cloud_security_posture_api/config.ts
- x-pack/solutions/security/test/cloud_security_posture_api/config.graph_basic.ts
- x-pack/solutions/security/test/cloud_security_posture_functional/config.ts
- x-pack/solutions/security/test/cloud_security_posture_functional/config.agentless.ts
- x-pack/solutions/security/test/cloud_security_posture_functional/data_views/config.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ export default createTestConfig({
'--xpack.dataUsage.autoops.api.url=http://localhost:9000',
`--xpack.dataUsage.autoops.api.tls.certificate=${KBN_CERT_PATH}`,
`--xpack.dataUsage.autoops.api.tls.key=${KBN_KEY_PATH}`,
// Enables /internal/cloud_security_posture/graph API
`--uiSettings.overrides.securitySolution:enableGraphVisualization=true`,
],
enableFleetDockerRegistry: false,
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '@kbn/cloud-security-posture-common/schema/graph/latest';
import { transformError } from '@kbn/securitysolution-es-utils';
import type { GraphRequest } from '@kbn/cloud-security-posture-common/types/graph/v1';
import { SECURITY_SOLUTION_ENABLE_GRAPH_VISUALIZATION_SETTING } from '@kbn/management-settings-ids';
import { GRAPH_ROUTE_PATH } from '../../../common/constants';
import type { CspRequestHandlerContext, CspRouter } from '../../types';
import { getGraph as getGraphV1 } from './v1';
Expand All @@ -22,6 +21,9 @@ export const defineGraphRoute = (router: CspRouter) =>
access: 'internal',
enableQueryVersion: true,
path: GRAPH_ROUTE_PATH,
options: {
tags: ['securitySolutionProductFeature:graph_visualization'],
},
security: {
authz: {
requiredPrivileges: ['cloud-security-posture-read'],
Expand All @@ -46,14 +48,12 @@ export const defineGraphRoute = (router: CspRouter) =>
const { originEventIds, start, end, indexPatterns, esQuery, entityIds, pinnedIds } = request
.body.query as GraphRequest['query'];
const spaceId = await cspContext.spacesService?.getSpaceId(request);
const isGraphEnabled = await (
await context.core
).uiSettings.client.get(SECURITY_SOLUTION_ENABLE_GRAPH_VISUALIZATION_SETTING);

cspContext.logger.debug(`isGraphEnabled: ${isGraphEnabled} for space: ${spaceId}`);

if (!isGraphEnabled) {
return response.notFound();
const { license } = await context.licensing;
if (!license.hasAtLeast('platinum')) {
return response.forbidden({
body: { message: 'Graph visualization requires a Platinum license or higher.' },
});
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type { CspStatusCode, IndexDetails } from '@kbn/cloud-security-posture-co
import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server';
import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server';
import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server';
import type { AlertingPluginSetup } from '@kbn/alerting-plugin/public/plugin';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/server';

Expand Down Expand Up @@ -89,6 +90,7 @@ export type CspRequestHandlerContext = CustomRequestHandlerContext<{
csp: CspApiRequestHandlerContext;
fleet: FleetRequestHandlerContext['fleet'];
alerting: AlertingApiRequestHandlerContext;
licensing: LicensingApiRequestHandlerContext;
core: Promise<CoreRequestHandlerContext>;
}>;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 { resolve } from 'path';
import { getKibanaCliLoggers, type FtrConfigProviderContext } from '@kbn/test';
import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-common';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xPackAPITestsConfig = await readConfigFile(
require.resolve('@kbn/test-suites-xpack-platform/api_integration/config')
);

return {
...xPackAPITestsConfig.getAll(),
testFiles: [resolve(__dirname, './routes/graph_basic')],
junit: {
reportName: 'X-Pack Cloud Security Posture API Tests - Graph Basic License',
},
esTestCluster: {
...xPackAPITestsConfig.get('esTestCluster'),
license: 'basic',
serverArgs: [
...xPackAPITestsConfig.get('esTestCluster.serverArgs'),
'xpack.license.self_generated.type=basic',
],
},
kbnTestServer: {
...xPackAPITestsConfig.get('kbnTestServer'),
serverArgs: [
...xPackAPITestsConfig.get('kbnTestServer.serverArgs'),
`--logging.loggers=${JSON.stringify([
...getKibanaCliLoggers(xPackAPITestsConfig.get('kbnTestServer.serverArgs')),
{
name: 'plugins.cloudSecurityPosture',
level: 'all',
appenders: ['default'],
},
])}`,
`--xpack.fleet.packages.0.name=cloud_security_posture`,
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
],
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
`--xpack.fleet.packages.0.name=cloud_security_posture`,
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
// `--xpack.fleet.registryUrl=https://localhost:8080`,
// Enables /internal/cloud_security_posture/graph API
`--uiSettings.overrides.securitySolution:enableGraphVisualization=true`,
],
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 {
ELASTIC_HTTP_VERSION_HEADER,
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
} from '@kbn/core-http-common';
import type { Agent } from 'supertest';
import type { GraphRequest } from '@kbn/cloud-security-posture-common/types/graph/v1';
import type { FtrProviderContext } from '../ftr_provider_context';
import { result } from '../utils';

// eslint-disable-next-line import/no-default-export
export default function graphBasicTests({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const logger = getService('log');

const postGraph = (agent: Agent, body: GraphRequest) => {
return agent
.post('/internal/cloud_security_posture/graph')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.set('kbn-xsrf', 'xxxx')
.send(body);
};

describe('POST /internal/cloud_security_posture/graph - Basic license', () => {
it('should return 403 when license is below platinum', async () => {
await postGraph(supertest, {
query: {
originEventIds: [],
start: 'now-1d/d',
end: 'now/d',
},
}).expect(result(403, logger));
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils';
import { createTestConfig } from '@kbn/test-suites-xpack-platform/serverless/api_integration/config.base';

export default createTestConfig({
serverlessProject: 'security',
testFiles: [require.resolve('../test_suites/cloud_security_posture/graph')],
junit: {
reportName: 'Serverless Security API Integration Tests - Graph Complete Tier',
},
suiteTags: { exclude: ['skipSvlSec'] },
kbnServerArgs: [
`--xpack.task_manager.unsafe.exclude_task_types=${JSON.stringify(['Fleet-Metrics-Task'])}`,
'--coreApp.allowDynamicConfigOverrides=true',
`--xpack.securitySolutionServerless.cloudSecurityUsageReportingTaskInterval=5s`,
`--xpack.securitySolutionServerless.usageApi.url=http://localhost:8081`,
'--xpack.dataUsage.enabled=true',
'--xpack.dataUsage.enableExperimental=[]',
'--xpack.dataUsage.autoops.enabled=true',
'--xpack.dataUsage.autoops.api.url=http://localhost:9000',
`--xpack.dataUsage.autoops.api.tls.certificate=${KBN_CERT_PATH}`,
`--xpack.dataUsage.autoops.api.tls.key=${KBN_KEY_PATH}`,
// Complete tier enables graph visualization product feature
`--xpack.securitySolutionServerless.productTypes=${JSON.stringify([
{ product_line: 'security', product_tier: 'complete' },
{ product_line: 'endpoint', product_tier: 'complete' },
{ product_line: 'cloud', product_tier: 'complete' },
])}`,
],
enableFleetDockerRegistry: false,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { createTestConfig } from '@kbn/test-suites-xpack-platform/serverless/api_integration/config.base';

export default createTestConfig({
serverlessProject: 'security',
testFiles: [require.resolve('../test_suites/cloud_security_posture/graph.essentials')],
junit: {
reportName: 'Serverless Security API Integration Tests - Graph Essentials Tier',
},
suiteTags: { exclude: ['skipSvlSec'] },
kbnServerArgs: [
// Essentials tier does NOT include graph visualization product feature
`--xpack.securitySolutionServerless.productTypes=${JSON.stringify([
{ product_line: 'security', product_tier: 'essentials' },
{ product_line: 'endpoint', product_tier: 'essentials' },
{ product_line: 'cloud', product_tier: 'essentials' },
])}`,
],
enableFleetDockerRegistry: false,
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ export default createTestConfig({
'--xpack.dataUsage.autoops.api.url=http://localhost:9000',
`--xpack.dataUsage.autoops.api.tls.certificate=${KBN_CERT_PATH}`,
`--xpack.dataUsage.autoops.api.tls.key=${KBN_KEY_PATH}`,
// Enables /internal/cloud_security_posture/graph API
`--uiSettings.overrides.securitySolution:enableGraphVisualization=true`,
// Complete tier enables graph visualization product feature
`--xpack.securitySolutionServerless.productTypes=${JSON.stringify([
{ product_line: 'security', product_tier: 'complete' },
{ product_line: 'endpoint', product_tier: 'complete' },
{ product_line: 'cloud', product_tier: 'complete' },
])}`,
],
enableFleetDockerRegistry: false,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 {
ELASTIC_HTTP_VERSION_HEADER,
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
} from '@kbn/core-http-common';
import type { Agent } from 'supertest';
import type { GraphRequest } from '@kbn/cloud-security-posture-common/types/graph/v1';
import { result } from './utils';
import type { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getService }: FtrProviderContext) {
const roleScopedSupertest = getService('roleScopedSupertest');
let supertestViewer: Pick<Agent, 'post'>;

const postGraph = (agent: Pick<Agent, 'post'>, body: GraphRequest) => {
const req = agent
.post('/internal/cloud_security_posture/graph')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.set('kbn-xsrf', 'xxxx');

return req.send(body);
};

describe('POST /internal/cloud_security_posture/graph - Essentials tier', function () {
// see details: https://github.com/elastic/kibana/issues/208903
this.tags(['failsOnMKI']);
before(async () => {
supertestViewer = await roleScopedSupertest.getSupertestWithRoleScope('viewer', {
useCookieHeader: true,
withInternalHeaders: true,
});
});

it('should return 404 because graph visualization is not available in essentials tier', async () => {
await postGraph(supertestViewer, {
query: {
originEventIds: [],
start: 'now-1d/d',
end: 'now/d',
},
}).expect(result(404));
});
});
}
Loading