From 881a4bb29317ab23895ab550f94cc10915bc781a Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 13 Nov 2023 10:28:16 +0100 Subject: [PATCH] [Security Solution] Add a script to create roles and users (#171067) **Relates to:** https://github.com/elastic/kibana/pull/169017 ## Summary This PR re-adds an utility shell script for roles and users creation to replace scripts removed in a previous [PR](https://github.com/elastic/kibana/pull/169017). --- .github/CODEOWNERS | 1 + .../scripts/roles_users/README.md | 41 +++++++ .../roles_users/create_role_and_user.sh | 10 ++ .../roles_users/create_role_and_user.ts | 106 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/README.md create mode 100755 x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.sh create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 453cbc463b270..5c112d886cd3a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1371,6 +1371,7 @@ x-pack/test/security_solution_api_integration/test_suites/detections_response/de x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_creation @elastic/security-detection-engine x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/actions @elastic/security-detection-engine x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/alerts @elastic/security-detection-engine +/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users @elastic/security-detection-engine ## Security Threat Intelligence - Under Security Platform /x-pack/plugins/security_solution/public/common/components/threat_match @elastic/security-detection-engine diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/README.md new file mode 100644 index 0000000000000..0398f182f9f4e --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/README.md @@ -0,0 +1,41 @@ +# Create role/user utility + +`create_role_and_user.sh` shell script facilitates roles and users creation process. It accepts only one `--role` parameter restricted to known role definitions (See `@kbn/security-solution-plugin/common/test/index.ts` for the roles list). Created user has role's name and this only role assigned. + +## Expected environment variables + +The following environment variables can be specified + +- `ELASTICSEARCH_URL` Elasticsearch url e.g. `http://127.0.0.1:9200` +- `KIBANA_URL` Kibana url e.g. `http://127.0.0.1:560` +- `USERNAME` a user name to authenticate requests e.g. `elastic` +- `PASSWORD` a password to authenticate requests e.g. `changeme` + +If an environment variable is not specified sensible defaults is used. + +### Notes + +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. Rule Author has the ability to create rules and create value lists + +## Examples + +For example to create `t1_analyst` user with `t1_analyst` role run the following command in the current folder + +```bash +./create_role_and_user.sh --role=t1_analyst +``` + +Output + +``` + warn Environment variable "ELASTICSEARCH_URL" is not set, using "http://127.0.0.1:9200" as a default value + info Using environment variable KIBANA_URL=http://127.0.0.1:5601/kbn + warn Environment variable "USERNAME" is not set, using "elastic" as a default value + warn Environment variable "PASSWORD" is not set, using "changeme" as a default value + info Creating role "t1_analyst"... + info Role "t1_analyst" has been created + info Creating user "t1_analyst"... + info User "t1_analyst" has been created (password "changeme") + succ Done +``` \ No newline at end of file diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.sh new file mode 100755 index 0000000000000..516d38829b3e4 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh + +# +# 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. +# + +npx ts-node "$(dirname "${0}")/create_role_and_user.ts" "$@" \ No newline at end of file diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts new file mode 100644 index 0000000000000..04b09feb1a153 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/create_role_and_user.ts @@ -0,0 +1,106 @@ +/* + * 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 axios from 'axios'; +import yargs from 'yargs'; +import { ToolingLog } from '@kbn/tooling-log'; +import { + KNOWN_ESS_ROLE_DEFINITIONS, + KNOWN_SERVERLESS_ROLE_DEFINITIONS, +} from '../../../../../common/test'; + +const logger = new ToolingLog({ + level: 'info', + writeTo: process.stdout, +}); +const KNOWN_ROLE_DEFINITIONS = { + ...KNOWN_ESS_ROLE_DEFINITIONS, + ...KNOWN_SERVERLESS_ROLE_DEFINITIONS, +}; +const DEFAULT_PASSWORD = 'changeme'; + +cli() + .then(() => logger.success('Done')) + .catch((e) => logger.error(e)); + +async function cli(): Promise { + const { role } = yargs(process.argv) + .choices( + 'role', + Object.keys(KNOWN_ROLE_DEFINITIONS) as Array + ) + .demandOption('role') + .version(false) + .help(false).argv; + const selectedRoleDefinition = KNOWN_ROLE_DEFINITIONS[role]; + const userName = role; + const ELASTICSEARCH_URL = getEnvVariableOrDefault('ELASTICSEARCH_URL', 'http://127.0.0.1:9200'); + const KIBANA_URL = getEnvVariableOrDefault('KIBANA_URL', 'http://127.0.0.1:560'); + const USERNAME = getEnvVariableOrDefault('USERNAME', 'elastic'); + const PASSWORD = getEnvVariableOrDefault('PASSWORD', DEFAULT_PASSWORD); + const password = DEFAULT_PASSWORD; + const requestHeaders = { + Authorization: `Basic ${btoa(`${USERNAME}:${PASSWORD}`)}`, + 'kbn-xsrf': 'xxx', + }; + + try { + logger.info(`Creating role "${role}"...`); + await axios.put( + `${KIBANA_URL}/api/security/role/${role}`, + { + elasticsearch: selectedRoleDefinition.elasticsearch, + kibana: selectedRoleDefinition.kibana, + }, + { + headers: requestHeaders, + } + ); + + logger.info(`Role "${role}" has been created`); + } catch (e) { + logger.error(`Unable to create role "${role}"`); + throw e; + } + + try { + logger.info(`Creating user "${userName}"...`); + await axios.put( + `${ELASTICSEARCH_URL}/_security/user/${userName}`, + { + password, + roles: [role], + full_name: role, + email: `role@example.com`, + }, + { + headers: requestHeaders, + } + ); + + logger.info(`User "${userName}" has been created (password "${password}")`); + } catch (e) { + logger.error(`Unable to create user "${userName}"`); + throw e; + } +} + +function getEnvVariableOrDefault(variableName: string, defaultValue: string): string { + const value = process.env[variableName]; + + if (!value) { + logger.warning( + `Environment variable "${variableName}" is not set, using "${defaultValue}" as a default value` + ); + + return defaultValue; + } + + logger.info(`Using environment variable ${variableName}=${value}`); + + return value; +}