Skip to content

Commit

Permalink
Custom fleet policy UX for new integration (cloud defend v1) (#147300)
Browse files Browse the repository at this point in the history
## Summary

New Kibana plugin created for an integration called "Cloud defend for
containers" which will have a corresponding agent service which can
proactively block and alert on executable creation or modification in a
running container.

This plugin is purely in place to configure the fleet policy UX around
this new integration. For now we have added a yaml editor as a custom
input to our integration. The monaco-yaml libary was added to allow
support for JSON schema validation support for yaml.

Integration PR is up, and a work in progress: (waiting on some content
for the doc page)
elastic/integrations#4680

### Screenshot


![image](https://user-images.githubusercontent.com/16198204/207160791-73e11e05-953b-42ba-b4dd-a4904bd95451.png)

### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)

Co-authored-by: Karl Godard <karlgodard@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 20, 2022
1 parent 7a6eac8 commit 0b19cfa
Show file tree
Hide file tree
Showing 34 changed files with 918 additions and 6 deletions.
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,10 @@ The plugin exposes the static DefaultEditorController class to consume.
|Static migration page where self-managed users can see text/copy about migrating to Elastic Cloud
|{kib-repo}blob/{branch}/x-pack/plugins/cloud_defend/README.md[cloudDefend]
|This plugin currently only exists to provide custom fleet policy UX for a set of new BPF LSM features. The first feature being container "drift prevention".
|{kib-repo}blob/{branch}/x-pack/plugins/cloud_integrations/cloud_experiments/README.mdx[cloudExperiments]
|The Cloud Experiments Service provides the necessary APIs to implement A/B testing scenarios, fetching the variations in configuration and reporting back metrics to track conversion rates of the experiments.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@
"moment-duration-format": "^2.3.2",
"moment-timezone": "^0.5.34",
"monaco-editor": "^0.24.0",
"monaco-yaml": "3.2.1",
"mustache": "^2.3.2",
"node-fetch": "^2.6.7",
"node-forge": "^1.3.1",
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-monaco/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ RUNTIME_DEPS = [
"@npm//antlr4ts",
"@npm//babel-loader",
"@npm//monaco-editor",
"@npm//monaco-yaml",
"@npm//raw-loader",
"@npm//rxjs",
]
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-monaco/src/monaco_imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching.js';
import 'monaco-editor/esm/vs/language/json/monaco.contribution.js';
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.js'; // Needed for basic javascript support
import 'monaco-editor/esm/vs/basic-languages/xml/xml.contribution.js'; // Needed for basic xml support
import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution'; // Needed for yaml support

export { monaco };
8 changes: 7 additions & 1 deletion packages/kbn-monaco/src/register_globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import { PainlessLang } from './painless';
import { SQLLang } from './sql';
import { monaco } from './monaco_imports';
import { ESQL_THEME_ID, ESQLLang, buildESQlTheme } from './esql';

import { registerLanguage, registerTheme } from './helpers';
import { createWorkersRegistry } from './workers_registry';

export const DEFAULT_WORKER_ID = 'default';

const Yaml = 'yaml';

const workerRegistry = createWorkersRegistry(DEFAULT_WORKER_ID);

workerRegistry.register(
Expand Down Expand Up @@ -44,6 +45,11 @@ workerRegistry.register(
async () => await import('!!raw-loader!../../target_workers/json.editor.worker.js')
);

workerRegistry.register(
Yaml,
async () => await import('!!raw-loader!../../target_workers/yaml.editor.worker.js')
);

/**
* Register languages and lexer rules
*/
Expand Down
4 changes: 3 additions & 1 deletion packages/kbn-monaco/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const getWorkerEntry = (language) => {
return 'monaco-editor/esm/vs/editor/editor.worker.js';
case 'json':
return 'monaco-editor/esm/vs/language/json/json.worker.js';
case 'yaml':
return 'monaco-yaml/lib/esm/yaml.worker.js';
default:
return path.resolve(__dirname, 'src', language, 'worker', `${language}.worker.ts`);
}
Expand Down Expand Up @@ -47,4 +49,4 @@ const getWorkerConfig = (language) => ({
},
});

module.exports = ['default', 'json', 'painless', 'xjson', 'esql'].map(getWorkerConfig);
module.exports = ['default', 'json', 'painless', 'xjson', 'esql', 'yaml'].map(getWorkerConfig);
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pageLoadAssetSize:
cloud: 21076
cloudChat: 19894
cloudDataMigration: 19170
cloudDefend: 18697
cloudExperiments: 59358
cloudFullStory: 18493
cloudGainsight: 18710
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-test/jest-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ module.exports = {
transformIgnorePatterns: [
// ignore all node_modules except monaco-editor and react-monaco-editor which requires babel transforms to handle dynamic import()
// since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842)
'[/\\\\]node_modules(?![\\/\\\\](byte-size|monaco-editor|react-monaco-editor|d3-interpolate|d3-color))[/\\\\].+\\.js$',
'[/\\\\]node_modules(?![\\/\\\\](byte-size|monaco-editor|monaco-yaml|vscode-languageserver-types|react-monaco-editor|d3-interpolate|d3-color))[/\\\\].+\\.js$',
'packages/kbn-pm/dist/index.js',
],

Expand Down
9 changes: 9 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,15 @@
"enabled": true,
"prCreation": "immediate"
},
{
"groupName": "Cloud Defend",
"matchPackageNames": ["monaco-yaml"],
"reviewers": ["team:sec-cloudnative-integrations"],
"matchBaseBranches": ["main"],
"labels": ["Team: Cloud Native Integrations", "release_note:skip", "backport:skip"],
"enabled": true,
"prCreation": "immediate"
},
{
"groupName": "XState",
"matchPackageNames": ["xstate"],
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,8 @@
"@kbn/canvas-plugin/*": ["x-pack/plugins/canvas/*"],
"@kbn/cases-plugin": ["x-pack/plugins/cases"],
"@kbn/cases-plugin/*": ["x-pack/plugins/cases/*"],
"@kbn/cloud-defend-plugin": ["x-pack/plugins/cloud_defend"],
"@kbn/cloud-defend-plugin/*": ["x-pack/plugins/cloud_defend/*"],
"@kbn/cloud-chat-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat"],
"@kbn/cloud-chat-plugin/*": ["x-pack/plugins/cloud_integrations/cloud_chat/*"],
"@kbn/cloud-data-migration-plugin": ["x-pack/plugins/cloud_integrations/cloud_data_migration"],
Expand Down
1 change: 1 addition & 0 deletions x-pack/.i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"xpack.cases": "plugins/cases",
"xpack.cloud": "plugins/cloud",
"xpack.cloudChat": "plugins/cloud_integrations/cloud_chat",
"xpack.cloudDefend": "plugins/cloud_defend",
"xpack.cloudLinks": "plugins/cloud_integrations/cloud_links",
"xpack.cloudDataMigration": "plugins/cloud_integrations/cloud_data_migration",
"xpack.csp": "plugins/cloud_security_posture",
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/cloud_defend/.i18nrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"prefix": "cloudDefend",
"paths": {
"cloudDefend": "."
},
"translations": ["translations/ja-JP.json"]
}
48 changes: 48 additions & 0 deletions x-pack/plugins/cloud_defend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Cloud Defend (for containers)

This plugin currently only exists to provide custom fleet policy UX for a set of new BPF LSM features. The first feature being container "drift prevention".

Drift prevention is a way to block when executables are created or modified. Our agent service detects these events, and applies a set of selectors and responses configured to either block, alert or both.

## Example configuration
```
selectors:
# default selector (user can modify or remove if they want)
- name: default
operation: [createExecutable, modifyExecutable, execMemFd]
# example custom selector
- name: nginxOnly
containerImageName:
- nginx
# example selector used for exclude
- name: excludeCustomNginxBuild
containerImageTag:
- staging
# responses are evaluated from top to bottom
# only the first response with a match will run its actions
responses:
- match: [nginxOnly]
exclude: [excludeCustomNginxBuild]
actions: [alert, block]
# default response
# delete this if no default response needed
- match: [default]
actions: [alert]
```

---

## Development

## pre commit checks

```
node scripts/type_check.js --project x-pack/plugins/cloud_defend/tsconfig.json
yarn test:jest x-pack/plugins/cloud_defend
```

See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
12 changes: 12 additions & 0 deletions x-pack/plugins/cloud_defend/common/constants.ts
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.
*/

export const PLUGIN_ID = 'cloudDefend';
export const PLUGIN_NAME = 'cloudDefend';
export const INTEGRATION_PACKAGE_NAME = 'cloud_defend';
export const INPUT_CONTROL = 'cloud_defend/control';
export const ALERTS_DATASET = 'cloud_defend.alerts';
18 changes: 18 additions & 0 deletions x-pack/plugins/cloud_defend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/x-pack/plugins/cloud_defend'],
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/x-pack/plugins/cloud_defend',
coverageReporters: ['text', 'html'],
collectCoverageFrom: [
'<rootDir>/x-pack/plugins/cloud_defend/{common,public,server}/**/*.{ts,tsx}',
],
};
14 changes: 14 additions & 0 deletions x-pack/plugins/cloud_defend/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "cloudDefend",
"version": "1.0.0",
"kibanaVersion": "kibana",
"owner": {
"name": "Cloud Native Integrations",
"githubTeam": "sec-cloudnative-integrations"
},
"description": "Defend for Containers",
"server": false,
"ui": true,
"requiredPlugins": ["fleet", "kibanaReact"],
"optionalPlugins": []
}
12 changes: 12 additions & 0 deletions x-pack/plugins/cloud_defend/public/common/utils.ts
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.
*/

import { NewPackagePolicy } from '@kbn/fleet-plugin/public';

export function getInputFromPolicy(policy: NewPackagePolicy, inputId: string) {
return policy.inputs.find((input) => input.type === inputId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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.
*/

class ResizeObserver {
observe() {
// do nothing
}
unobserve() {
// do nothing
}
disconnect() {
// do nothing
}
}

window.ResizeObserver = ResizeObserver;
export default ResizeObserver;
Original file line number Diff line number Diff line change
@@ -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.
*/

class Worker {
constructor(stringUrl) {
this.url = stringUrl;
this.onmessage = () => {};
}

postMessage(msg) {
this.onmessage(msg);
}

terminate() {}
}

window.Worker = Worker;
export default Worker;
Loading

0 comments on commit 0b19cfa

Please sign in to comment.