[Security Solution] [Detections] Adds scripts to create users + roles based on specific privileges (#81866)
* shell scripts for creating roles + users for testing * update readme's and updated privilege requirements based on testing with the users and inferring what the roles are supposed to do * update role privileges based on feedback meeting yesterday * updated scripts to accept filepath to role / user, added a test to ensure upload value list button is disabled * updated role scripts to be parameterized * adds login with role function and adds a sample test with a role to test that a t1 analyst user cannot upload a value list * add object with corresponding roles * fix spacing * parameterize urls for basic auth with roles + users * forgot to change the cy.visit string * add KIBANA_URL env var for cli runner * add env vars for curl script execution * second script * update readme's for each role and remove create_index from lists privilege for the soc manager role * remove 'manage' cluster privilege for rule author * remove 'create_index' privilege from soc_manager role since that is not parity with the security workflows spreadsheet * update the login function logic with glo's feedback * replace SIEM with Security Solution in markdown files * make role param optional not just undefined * remove unused file * add copyright to scripts files * update top-level README for roles scripts * remove reference to internal spreadsheet and reference readme for this pr * remove unnecessary -XPOST and remove verbose mode from post_detections_user script * adds utils for running integration tests with other users and adds two sample tests showing example usage * minor type updates and small refactor * fix x-pack/test types * use enum types instead of custom type * fix path to json Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
This commit is contained in:
parent
45d3861219
commit
b3c334a1d9
|
@ -3,6 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { AlertAction } from '../../../alerts/common';
|
||||
|
||||
export type RuleAlertAction = Omit<AlertAction, 'actionTypeId'> & {
|
||||
|
|
18
x-pack/plugins/security_solution/common/test/index.ts
Normal file
18
x-pack/plugins/security_solution/common/test/index.ts
Normal file
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// For the source of these roles please consult the PR these were introduced https://github.com/elastic/kibana/pull/81866#issue-511165754
|
||||
export enum ROLES {
|
||||
t1_analyst = 't1_analyst',
|
||||
t2_analyst = 't2_analyst',
|
||||
hunter = 'hunter',
|
||||
rule_author = 'rule_author',
|
||||
soc_manager = 'soc_manager',
|
||||
platform_engineer = 'platform_engineer',
|
||||
detections_admin = 'detections_admin',
|
||||
}
|
||||
|
||||
export type RolesType = keyof typeof ROLES;
|
|
@ -4,7 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
import { ROLES } from '../../common/test';
|
||||
import { deleteRoleAndUser, loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
import {
|
||||
waitForAlertsPanelToBeLoaded,
|
||||
|
@ -24,7 +25,7 @@ import {
|
|||
deleteValueListsFile,
|
||||
exportValueList,
|
||||
} from '../tasks/lists';
|
||||
import { VALUE_LISTS_TABLE, VALUE_LISTS_ROW } from '../screens/lists';
|
||||
import { VALUE_LISTS_TABLE, VALUE_LISTS_ROW, VALUE_LISTS_MODAL_ACTIVATOR } from '../screens/lists';
|
||||
|
||||
describe('value lists', () => {
|
||||
describe('management modal', () => {
|
||||
|
@ -220,4 +221,19 @@ describe('value lists', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('user with restricted access role', () => {
|
||||
beforeEach(() => {
|
||||
loginAndWaitForPageWithoutDateRange(DETECTIONS_URL, ROLES.t1_analyst);
|
||||
goToManageAlertsDetectionRules();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
deleteRoleAndUser(ROLES.t1_analyst);
|
||||
});
|
||||
|
||||
it('Does not allow a t1 analyst user to upload a value list', () => {
|
||||
cy.get(VALUE_LISTS_MODAL_ACTIVATOR).should('have.attr', 'disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
import * as yaml from 'js-yaml';
|
||||
import Url, { UrlObject } from 'url';
|
||||
|
||||
import { RolesType } from '../../common/test';
|
||||
import { TIMELINE_FLYOUT_BODY } from '../screens/timeline';
|
||||
|
||||
/**
|
||||
|
@ -42,6 +45,89 @@ const ELASTICSEARCH_PASSWORD = 'ELASTICSEARCH_PASSWORD';
|
|||
*/
|
||||
const LOGIN_API_ENDPOINT = '/internal/security/login';
|
||||
|
||||
/**
|
||||
* cy.visit will default to the baseUrl which uses the default kibana test user
|
||||
* This function will override that functionality in cy.visit by building the baseUrl
|
||||
* directly from the environment variables set up in x-pack/test/security_solution_cypress/runner.ts
|
||||
*
|
||||
* @param role string role/user to log in with
|
||||
* @param route string route to visit
|
||||
*/
|
||||
export const getUrlWithRoute = (role: RolesType, route: string) => {
|
||||
const theUrl = `${Url.format({
|
||||
auth: `${role}:changeme`,
|
||||
username: role,
|
||||
password: 'changeme',
|
||||
protocol: Cypress.env('protocol'),
|
||||
hostname: Cypress.env('hostname'),
|
||||
port: Cypress.env('configport'),
|
||||
} as UrlObject)}${route.startsWith('/') ? '' : '/'}${route}`;
|
||||
cy.log(`origin: ${theUrl}`);
|
||||
return theUrl;
|
||||
};
|
||||
|
||||
export const getCurlScriptEnvVars = () => ({
|
||||
ELASTICSEARCH_URL: Cypress.env('ELASTICSEARCH_URL'),
|
||||
ELASTICSEARCH_USERNAME: Cypress.env('ELASTICSEARCH_USERNAME'),
|
||||
ELASTICSEARCH_PASSWORD: Cypress.env('ELASTICSEARCH_PASSWORD'),
|
||||
KIBANA_URL: Cypress.env('KIBANA_URL'),
|
||||
});
|
||||
|
||||
export const postRoleAndUser = (role: RolesType) => {
|
||||
const env = getCurlScriptEnvVars();
|
||||
const detectionsRoleScriptPath = `./server/lib/detection_engine/scripts/roles_users/${role}/post_detections_role.sh`;
|
||||
const detectionsRoleJsonPath = `./server/lib/detection_engine/scripts/roles_users/${role}/detections_role.json`;
|
||||
const detectionsUserScriptPath = `./server/lib/detection_engine/scripts/roles_users/${role}/post_detections_user.sh`;
|
||||
const detectionsUserJsonPath = `./server/lib/detection_engine/scripts/roles_users/${role}/detections_user.json`;
|
||||
|
||||
// post the role
|
||||
cy.exec(`bash ${detectionsRoleScriptPath} ${detectionsRoleJsonPath}`, {
|
||||
env,
|
||||
});
|
||||
|
||||
// post the user associated with the role to elasticsearch
|
||||
cy.exec(`bash ${detectionsUserScriptPath} ${detectionsUserJsonPath}`, {
|
||||
env,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteRoleAndUser = (role: RolesType) => {
|
||||
const env = getCurlScriptEnvVars();
|
||||
const detectionsUserDeleteScriptPath = `./server/lib/detection_engine/scripts/roles_users/${role}/delete_detections_user.sh`;
|
||||
|
||||
// delete the role
|
||||
cy.exec(`bash ${detectionsUserDeleteScriptPath}`, {
|
||||
env,
|
||||
});
|
||||
};
|
||||
|
||||
export const loginWithRole = async (role: RolesType) => {
|
||||
postRoleAndUser(role);
|
||||
const theUrl = Url.format({
|
||||
auth: `${role}:changeme`,
|
||||
username: role,
|
||||
password: 'changeme',
|
||||
protocol: Cypress.env('protocol'),
|
||||
hostname: Cypress.env('hostname'),
|
||||
port: Cypress.env('configport'),
|
||||
} as UrlObject);
|
||||
cy.log(`origin: ${theUrl}`);
|
||||
cy.request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: role,
|
||||
password: 'changeme',
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds-via-config' },
|
||||
method: 'POST',
|
||||
url: getUrlWithRoute(role, LOGIN_API_ENDPOINT),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticates with Kibana using, if specified, credentials specified by
|
||||
* environment variables. The credentials in `kibana.dev.yml` will be used
|
||||
|
@ -50,8 +136,10 @@ const LOGIN_API_ENDPOINT = '/internal/security/login';
|
|||
* To speed the execution of tests, prefer this non-interactive authentication,
|
||||
* which is faster than authentication via Kibana's interactive login page.
|
||||
*/
|
||||
export const login = () => {
|
||||
if (credentialsProvidedByEnvironment()) {
|
||||
export const login = (role?: RolesType) => {
|
||||
if (role != null) {
|
||||
loginWithRole(role);
|
||||
} else if (credentialsProvidedByEnvironment()) {
|
||||
loginViaEnvironmentCredentials();
|
||||
} else {
|
||||
loginViaConfig();
|
||||
|
@ -129,8 +217,8 @@ const loginViaConfig = () => {
|
|||
* Authenticates with Kibana, visits the specified `url`, and waits for the
|
||||
* Kibana global nav to be displayed before continuing
|
||||
*/
|
||||
export const loginAndWaitForPage = (url: string) => {
|
||||
login();
|
||||
export const loginAndWaitForPage = (url: string, role?: RolesType) => {
|
||||
login(role);
|
||||
cy.viewport('macbook-15');
|
||||
cy.visit(
|
||||
`${url}?timerange=(global:(linkTo:!(timeline),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)))`
|
||||
|
@ -138,17 +226,19 @@ export const loginAndWaitForPage = (url: string) => {
|
|||
cy.get('[data-test-subj="headerGlobalNav"]');
|
||||
};
|
||||
|
||||
export const loginAndWaitForPageWithoutDateRange = (url: string) => {
|
||||
login();
|
||||
export const loginAndWaitForPageWithoutDateRange = (url: string, role?: RolesType) => {
|
||||
login(role);
|
||||
cy.viewport('macbook-15');
|
||||
cy.visit(url);
|
||||
cy.visit(role ? getUrlWithRoute(role, url) : url);
|
||||
cy.get('[data-test-subj="headerGlobalNav"]', { timeout: 120000 });
|
||||
};
|
||||
|
||||
export const loginAndWaitForTimeline = (timelineId: string) => {
|
||||
login();
|
||||
export const loginAndWaitForTimeline = (timelineId: string, role?: RolesType) => {
|
||||
const route = `/app/security/timelines?timeline=(id:'${timelineId}',isOpen:!t)`;
|
||||
|
||||
login(role);
|
||||
cy.viewport('macbook-15');
|
||||
cy.visit(`/app/security/timelines?timeline=(id:'${timelineId}',isOpen:!t)`);
|
||||
cy.visit(role ? getUrlWithRoute(role, route) : route);
|
||||
cy.get('[data-test-subj="headerGlobalNav"]');
|
||||
cy.get(TIMELINE_FLYOUT_BODY).should('be.visible');
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"build-graphql-types": "node scripts/generate_types_from_graphql.js",
|
||||
"cypress:open": "../../../node_modules/.bin/cypress open --config-file ./cypress/cypress.json",
|
||||
"cypress:open-as-ci": "node ../../../scripts/functional_tests --config ../../test/security_solution_cypress/visual_config.ts",
|
||||
"cypress:run": "../../../node_modules/.bin/cypress run --browser chrome --headless --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/ && exit $status;",
|
||||
"cypress:run": "../../../node_modules/.bin/cypress run --browser chrome --headless --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/ && exit $status;",
|
||||
"cypress:run-as-ci": "node --max-old-space-size=2048 ../../../scripts/functional_tests --config ../../test/security_solution_cypress/cli_config.ts",
|
||||
"test:generate": "node scripts/endpoint/resolver_generator"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
1. When first starting up elastic, detections will not be available until you visit the page with a SOC Manager role or Platform Engineer role
|
||||
2. I gave the Hunter role "all" privileges for saved objects management and builtInAlerts so that they can create rules.
|
||||
3. Rule Author has the ability to create rules and create value lists
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :------------------------------------------: | :----------: | :-------------------------------: | :---------: | :--------------: | :---------------: | :------------------------------: |
|
||||
| T1 Analyst | read | read | none | read | read | read, write |
|
||||
| T2 Analyst | read | read | read | read | read | read, write |
|
||||
| Hunter / T3 Analyst | read, write | read | read | read, write | read | read, write |
|
||||
| Rule Author / Manager / Detections Engineer | read, write | read | read, write | read, write | read | read, write, view_index_metadata |
|
||||
| SOC Manager | read, write | read | read, write | read, write | all | read, write, manage |
|
||||
| Platform Engineer (data ingest, cluster ops) | read, write | all | all | read, write | all | all |
|
|
@ -0,0 +1 @@
|
|||
This user contains all the possible privileges listed in our detections privileges docs https://www.elastic.co/guide/en/security/current/detections-permissions-section.html This user has higher privileges than the Platform Engineer user
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/detections_admin
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": ["manage"],
|
||||
"indices": [
|
||||
{
|
||||
"names": [
|
||||
".siem-signals-*",
|
||||
".lists*",
|
||||
".items*",
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"privileges": ["manage", "write", "read"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["all"],
|
||||
"siem": ["all"],
|
||||
"actions": ["read"],
|
||||
"builtInAlerts": ["all"],
|
||||
"dev_tools": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["detections_admin"],
|
||||
"full_name": "Detections User",
|
||||
"email": "detections-user@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/detections_admin | jq -S .
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/detections_admin \
|
||||
-d @detections_role.json
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/detections_admin \
|
||||
-d @${USER}
|
|
@ -0,0 +1,12 @@
|
|||
This user can CRUD rules and signals. The main difference here is the user has
|
||||
|
||||
```json
|
||||
"builtInAlerts": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
```
|
||||
|
||||
privileges whereas the T1 and T2 have "read" privileges which prevents them from creating rules
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :-----------------: | :----------: | :------------------: | :---: | :--------------: | :---------------: | :------------: |
|
||||
| Hunter / T3 Analyst | read, write | read | read | read, write | read | read, write |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/hunter
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": [
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"privileges": ["read", "write"]
|
||||
},
|
||||
{
|
||||
"names": [".siem-signals-*"],
|
||||
"privileges": ["read", "write"]
|
||||
},
|
||||
{
|
||||
"names": [".lists*", ".items*"],
|
||||
"privileges": ["read", "write"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["read"],
|
||||
"siem": ["all"],
|
||||
"actions": ["read"],
|
||||
"builtInAlerts": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["hunter"],
|
||||
"full_name": "Hunter",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/hunter | jq -S .
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/hunter \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/hunter \
|
||||
-d @${USER}
|
|
@ -0,0 +1,5 @@
|
|||
essentially a superuser for security solution
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :------------------------------------------: | :----------: | :------------------: | :---: | :--------------: | :---------------: | :------------: |
|
||||
| Platform Engineer (data ingest, cluster ops) | all | all | all | read, write | all | all |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/platform_engineer
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": ["manage"],
|
||||
"indices": [
|
||||
{
|
||||
"names": [".lists*", ".items*"],
|
||||
"privileges": ["all"]
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"privileges": ["all"]
|
||||
},
|
||||
{
|
||||
"names": [".siem-signals-*"],
|
||||
"privileges": ["all"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["all"],
|
||||
"siem": ["all"],
|
||||
"actions": ["all"],
|
||||
"builtInAlerts": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["platform_engineer"],
|
||||
"full_name": "platform engineer",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/platform_engineer | jq -S .
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/platform_engineer \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/platform_engineer \
|
||||
-d @${USER}
|
|
@ -0,0 +1,5 @@
|
|||
rule author has the same privileges as hunter with the additional privileges of uploading value lists
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :-----------------------------------------: | :----------: | :------------------: | :---------: | :--------------: | :---------------: | :------------------------------: |
|
||||
| Rule Author / Manager / Detections Engineer | read, write | read | read, write | read, write | read | read, write, view_index_metadata |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/rule_author
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": [
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*",
|
||||
".lists*",
|
||||
".items*"
|
||||
],
|
||||
"privileges": ["read", "write"]
|
||||
},
|
||||
{
|
||||
"names": [".siem-signals-*"],
|
||||
"privileges": ["read", "write", "view_index_metadata"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["read"],
|
||||
"siem": ["all"],
|
||||
"actions": ["read"],
|
||||
"builtInAlerts": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["rule_author"],
|
||||
"full_name": "rule author",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/rule_author | jq -S .
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/rule_author \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/rule_author \
|
||||
-d @${USER}
|
|
@ -0,0 +1,5 @@
|
|||
SOC Manager has all of the privileges of a rule author role with the additional privilege of managing the signals index. It can't create the signals index though.
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :---------: | :----------: | :------------------: | :---------: | :--------------: | :---------------: | :-----------------: |
|
||||
| SOC Manager | read, write | read | read, write | read, write | all | read, write, manage |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/soc_manager
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{
|
||||
"names": [
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*",
|
||||
".lists*",
|
||||
".items*"
|
||||
],
|
||||
"privileges": ["read", "write"]
|
||||
},
|
||||
{
|
||||
"names": [".siem-signals-*"],
|
||||
"privileges": ["read", "write", "manage"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["read"],
|
||||
"siem": ["all"],
|
||||
"actions": ["all"],
|
||||
"builtInAlerts": ["all"],
|
||||
"savedObjectsManagement": ["all"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["soc_manager"],
|
||||
"full_name": "SOC manager",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/soc_manager | jq -S .
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/soc_manager \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/soc_manager \
|
||||
-d @${USER}
|
|
@ -0,0 +1,3 @@
|
|||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Actions Connectors | Signals/Alerts |
|
||||
| :--------: | :----------: | :------------------: | :---: | :--------------: | :----------------: | :------------: |
|
||||
| T1 Analyst | read | read | none | read | read | read, write |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/t1_analyst
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{ "names": [".siem-signals-*"], "privileges": ["read", "write"] },
|
||||
{
|
||||
"names": [
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["read"],
|
||||
"siem": ["all"],
|
||||
"actions": ["read"],
|
||||
"builtInAlerts": ["read"],
|
||||
"savedObjectsManagement": ["read"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["t1_analyst"],
|
||||
"full_name": "T1 Analyst",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/t1_analyst | jq -S .
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
# Uses a default if no argument is specified
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/t1_analyst \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/t1_analyst \
|
||||
-d @${USER}
|
|
@ -0,0 +1,5 @@
|
|||
This role can view rules. Essentially there is no difference between a T1 and T2 analyst.
|
||||
|
||||
| Role | Data Sources | Security Solution ML Jobs/Results | Lists | Rules/Exceptions | Action Connectors | Signals/Alerts |
|
||||
| :--------: | :----------: | :------------------: | :---: | :--------------: | :---------------: | :------------: |
|
||||
| T2 Analyst | read | read | read | read | read | read, write |
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XDELETE ${ELASTICSEARCH_URL}/_security/user/t2_analyst
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"elasticsearch": {
|
||||
"cluster": [],
|
||||
"indices": [
|
||||
{ "names": [".siem-signals-*"], "privileges": ["read", "write"] },
|
||||
{
|
||||
"names": [
|
||||
".lists*",
|
||||
".items*",
|
||||
"apm-*-transaction*",
|
||||
"auditbeat-*",
|
||||
"endgame-*",
|
||||
"filebeat-*",
|
||||
"logs-*",
|
||||
"packetbeat-*",
|
||||
"winlogbeat-*"
|
||||
],
|
||||
"privileges": ["read"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"kibana": [
|
||||
{
|
||||
"feature": {
|
||||
"ml": ["read"],
|
||||
"siem": ["all"],
|
||||
"actions": ["read"],
|
||||
"builtInAlerts": ["read"],
|
||||
"savedObjectsManagement": ["read"]
|
||||
},
|
||||
"spaces": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"password": "changeme",
|
||||
"roles": ["t2_analyst"],
|
||||
"full_name": "t2 analyst",
|
||||
"email": "detections-reader@example.com"
|
||||
}
|
|
@ -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;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XGET ${KIBANA_URL}/api/security/role/t2_analyst | jq -S .
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
ROLE=(${@:-./detections_role.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
-XPUT ${KIBANA_URL}/api/security/role/t2_analyst \
|
||||
-d @${ROLE}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#
|
||||
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License;
|
||||
# you may not use this file except in compliance with the Elastic License.
|
||||
#
|
||||
|
||||
USER=(${@:-./detections_user.json})
|
||||
|
||||
curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\
|
||||
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
|
||||
${ELASTICSEARCH_URL}/_security/user/t2_analyst \
|
||||
-d @${USER}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import * as t1AnalystUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_user.json';
|
||||
import * as t2AnalystUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_user.json';
|
||||
import * as hunterUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_user.json';
|
||||
import * as ruleAuthorUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_user.json';
|
||||
import * as socManagerUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_user.json';
|
||||
import * as platformEngineerUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_user.json';
|
||||
import * as detectionsAdminUser from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_user.json';
|
||||
|
||||
import * as t1AnalystRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json';
|
||||
import * as t2AnalystRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json';
|
||||
import * as hunterRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json';
|
||||
import * as ruleAuthorRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json';
|
||||
import * as socManagerRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json';
|
||||
import * as platformEngineerRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json';
|
||||
import * as detectionsAdminRole from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json';
|
||||
|
||||
import { ROLES } from '../../../../plugins/security_solution/common/test';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
export const createUserAndRole = async (
|
||||
securityService: ReturnType<FtrProviderContext['getService']>,
|
||||
role: keyof typeof ROLES
|
||||
) => {
|
||||
switch (role) {
|
||||
case ROLES.detections_admin:
|
||||
await postRoleAndUser(
|
||||
ROLES.detections_admin,
|
||||
detectionsAdminRole,
|
||||
detectionsAdminUser,
|
||||
securityService
|
||||
);
|
||||
break;
|
||||
case ROLES.t1_analyst:
|
||||
await postRoleAndUser(ROLES.t1_analyst, t1AnalystRole, t1AnalystUser, securityService);
|
||||
break;
|
||||
case ROLES.t2_analyst:
|
||||
await postRoleAndUser(ROLES.t2_analyst, t2AnalystRole, t2AnalystUser, securityService);
|
||||
break;
|
||||
case ROLES.hunter:
|
||||
await postRoleAndUser(ROLES.hunter, hunterRole, hunterUser, securityService);
|
||||
break;
|
||||
case ROLES.rule_author:
|
||||
await postRoleAndUser(ROLES.rule_author, ruleAuthorRole, ruleAuthorUser, securityService);
|
||||
break;
|
||||
case ROLES.soc_manager:
|
||||
await postRoleAndUser(ROLES.soc_manager, socManagerRole, socManagerUser, securityService);
|
||||
break;
|
||||
case ROLES.platform_engineer:
|
||||
await postRoleAndUser(
|
||||
ROLES.platform_engineer,
|
||||
platformEngineerRole,
|
||||
platformEngineerUser,
|
||||
securityService
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
interface UserInterface {
|
||||
password: string;
|
||||
roles: string[];
|
||||
full_name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface RoleInterface {
|
||||
elasticsearch: {
|
||||
cluster: string[];
|
||||
indices: Array<{
|
||||
names: string[];
|
||||
privileges: string[];
|
||||
}>;
|
||||
};
|
||||
kibana: Array<{
|
||||
feature: {
|
||||
ml: string[];
|
||||
siem: string[];
|
||||
actions: string[];
|
||||
builtInAlerts: string[];
|
||||
savedObjectsManagement: string[];
|
||||
};
|
||||
spaces: string[];
|
||||
}>;
|
||||
}
|
||||
|
||||
export const postRoleAndUser = async (
|
||||
roleName: string,
|
||||
role: RoleInterface,
|
||||
user: UserInterface,
|
||||
securityService: ReturnType<FtrProviderContext['getService']>
|
||||
) => {
|
||||
await securityService.role.create(roleName, {
|
||||
kibana: role.kibana,
|
||||
elasticsearch: role.elasticsearch,
|
||||
});
|
||||
await securityService.user.create(roleName, {
|
||||
password: 'changeme',
|
||||
full_name: user.full_name,
|
||||
roles: user.roles,
|
||||
});
|
||||
};
|
|
@ -25,12 +25,16 @@ import {
|
|||
waitForSignalsToBePresent,
|
||||
getAllSignals,
|
||||
} from '../../utils';
|
||||
import { createUserAndRole } from '../roles_users_utils';
|
||||
import { ROLES } from '../../../../plugins/security_solution/common/test';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const es = getService('es');
|
||||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
const securityService = getService('security');
|
||||
|
||||
describe('open_close_signals', () => {
|
||||
describe('validation checks', () => {
|
||||
|
@ -157,6 +161,79 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
);
|
||||
expect(everySignalClosed).to.eql(true);
|
||||
});
|
||||
|
||||
it('should NOT be able to close signals with t1 analyst user', async () => {
|
||||
const rule = { ...getSimpleRule(), from: '1900-01-01T00:00:00.000Z', query: '*:*' };
|
||||
await createRule(supertest, rule);
|
||||
await waitForSignalsToBePresent(supertest);
|
||||
await createUserAndRole(securityService, ROLES.t1_analyst);
|
||||
const signalsOpen = await getAllSignals(supertest);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
|
||||
// Try to set all of the signals to the state of closed.
|
||||
// This should not be possible with the given user.
|
||||
await supertestWithoutAuth
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.auth(ROLES.t1_analyst, 'changeme')
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.expect(403);
|
||||
|
||||
// query for the signals with the superuser
|
||||
// to allow a check that the signals were NOT closed with t1 analyst
|
||||
const {
|
||||
body: signalsClosed,
|
||||
}: { body: SearchResponse<{ signal: Signal }> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.expect(200);
|
||||
|
||||
const everySignalOpen = signalsClosed.hits.hits.every(
|
||||
({
|
||||
_source: {
|
||||
signal: { status },
|
||||
},
|
||||
}) => status === 'open'
|
||||
);
|
||||
expect(everySignalOpen).to.eql(true);
|
||||
});
|
||||
|
||||
it('should be able to close signals with soc_manager user', async () => {
|
||||
const rule = { ...getSimpleRule(), from: '1900-01-01T00:00:00.000Z', query: '*:*' };
|
||||
await createRule(supertest, rule);
|
||||
await waitForSignalsToBePresent(supertest);
|
||||
const userAndRole = ROLES.soc_manager;
|
||||
await createUserAndRole(securityService, userAndRole);
|
||||
const signalsOpen = await getAllSignals(supertest);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
|
||||
// Try to set all of the signals to the state of closed.
|
||||
// This should not be possible with the given user.
|
||||
await supertestWithoutAuth
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.auth(userAndRole, 'changeme') // each user has the same password
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.expect(200);
|
||||
|
||||
const {
|
||||
body: signalsClosed,
|
||||
}: { body: SearchResponse<{ signal: Signal }> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.expect(200);
|
||||
|
||||
const everySignalClosed = signalsClosed.hits.hits.every(
|
||||
({
|
||||
_source: {
|
||||
signal: { status },
|
||||
},
|
||||
}) => status === 'closed'
|
||||
);
|
||||
expect(everySignalClosed).to.eql(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,9 +28,20 @@ export async function SecuritySolutionCypressCliTestRunner({ getService }: FtrPr
|
|||
FORCE_COLOR: '1',
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_baseUrl: Url.format(config.get('servers.kibana')),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_protocol: config.get('servers.kibana.protocol'),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_hostname: config.get('servers.kibana.hostname'),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_configport: config.get('servers.kibana.port'),
|
||||
CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')),
|
||||
CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'),
|
||||
CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'),
|
||||
CYPRESS_KIBANA_URL: Url.format({
|
||||
protocol: config.get('servers.kibana.protocol'),
|
||||
hostname: config.get('servers.kibana.hostname'),
|
||||
port: config.get('servers.kibana.port'),
|
||||
}),
|
||||
...process.env,
|
||||
},
|
||||
wait: true,
|
||||
|
@ -55,9 +66,20 @@ export async function SecuritySolutionCypressVisualTestRunner({ getService }: Ft
|
|||
FORCE_COLOR: '1',
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_baseUrl: Url.format(config.get('servers.kibana')),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_protocol: config.get('servers.kibana.protocol'),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_hostname: config.get('servers.kibana.hostname'),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
CYPRESS_configport: config.get('servers.kibana.port'),
|
||||
CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')),
|
||||
CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'),
|
||||
CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'),
|
||||
CYPRESS_KIBANA_URL: Url.format({
|
||||
protocol: config.get('servers.kibana.protocol'),
|
||||
hostname: config.get('servers.kibana.hostname'),
|
||||
port: config.get('servers.kibana.port'),
|
||||
}),
|
||||
...process.env,
|
||||
},
|
||||
wait: true,
|
||||
|
|
Loading…
Reference in a new issue