Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Serverless][Security Solution][Endpoint] Restrict endpoint exceptions on serverless via plugin sub-features #164107

Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
e41200e
poc
semd Aug 11, 2023
54b4b6a
Merge remote-tracking branch 'upstream/main' into poc/extract_kibana_…
semd Aug 11, 2023
70c0ac6
some fixes
semd Aug 12, 2023
86ac364
fix capability name
semd Aug 12, 2023
aefb49c
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Aug 12, 2023
779a41b
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Aug 12, 2023
89c8f9d
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Aug 12, 2023
011f919
Merge remote-tracking branch 'upstream/main' into poc/extract_kibana_…
YulNaumenko Aug 15, 2023
e5aa367
gate endpoint exceptions for non-endpoint PLIs
ashokaditya Aug 16, 2023
6995d6e
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 17, 2023
d55b9c8
fix tests
ashokaditya Aug 17, 2023
ced8b80
Merge branch 'task/dw-serverless-endpoint-exceptions-pli-with-plugin-…
ashokaditya Aug 17, 2023
c57a3ce
fix test
ashokaditya Aug 17, 2023
d6c32e9
fix imports
ashokaditya Aug 17, 2023
c454c0f
fix test
ashokaditya Aug 17, 2023
44f0f62
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Aug 17, 2023
966ab0c
Merge remote-tracking branch 'upstream/main' into task/dw-serverless-…
YulNaumenko Aug 21, 2023
a8c0e50
Fixed tests and added security assistant
YulNaumenko Aug 21, 2023
81bedeb
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Aug 21, 2023
b3f853b
fix missing configurator error
ashokaditya Aug 21, 2023
e4b3d6c
fix type check
ashokaditya Aug 21, 2023
4c844c9
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 21, 2023
186df52
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
YulNaumenko Aug 22, 2023
db955bd
changed rules links capabilities to default
YulNaumenko Aug 22, 2023
16e8a34
fix type error
ashokaditya Aug 22, 2023
0c72a02
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Aug 22, 2023
8ca4ccf
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 22, 2023
e8e1cdc
fix
ashokaditya Aug 22, 2023
211f58b
revert type changes for now
ashokaditya Aug 22, 2023
1562d5c
remove redundant package inclusion
ashokaditya Aug 22, 2023
df5a06a
Merge remote-tracking branch 'upstream/main' into task/dw-serverless-…
YulNaumenko Aug 23, 2023
ea18c84
fixed unit tests and type check
YulNaumenko Aug 23, 2023
5a7d3ae
updated limits
YulNaumenko Aug 23, 2023
1efedad
fixed unit test server
YulNaumenko Aug 23, 2023
160742c
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
YulNaumenko Aug 23, 2023
06ed066
fix test
ashokaditya Aug 23, 2023
761f291
Cleanup - Delete old app_features folder
machadoum Aug 23, 2023
5a6b3ec
Cleanup - Delete rule test sample code
machadoum Aug 23, 2023
ec4287f
fix type
ashokaditya Aug 23, 2023
157fe3b
cleanup unused ts directives
ashokaditya Aug 23, 2023
3dd8ea7
fix
ashokaditya Aug 23, 2023
3699dcb
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 23, 2023
1a48700
rename
ashokaditya Aug 24, 2023
47412a8
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 25, 2023
944743c
cleanup
ashokaditya Aug 25, 2023
d2196bd
fix manage_list cypress test
ashokaditya Aug 25, 2023
97d4dee
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
YulNaumenko Aug 26, 2023
d616d13
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
machadoum Aug 28, 2023
e2c9ebc
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 28, 2023
5b08c02
small improvements
semd Aug 28, 2023
21e8f77
Fix manage_lists cypress test
machadoum Aug 28, 2023
48d6d2e
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
kibanamachine Aug 28, 2023
79e19a5
app features configs relocation to package
semd Aug 28, 2023
43f4c1d
fix mock
semd Aug 28, 2023
619266f
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Aug 28, 2023
ebf07ff
translations
semd Aug 28, 2023
94d31c4
fix circular dependency
semd Aug 28, 2023
594d65d
Merge remote-tracking branch 'upstream/main' into task/dw-serverless-…
semd Aug 28, 2023
5c93286
split package exports for optimization
semd Aug 28, 2023
4119d61
distinguish type from enum and fix imports
ashokaditya Aug 29, 2023
abdf0e9
remove unused param
ashokaditya Aug 29, 2023
e246ddc
fix missing arguments in `register upselling` test
ashokaditya Aug 29, 2023
cc2c630
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 29, 2023
f058869
Merge branch 'main' into task/dw-serverless-endpoint-exceptions-pli-w…
ashokaditya Aug 29, 2023
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ module.exports = {
overrides: [
{
files: [
'x-pack/packages/security-solution/features/**/*.{js,mjs,ts,tsx}',
'x-pack/packages/security-solution/navigation/**/*.{js,mjs,ts,tsx}',
'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}',
'x-pack/plugins/security_solution_ess/**/*.{js,mjs,ts,tsx}',
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ x-pack/plugins/searchprofiler @elastic/platform-deployment-management
x-pack/test/security_api_integration/packages/helpers @elastic/kibana-security
x-pack/plugins/security @elastic/kibana-security
x-pack/plugins/security_solution_ess @elastic/security-solution
x-pack/packages/security-solution/features @elastic/security-threat-hunting-explore
x-pack/test/cases_api_integration/common/plugins/security_solution @elastic/response-ops
x-pack/packages/security-solution/navigation @elastic/security-threat-hunting-explore
x-pack/plugins/security_solution @elastic/security-solution
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@
"@kbn/searchprofiler-plugin": "link:x-pack/plugins/searchprofiler",
"@kbn/security-plugin": "link:x-pack/plugins/security",
"@kbn/security-solution-ess": "link:x-pack/plugins/security_solution_ess",
"@kbn/security-solution-features": "link:x-pack/packages/security-solution/features",
"@kbn/security-solution-fixtures-plugin": "link:x-pack/test/cases_api_integration/common/plugins/security_solution",
"@kbn/security-solution-navigation": "link:x-pack/packages/security-solution/navigation",
"@kbn/security-solution-plugin": "link:x-pack/plugins/security_solution",
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pageLoadAssetSize:
security: 81771
securitySolution: 66738
securitySolutionEss: 16573
securitySolutionServerless: 40000
securitySolutionServerless: 45000
serverless: 16573
serverlessObservability: 68747
serverlessSearch: 71995
Expand Down
20 changes: 20 additions & 0 deletions packages/kbn-utility-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,23 @@ export type ArrayElement<A> = A extends ReadonlyArray<infer T> ? T : never;
export type WithRequiredProperty<Type, Key extends keyof Type> = Omit<Type, Key> & {
[Property in Key]-?: Type[Property];
};

// Recursive partial object type. inspired by EUI RecursivePartial
export type RecursivePartial<T> = {
[P in keyof T]?: T[P] extends NonAny[]
? T[P]
: T[P] extends readonly NonAny[]
? T[P]
: T[P] extends Array<infer U>
? Array<RecursivePartial<U>>
: T[P] extends ReadonlyArray<infer U>
? ReadonlyArray<RecursivePartial<U>>
: T[P] extends Set<infer V>
? Set<RecursivePartial<V>>
: T[P] extends Map<infer K, infer V>
? Map<K, RecursivePartial<V>>
: T[P] extends NonAny
? T[P]
: RecursivePartial<T[P]>;
};
type NonAny = number | boolean | string | symbol | null;
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,8 @@
"@kbn/security-plugin/*": ["x-pack/plugins/security/*"],
"@kbn/security-solution-ess": ["x-pack/plugins/security_solution_ess"],
"@kbn/security-solution-ess/*": ["x-pack/plugins/security_solution_ess/*"],
"@kbn/security-solution-features": ["x-pack/packages/security-solution/features"],
"@kbn/security-solution-features/*": ["x-pack/packages/security-solution/features/*"],
"@kbn/security-solution-fixtures-plugin": ["x-pack/test/cases_api_integration/common/plugins/security_solution"],
"@kbn/security-solution-fixtures-plugin/*": ["x-pack/test/cases_api_integration/common/plugins/security_solution/*"],
"@kbn/security-solution-navigation": ["x-pack/packages/security-solution/navigation"],
Expand Down
4 changes: 4 additions & 0 deletions x-pack/packages/security-solution/features/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Security Solution App Features

This package provides resources to be used for Security Solution app features

10 changes: 10 additions & 0 deletions x-pack/packages/security-solution/features/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/
export { AppFeatures } from './src/app_features';
export { AppFeaturesPrivileges } from './src/app_features_privileges';
export * from './src/app_features_keys';
export * from './src/types';
12 changes: 12 additions & 0 deletions x-pack/packages/security-solution/features/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../..',
roots: ['<rootDir>/x-pack/packages/security-solution/features'],
};
5 changes: 5 additions & 0 deletions x-pack/packages/security-solution/features/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/security-solution-features",
"owner": "@elastic/security-threat-hunting-explore"
}
19 changes: 19 additions & 0 deletions x-pack/packages/security-solution/features/mocks/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 type { CoreStart } from '@kbn/core/public';

export const mockGetUrlForApp = jest.fn();
export const mockNavigateToApp = jest.fn();
export const mockNavigateToUrl = jest.fn();

export const mockCoreStart = {
application: {
getUrlForApp: mockGetUrlForApp,
navigateToApp: mockNavigateToApp,
navigateToUrl: mockNavigateToUrl,
},
} as unknown as CoreStart;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const mockGetAppUrl = jest.fn();
export const mockNavigateTo = jest.fn();
6 changes: 6 additions & 0 deletions x-pack/packages/security-solution/features/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@kbn/security-solution-features",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 React, { createContext } from 'react';
import type { CoreStart } from '@kbn/core/public';
import { mockCoreStart } from '../../mocks/context';

const navigationContext = createContext<CoreStart | null>(mockCoreStart);

export const NavigationProvider: React.FC = ({ children }) => (
<navigationContext.Provider value={mockCoreStart}>{children}</navigationContext.Provider>
);

export const useNavigationContext = (): CoreStart => {
return mockCoreStart;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { mockGetAppUrl, mockNavigateTo } from '../../mocks/navigation';

export const useGetAppUrl = jest.fn(() => {
return { getAppUrl: mockGetAppUrl };
});

export const useNavigateTo = jest.fn(() => {
return { navigateTo: mockNavigateTo };
});

export const useNavigation = jest.fn(() => {
return { navigateTo: mockGetAppUrl, getAppUrl: mockNavigateTo };
});
185 changes: 185 additions & 0 deletions x-pack/packages/security-solution/features/src/app_features.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* 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 type { PluginSetupContract } from '@kbn/features-plugin/server';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { AppFeatures } from './app_features';
import type {
AppFeatureKey,
AppFeaturesConfig,
AppSubFeaturesMap,
BaseKibanaFeatureConfig,
} from './types';

const category = {
id: 'security',
label: 'Security app category',
};

const baseKibanaFeature: BaseKibanaFeatureConfig = {
id: 'FEATURE_ID',
name: 'Base Feature',
order: 1100,
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
privileges: {
all: {
api: ['api-read', 'api-write'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['write', 'read'],
},
read: {
api: ['api-read'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['read'],
},
},
category,
};

const privileges = {
privileges: {
all: {
api: ['api-read', 'api-write', 'test-capability'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['write', 'read', 'test-capability'],
},
read: {
api: ['api-read', 'test-capability'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['read', 'test-capability'],
},
},
};

const SECURITY_APP_FEATURE_CONFIG: AppFeaturesConfig<string> = new Map();
SECURITY_APP_FEATURE_CONFIG.set('test-base-feature' as AppFeatureKey, {
privileges: {
all: {
ui: ['test-capability'],
api: ['test-capability'],
},
read: {
ui: ['test-capability'],
api: ['test-capability'],
},
},
});

const CASES_BASE_CONFIG = {
privileges: {
all: {
api: ['api-read', 'api-write', 'test-cases-capability'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['write', 'read', 'test-cases-capability'],
},
read: {
api: ['api-read', 'test-cases-capability'],
app: ['FEATURE_ID', 'kibana'],
catalogue: ['APP_ID'],
savedObject: {
all: [],
read: [],
},
ui: ['read', 'test-cases-capability'],
},
},
};

const CASES_APP_FEATURE_CONFIG: AppFeaturesConfig<string> = new Map();
CASES_APP_FEATURE_CONFIG.set('test-cases-feature' as AppFeatureKey, {
privileges: {
all: {
ui: ['test-cases-capability'],
api: ['test-cases-capability'],
},
read: {
ui: ['test-cases-capability'],
api: ['test-cases-capability'],
},
},
});

const securityKibanaSubFeatures = {
securitySubFeaturesMap: new Map([['subFeature1', { baz: 'baz' }]]),
};

const securityCasesKibanaSubFeatures = {
casesSubFeaturesMap: new Map([['subFeature1', { baz: 'baz' }]]),
};

describe('AppFeatures', () => {
it('should register enabled kibana features', () => {
const featuresSetup = {
registerKibanaFeature: jest.fn(),
getKibanaFeatures: jest.fn(),
} as unknown as PluginSetupContract;

const appFeatures = new AppFeatures(
loggingSystemMock.create().get('mock'),
securityKibanaSubFeatures.securitySubFeaturesMap as unknown as AppSubFeaturesMap<string>,
baseKibanaFeature,
['subFeature1']
);
appFeatures.init(featuresSetup);
appFeatures.setConfig(SECURITY_APP_FEATURE_CONFIG);

expect(featuresSetup.registerKibanaFeature).toHaveBeenCalledWith({
...baseKibanaFeature,
...SECURITY_APP_FEATURE_CONFIG.get('test-base-feature' as AppFeatureKey),
...privileges,
subFeatures: [{ baz: 'baz' }],
});
});

it('should register enabled cases features', () => {
const featuresSetup = {
registerKibanaFeature: jest.fn(),
} as unknown as PluginSetupContract;

const appFeatures = new AppFeatures(
loggingSystemMock.create().get('mock'),
securityCasesKibanaSubFeatures.casesSubFeaturesMap as unknown as AppSubFeaturesMap<string>,
baseKibanaFeature,
['subFeature1']
);
appFeatures.init(featuresSetup);
appFeatures.setConfig(CASES_APP_FEATURE_CONFIG);

expect(featuresSetup.registerKibanaFeature).toHaveBeenCalledWith({
...baseKibanaFeature,
...CASES_APP_FEATURE_CONFIG.get('test-cases-feature' as AppFeatureKey),
subFeatures: [{ baz: 'baz' }],
...CASES_BASE_CONFIG,
});
});
});
Loading