mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Entity Analytics][Privilege User Monitoring] Add Privileged User CRUD API (#218098)
## Summary This PR introduces basic CRUD routes for handling Privileged Users in Entity Analytics. The following routes are available: * CREATE: `POST /api/entity_analytics/monitoring/users` * GET: `GET /api/entity_analytics/monitoring/users/{id}` * LIST: `GET /api/entity_analytics/monitoring/users/list` * UPDATE: `PUT /api/entity_analytics/monitoring/users/{id}` * DELETE: `DELETE /api/entity_analytics/monitoring/users/{id}` For CREATE and UPDATE, the request body should be of type: ``` { "user_name": string, is_monitored: boolean } ``` The reason for snake_case is to align better with the upcoming csv and json upload work. This PR already introduces boilerplate code (registering the endpoints and handlers) for those routes). We might want to change this. ## How to test 1. Start a fresh Kibana instance 2. Enable the `EntityAnalyticsPrivilegeMonitoring` Feature Flag. 3. Initialise the privmon engine with `POST kbn:/api/entity_analytics/monitoring/engine/init` 4. Test any of the endpoints above * Make sure to either note down the returned `id`s or simply query the underlying index: `.entity_analytics.monitoring.users-<your namespace>` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
1971ff261c
commit
7059a8a1c7
37 changed files with 2393 additions and 2 deletions
|
@ -13412,6 +13412,173 @@ paths:
|
|||
summary: Health check on Privilege Monitoring
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users:
|
||||
post:
|
||||
operationId: CreatePrivMonUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_UserName'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User created successfully
|
||||
summary: Create a new monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_csv:
|
||||
post:
|
||||
operationId: BulkUploadUsersCSV
|
||||
requestBody:
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
description: CSV file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via CSV upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_json:
|
||||
post:
|
||||
operationId: BulkUploadUsersJSON
|
||||
requestBody:
|
||||
content:
|
||||
text/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
is_monitored:
|
||||
type: boolean
|
||||
user_name:
|
||||
type: string
|
||||
type: array
|
||||
description: JSON file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via JSON upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
delete:
|
||||
operationId: DeletePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
aknowledged:
|
||||
description: Indicates if the deletion was successful
|
||||
type: boolean
|
||||
message:
|
||||
description: A message providing additional information about the deletion status
|
||||
type: string
|
||||
required:
|
||||
- success
|
||||
description: User deleted successfully
|
||||
summary: Delete a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
get:
|
||||
operationId: GetPrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User details retrieved
|
||||
summary: Retrieve a monitored user by ID
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
put:
|
||||
operationId: UpdatePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User updated successfully
|
||||
summary: Update a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/list:
|
||||
get:
|
||||
operationId: ListPrivMonUsers
|
||||
parameters:
|
||||
- description: KQL query to filter the list of monitored users
|
||||
in: query
|
||||
name: kql
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
type: array
|
||||
description: List of monitored users
|
||||
summary: List all monitored users
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_store/enable:
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
|
@ -65337,6 +65504,65 @@ components:
|
|||
type: string
|
||||
Security_Entity_Analytics_API_Metadata:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_TransformStatsMetadata'
|
||||
Security_Entity_Analytics_API_MonitoredUserDoc:
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
format: date-time
|
||||
type: string
|
||||
entity_analytics_monitoring:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
type: array
|
||||
event:
|
||||
type: object
|
||||
properties:
|
||||
ingested:
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
labels:
|
||||
type: object
|
||||
properties:
|
||||
monitoring:
|
||||
type: object
|
||||
properties:
|
||||
privileged_users:
|
||||
enum:
|
||||
- monitored
|
||||
- deleted
|
||||
type: string
|
||||
source_indices:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
source_integrations:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
sources:
|
||||
items:
|
||||
enum:
|
||||
- csv
|
||||
- index_sync
|
||||
- api
|
||||
type: array
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
Security_Entity_Analytics_API_MonitoringEngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -65587,6 +65813,15 @@ components:
|
|||
required:
|
||||
- user
|
||||
- entity
|
||||
Security_Entity_Analytics_API_UserName:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: The name of the user.
|
||||
type: string
|
||||
Security_Exceptions_API_CreateExceptionListItemComment:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -15571,6 +15571,173 @@ paths:
|
|||
summary: Health check on Privilege Monitoring
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users:
|
||||
post:
|
||||
operationId: CreatePrivMonUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_UserName'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User created successfully
|
||||
summary: Create a new monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_csv:
|
||||
post:
|
||||
operationId: BulkUploadUsersCSV
|
||||
requestBody:
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
description: CSV file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via CSV upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_json:
|
||||
post:
|
||||
operationId: BulkUploadUsersJSON
|
||||
requestBody:
|
||||
content:
|
||||
text/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
is_monitored:
|
||||
type: boolean
|
||||
user_name:
|
||||
type: string
|
||||
type: array
|
||||
description: JSON file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via JSON upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
delete:
|
||||
operationId: DeletePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
aknowledged:
|
||||
description: Indicates if the deletion was successful
|
||||
type: boolean
|
||||
message:
|
||||
description: A message providing additional information about the deletion status
|
||||
type: string
|
||||
required:
|
||||
- success
|
||||
description: User deleted successfully
|
||||
summary: Delete a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
get:
|
||||
operationId: GetPrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User details retrieved
|
||||
summary: Retrieve a monitored user by ID
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
put:
|
||||
operationId: UpdatePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
description: User updated successfully
|
||||
summary: Update a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/list:
|
||||
get:
|
||||
operationId: ListPrivMonUsers
|
||||
parameters:
|
||||
- description: KQL query to filter the list of monitored users
|
||||
in: query
|
||||
name: kql
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_MonitoredUserDoc'
|
||||
type: array
|
||||
description: List of monitored users
|
||||
summary: List all monitored users
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_store/enable:
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
|
@ -74838,6 +75005,65 @@ components:
|
|||
type: string
|
||||
Security_Entity_Analytics_API_Metadata:
|
||||
$ref: '#/components/schemas/Security_Entity_Analytics_API_TransformStatsMetadata'
|
||||
Security_Entity_Analytics_API_MonitoredUserDoc:
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
format: date-time
|
||||
type: string
|
||||
entity_analytics_monitoring:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
type: array
|
||||
event:
|
||||
type: object
|
||||
properties:
|
||||
ingested:
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
labels:
|
||||
type: object
|
||||
properties:
|
||||
monitoring:
|
||||
type: object
|
||||
properties:
|
||||
privileged_users:
|
||||
enum:
|
||||
- monitored
|
||||
- deleted
|
||||
type: string
|
||||
source_indices:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
source_integrations:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
sources:
|
||||
items:
|
||||
enum:
|
||||
- csv
|
||||
- index_sync
|
||||
- api
|
||||
type: array
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
Security_Entity_Analytics_API_MonitoringEngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -75088,6 +75314,15 @@ components:
|
|||
required:
|
||||
- user
|
||||
- entity
|
||||
Security_Entity_Analytics_API_UserName:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: The name of the user.
|
||||
type: string
|
||||
Security_Exceptions_API_CreateExceptionListItemComment:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privilege Monitoring Users Common Schema
|
||||
* version: 1
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
export type UserName = z.infer<typeof UserName>;
|
||||
export const UserName = z.object({
|
||||
user: z
|
||||
.object({
|
||||
/**
|
||||
* The name of the user.
|
||||
*/
|
||||
name: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type MonitoredUserDoc = z.infer<typeof MonitoredUserDoc>;
|
||||
export const MonitoredUserDoc = z.object({
|
||||
id: z.string().optional(),
|
||||
event: z
|
||||
.object({
|
||||
ingested: z.string().datetime().optional(),
|
||||
})
|
||||
.optional(),
|
||||
'@timestamp': z.string().datetime().optional(),
|
||||
user: z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
labels: z
|
||||
.object({
|
||||
monitoring: z
|
||||
.object({
|
||||
privileged_users: z.enum(['monitored', 'deleted']).optional(),
|
||||
})
|
||||
.optional(),
|
||||
sources: z.array(z.unknown()).optional(),
|
||||
source_indices: z.array(z.string()).optional(),
|
||||
source_integrations: z.array(z.string()).optional(),
|
||||
})
|
||||
.optional(),
|
||||
entity_analytics_monitoring: z
|
||||
.object({
|
||||
labels: z
|
||||
.array(
|
||||
z.object({
|
||||
field: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
source: z.string().optional(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
|
@ -0,0 +1,83 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privilege Monitoring Users Common Schema
|
||||
description: Common schema for Privileged Users
|
||||
version: "1"
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
UserName:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The name of the user.
|
||||
|
||||
MonitoredUserDoc:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
|
||||
event:
|
||||
type: object
|
||||
properties:
|
||||
ingested:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
"@timestamp":
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
|
||||
labels:
|
||||
type: object
|
||||
properties:
|
||||
monitoring:
|
||||
type: object
|
||||
properties:
|
||||
privileged_users:
|
||||
type: string
|
||||
enum:
|
||||
- monitored
|
||||
- deleted
|
||||
|
||||
sources:
|
||||
type: array
|
||||
items:
|
||||
enum:
|
||||
- csv
|
||||
- index_sync
|
||||
- api
|
||||
source_indices:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
source_integrations:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
entity_analytics_monitoring:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import type { z } from '@kbn/zod';
|
||||
|
||||
import { UserName, MonitoredUserDoc } from './common.gen';
|
||||
|
||||
export type CreatePrivMonUserRequestBody = z.infer<typeof CreatePrivMonUserRequestBody>;
|
||||
export const CreatePrivMonUserRequestBody = UserName;
|
||||
export type CreatePrivMonUserRequestBodyInput = z.input<typeof CreatePrivMonUserRequestBody>;
|
||||
|
||||
export type CreatePrivMonUserResponse = z.infer<typeof CreatePrivMonUserResponse>;
|
||||
export const CreatePrivMonUserResponse = MonitoredUserDoc;
|
|
@ -0,0 +1,26 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: CreatePrivMonUser
|
||||
summary: Create a new monitored user
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./common.schema.yaml#/components/schemas/UserName"
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: User created successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./common.schema.yaml#/components/schemas/MonitoredUserDoc"
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
export type DeletePrivMonUserRequestParams = z.infer<typeof DeletePrivMonUserRequestParams>;
|
||||
export const DeletePrivMonUserRequestParams = z.object({
|
||||
id: z.string(),
|
||||
});
|
||||
export type DeletePrivMonUserRequestParamsInput = z.input<typeof DeletePrivMonUserRequestParams>;
|
||||
|
||||
export type DeletePrivMonUserResponse = z.infer<typeof DeletePrivMonUserResponse>;
|
||||
export const DeletePrivMonUserResponse = z.object({
|
||||
/**
|
||||
* Indicates if the deletion was successful
|
||||
*/
|
||||
aknowledged: z.boolean().optional(),
|
||||
/**
|
||||
* A message providing additional information about the deletion status
|
||||
*/
|
||||
message: z.string().optional(),
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
delete:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: DeletePrivMonUser
|
||||
summary: Delete a monitored user
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: User deleted successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- success
|
||||
properties:
|
||||
aknowledged:
|
||||
type: boolean
|
||||
description: Indicates if the deletion was successful
|
||||
message:
|
||||
type: string
|
||||
description: A message providing additional information about the deletion status
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { MonitoredUserDoc } from './common.gen';
|
||||
|
||||
export type GetPrivMonUserRequestParams = z.infer<typeof GetPrivMonUserRequestParams>;
|
||||
export const GetPrivMonUserRequestParams = z.object({
|
||||
id: z.string(),
|
||||
});
|
||||
export type GetPrivMonUserRequestParamsInput = z.input<typeof GetPrivMonUserRequestParams>;
|
||||
|
||||
export type GetPrivMonUserResponse = z.infer<typeof GetPrivMonUserResponse>;
|
||||
export const GetPrivMonUserResponse = MonitoredUserDoc;
|
|
@ -0,0 +1,25 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
get:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: GetPrivMonUser
|
||||
summary: Retrieve a monitored user by ID
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: User details retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./common.schema.yaml#/components/schemas/MonitoredUserDoc"
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { MonitoredUserDoc } from './common.gen';
|
||||
|
||||
export type ListPrivMonUsersRequestQuery = z.infer<typeof ListPrivMonUsersRequestQuery>;
|
||||
export const ListPrivMonUsersRequestQuery = z.object({
|
||||
/**
|
||||
* KQL query to filter the list of monitored users
|
||||
*/
|
||||
kql: z.string().optional(),
|
||||
});
|
||||
export type ListPrivMonUsersRequestQueryInput = z.input<typeof ListPrivMonUsersRequestQuery>;
|
||||
|
||||
export type ListPrivMonUsersResponse = z.infer<typeof ListPrivMonUsersResponse>;
|
||||
export const ListPrivMonUsersResponse = z.array(MonitoredUserDoc);
|
|
@ -0,0 +1,28 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/list:
|
||||
get:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: ListPrivMonUsers
|
||||
summary: List all monitored users
|
||||
parameters:
|
||||
- name: kql
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: KQL query to filter the list of monitored users
|
||||
responses:
|
||||
"200":
|
||||
description: List of monitored users
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "./common.schema.yaml#/components/schemas/MonitoredUserDoc"
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { MonitoredUserDoc } from './common.gen';
|
||||
|
||||
export type UpdatePrivMonUserRequestParams = z.infer<typeof UpdatePrivMonUserRequestParams>;
|
||||
export const UpdatePrivMonUserRequestParams = z.object({
|
||||
id: z.string(),
|
||||
});
|
||||
export type UpdatePrivMonUserRequestParamsInput = z.input<typeof UpdatePrivMonUserRequestParams>;
|
||||
|
||||
export type UpdatePrivMonUserRequestBody = z.infer<typeof UpdatePrivMonUserRequestBody>;
|
||||
export const UpdatePrivMonUserRequestBody = MonitoredUserDoc;
|
||||
export type UpdatePrivMonUserRequestBodyInput = z.input<typeof UpdatePrivMonUserRequestBody>;
|
||||
|
||||
export type UpdatePrivMonUserResponse = z.infer<typeof UpdatePrivMonUserResponse>;
|
||||
export const UpdatePrivMonUserResponse = MonitoredUserDoc;
|
|
@ -0,0 +1,32 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
put:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: UpdatePrivMonUser
|
||||
summary: Update a monitored user
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./common.schema.yaml#/components/schemas/MonitoredUserDoc"
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: User updated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./common.schema.yaml#/components/schemas/MonitoredUserDoc"
|
|
@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
export type BulkUploadUsersCSVResponse = z.infer<typeof BulkUploadUsersCSVResponse>;
|
||||
export const BulkUploadUsersCSVResponse = z.object({
|
||||
upserted_count: z.number().int().optional(),
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/_csv:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: BulkUploadUsersCSV
|
||||
summary: Upsert multiple monitored users via CSV upload
|
||||
requestBody:
|
||||
description: CSV file containing users to upsert
|
||||
required: true
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
|
@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Privileged User Monitoring API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
export type BulkUploadUsersJSONResponse = z.infer<typeof BulkUploadUsersJSONResponse>;
|
||||
export const BulkUploadUsersJSONResponse = z.object({
|
||||
upserted_count: z.number().int().optional(),
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Privileged User Monitoring API
|
||||
version: "2023-10-31"
|
||||
|
||||
paths:
|
||||
/api/entity_analytics/monitoring/users/_json:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: BulkUploadUsersJSON
|
||||
summary: Upsert multiple monitored users via JSON upload
|
||||
requestBody:
|
||||
description: JSON file containing users to upsert
|
||||
required: true
|
||||
content:
|
||||
text/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
user_name:
|
||||
type: string
|
||||
is_monitored:
|
||||
type: boolean
|
||||
responses:
|
||||
"200":
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
|
@ -264,6 +264,29 @@ import type {
|
|||
} from './entity_analytics/monitoring/search_indices.gen';
|
||||
import type { InitMonitoringEngineResponse } from './entity_analytics/privilege_monitoring/engine/init.gen';
|
||||
import type { PrivMonHealthResponse } from './entity_analytics/privilege_monitoring/health.gen';
|
||||
import type {
|
||||
CreatePrivMonUserRequestBodyInput,
|
||||
CreatePrivMonUserResponse,
|
||||
} from './entity_analytics/privilege_monitoring/users/create.gen';
|
||||
import type {
|
||||
DeletePrivMonUserRequestParamsInput,
|
||||
DeletePrivMonUserResponse,
|
||||
} from './entity_analytics/privilege_monitoring/users/delete.gen';
|
||||
import type {
|
||||
GetPrivMonUserRequestParamsInput,
|
||||
GetPrivMonUserResponse,
|
||||
} from './entity_analytics/privilege_monitoring/users/get.gen';
|
||||
import type {
|
||||
ListPrivMonUsersRequestQueryInput,
|
||||
ListPrivMonUsersResponse,
|
||||
} from './entity_analytics/privilege_monitoring/users/list.gen';
|
||||
import type {
|
||||
UpdatePrivMonUserRequestParamsInput,
|
||||
UpdatePrivMonUserRequestBodyInput,
|
||||
UpdatePrivMonUserResponse,
|
||||
} from './entity_analytics/privilege_monitoring/users/update.gen';
|
||||
import type { BulkUploadUsersCSVResponse } from './entity_analytics/privilege_monitoring/users/upload_csv.gen';
|
||||
import type { BulkUploadUsersJSONResponse } from './entity_analytics/privilege_monitoring/users/upload_json.gen';
|
||||
import type { CleanUpRiskEngineResponse } from './entity_analytics/risk_engine/engine_cleanup_route.gen';
|
||||
import type {
|
||||
ConfigureRiskEngineSavedObjectRequestBodyInput,
|
||||
|
@ -460,6 +483,30 @@ after 30 days. It also deletes other artifacts specific to the migration impleme
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async bulkUploadUsersCsv() {
|
||||
this.log.info(`${new Date().toISOString()} Calling API BulkUploadUsersCSV`);
|
||||
return this.kbnClient
|
||||
.request<BulkUploadUsersCSVResponse>({
|
||||
path: '/api/entity_analytics/monitoring/users/_csv',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async bulkUploadUsersJson() {
|
||||
this.log.info(`${new Date().toISOString()} Calling API BulkUploadUsersJSON`);
|
||||
return this.kbnClient
|
||||
.request<BulkUploadUsersJSONResponse>({
|
||||
path: '/api/entity_analytics/monitoring/users/_json',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Bulk upsert up to 1000 asset criticality records.
|
||||
|
||||
|
@ -595,6 +642,19 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async createPrivMonUser(props: CreatePrivMonUserProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API CreatePrivMonUser`);
|
||||
return this.kbnClient
|
||||
.request<CreatePrivMonUserResponse>({
|
||||
path: '/api/entity_analytics/monitoring/users',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Create a new detection rule.
|
||||
> warn
|
||||
|
@ -772,6 +832,18 @@ For detailed information on Kibana actions and alerting, and additional API call
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async deletePrivMonUser(props: DeletePrivMonUserProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API DeletePrivMonUser`);
|
||||
return this.kbnClient
|
||||
.request<DeletePrivMonUserResponse>({
|
||||
path: replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'DELETE',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Delete a detection rule using the `rule_id` or `id` field.
|
||||
|
||||
|
@ -1347,6 +1419,18 @@ finalize it.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async getPrivMonUser(props: GetPrivMonUserProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API GetPrivMonUser`);
|
||||
return this.kbnClient
|
||||
.request<GetPrivMonUserResponse>({
|
||||
path: replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async getProtectionUpdatesNote(props: GetProtectionUpdatesNoteProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API GetProtectionUpdatesNote`);
|
||||
return this.kbnClient
|
||||
|
@ -1797,6 +1881,20 @@ providing you with the most current and effective threat detection capabilities.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async listPrivMonUsers(props: ListPrivMonUsersProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API ListPrivMonUsers`);
|
||||
return this.kbnClient
|
||||
.request<ListPrivMonUsersResponse>({
|
||||
path: '/api/entity_analytics/monitoring/users/list',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
|
||||
query: props.query,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Update specific fields of an existing detection rule using the `rule_id` or `id` field.
|
||||
|
||||
|
@ -2298,6 +2396,19 @@ The difference between the `id` and `rule_id` is that the `id` is a unique rule
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async updatePrivMonUser(props: UpdatePrivMonUserProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API UpdatePrivMonUser`);
|
||||
return this.kbnClient
|
||||
.request<UpdatePrivMonUserResponse>({
|
||||
path: replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'PUT',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Update a detection rule using the `rule_id` or `id` field. The original rule is replaced, and all unspecified fields are deleted.
|
||||
|
||||
|
@ -2405,6 +2516,9 @@ export interface CreateAlertsMigrationProps {
|
|||
export interface CreateAssetCriticalityRecordProps {
|
||||
body: CreateAssetCriticalityRecordRequestBodyInput;
|
||||
}
|
||||
export interface CreatePrivMonUserProps {
|
||||
body: CreatePrivMonUserRequestBodyInput;
|
||||
}
|
||||
export interface CreateRuleProps {
|
||||
body: CreateRuleRequestBodyInput;
|
||||
}
|
||||
|
@ -2429,6 +2543,9 @@ export interface DeleteEntityEngineProps {
|
|||
export interface DeleteNoteProps {
|
||||
body: DeleteNoteRequestBodyInput;
|
||||
}
|
||||
export interface DeletePrivMonUserProps {
|
||||
params: DeletePrivMonUserRequestParamsInput;
|
||||
}
|
||||
export interface DeleteRuleProps {
|
||||
query: DeleteRuleRequestQueryInput;
|
||||
}
|
||||
|
@ -2522,6 +2639,9 @@ export interface GetNotesProps {
|
|||
export interface GetPolicyResponseProps {
|
||||
query: GetPolicyResponseRequestQueryInput;
|
||||
}
|
||||
export interface GetPrivMonUserProps {
|
||||
params: GetPrivMonUserRequestParamsInput;
|
||||
}
|
||||
export interface GetProtectionUpdatesNoteProps {
|
||||
params: GetProtectionUpdatesNoteRequestParamsInput;
|
||||
}
|
||||
|
@ -2589,6 +2709,9 @@ export interface InternalUploadAssetCriticalityRecordsProps {
|
|||
export interface ListEntitiesProps {
|
||||
query: ListEntitiesRequestQueryInput;
|
||||
}
|
||||
export interface ListPrivMonUsersProps {
|
||||
query: ListPrivMonUsersRequestQueryInput;
|
||||
}
|
||||
export interface PatchRuleProps {
|
||||
body: PatchRuleRequestBodyInput;
|
||||
}
|
||||
|
@ -2661,6 +2784,10 @@ export interface SuggestUserProfilesProps {
|
|||
export interface TriggerRiskScoreCalculationProps {
|
||||
body: TriggerRiskScoreCalculationRequestBodyInput;
|
||||
}
|
||||
export interface UpdatePrivMonUserProps {
|
||||
params: UpdatePrivMonUserRequestParamsInput;
|
||||
body: UpdatePrivMonUserRequestBodyInput;
|
||||
}
|
||||
export interface UpdateRuleProps {
|
||||
body: UpdateRuleRequestBodyInput;
|
||||
}
|
||||
|
|
|
@ -335,6 +335,175 @@ paths:
|
|||
summary: Health check on Privilege Monitoring
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users:
|
||||
post:
|
||||
operationId: CreatePrivMonUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserName'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User created successfully
|
||||
summary: Create a new monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_csv:
|
||||
post:
|
||||
operationId: BulkUploadUsersCSV
|
||||
requestBody:
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
description: CSV file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via CSV upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_json:
|
||||
post:
|
||||
operationId: BulkUploadUsersJSON
|
||||
requestBody:
|
||||
content:
|
||||
text/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
is_monitored:
|
||||
type: boolean
|
||||
user_name:
|
||||
type: string
|
||||
type: array
|
||||
description: JSON file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via JSON upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
delete:
|
||||
operationId: DeletePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
aknowledged:
|
||||
description: Indicates if the deletion was successful
|
||||
type: boolean
|
||||
message:
|
||||
description: >-
|
||||
A message providing additional information about the
|
||||
deletion status
|
||||
type: string
|
||||
required:
|
||||
- success
|
||||
description: User deleted successfully
|
||||
summary: Delete a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
get:
|
||||
operationId: GetPrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User details retrieved
|
||||
summary: Retrieve a monitored user by ID
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
put:
|
||||
operationId: UpdatePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User updated successfully
|
||||
summary: Update a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/list:
|
||||
get:
|
||||
operationId: ListPrivMonUsers
|
||||
parameters:
|
||||
- description: KQL query to filter the list of monitored users
|
||||
in: query
|
||||
name: kql
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
type: array
|
||||
description: List of monitored users
|
||||
summary: List all monitored users
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_store/enable:
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
|
@ -1420,6 +1589,65 @@ components:
|
|||
type: string
|
||||
Metadata:
|
||||
$ref: '#/components/schemas/TransformStatsMetadata'
|
||||
MonitoredUserDoc:
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
format: date-time
|
||||
type: string
|
||||
entity_analytics_monitoring:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
type: array
|
||||
event:
|
||||
type: object
|
||||
properties:
|
||||
ingested:
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
labels:
|
||||
type: object
|
||||
properties:
|
||||
monitoring:
|
||||
type: object
|
||||
properties:
|
||||
privileged_users:
|
||||
enum:
|
||||
- monitored
|
||||
- deleted
|
||||
type: string
|
||||
source_indices:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
source_integrations:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
sources:
|
||||
items:
|
||||
enum:
|
||||
- csv
|
||||
- index_sync
|
||||
- api
|
||||
type: array
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
MonitoringEngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1670,6 +1898,15 @@ components:
|
|||
required:
|
||||
- user
|
||||
- entity
|
||||
UserName:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: The name of the user.
|
||||
type: string
|
||||
securitySchemes:
|
||||
BasicAuth:
|
||||
scheme: basic
|
||||
|
|
|
@ -335,6 +335,175 @@ paths:
|
|||
summary: Health check on Privilege Monitoring
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users:
|
||||
post:
|
||||
operationId: CreatePrivMonUser
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserName'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User created successfully
|
||||
summary: Create a new monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_csv:
|
||||
post:
|
||||
operationId: BulkUploadUsersCSV
|
||||
requestBody:
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
description: CSV file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via CSV upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/_json:
|
||||
post:
|
||||
operationId: BulkUploadUsersJSON
|
||||
requestBody:
|
||||
content:
|
||||
text/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
is_monitored:
|
||||
type: boolean
|
||||
user_name:
|
||||
type: string
|
||||
type: array
|
||||
description: JSON file containing users to upsert
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
upserted_count:
|
||||
type: integer
|
||||
description: Successful response
|
||||
summary: Upsert multiple monitored users via JSON upload
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/{id}:
|
||||
delete:
|
||||
operationId: DeletePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
aknowledged:
|
||||
description: Indicates if the deletion was successful
|
||||
type: boolean
|
||||
message:
|
||||
description: >-
|
||||
A message providing additional information about the
|
||||
deletion status
|
||||
type: string
|
||||
required:
|
||||
- success
|
||||
description: User deleted successfully
|
||||
summary: Delete a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
get:
|
||||
operationId: GetPrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User details retrieved
|
||||
summary: Retrieve a monitored user by ID
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
put:
|
||||
operationId: UpdatePrivMonUser
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
description: User updated successfully
|
||||
summary: Update a monitored user
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_analytics/monitoring/users/list:
|
||||
get:
|
||||
operationId: ListPrivMonUsers
|
||||
parameters:
|
||||
- description: KQL query to filter the list of monitored users
|
||||
in: query
|
||||
name: kql
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/MonitoredUserDoc'
|
||||
type: array
|
||||
description: List of monitored users
|
||||
summary: List all monitored users
|
||||
tags:
|
||||
- Security Entity Analytics API
|
||||
/api/entity_store/enable:
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
|
@ -1420,6 +1589,65 @@ components:
|
|||
type: string
|
||||
Metadata:
|
||||
$ref: '#/components/schemas/TransformStatsMetadata'
|
||||
MonitoredUserDoc:
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
format: date-time
|
||||
type: string
|
||||
entity_analytics_monitoring:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
source:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
type: array
|
||||
event:
|
||||
type: object
|
||||
properties:
|
||||
ingested:
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
labels:
|
||||
type: object
|
||||
properties:
|
||||
monitoring:
|
||||
type: object
|
||||
properties:
|
||||
privileged_users:
|
||||
enum:
|
||||
- monitored
|
||||
- deleted
|
||||
type: string
|
||||
source_indices:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
source_integrations:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
sources:
|
||||
items:
|
||||
enum:
|
||||
- csv
|
||||
- index_sync
|
||||
- api
|
||||
type: array
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
MonitoringEngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1670,6 +1898,15 @@ components:
|
|||
required:
|
||||
- user
|
||||
- entity
|
||||
UserName:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
description: The name of the user.
|
||||
type: string
|
||||
securitySchemes:
|
||||
BasicAuth:
|
||||
scheme: basic
|
||||
|
|
|
@ -9,6 +9,7 @@ import type { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
|
|||
|
||||
// Static index names: may be more obvious and easier to manage.
|
||||
export const privilegedMonitorBaseIndexName = '.entity_analytics.monitoring';
|
||||
|
||||
// Used in Phase 0.
|
||||
export const getPrivilegedMonitorUsersIndex = (namespace: string) =>
|
||||
`${privilegedMonitorBaseIndexName}.users-${namespace}`;
|
||||
|
|
|
@ -17,7 +17,16 @@ import type {
|
|||
|
||||
import type { TaskManagerStartContract } from '@kbn/task-manager-plugin/server';
|
||||
import moment from 'moment';
|
||||
import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query';
|
||||
import { merge } from 'lodash';
|
||||
import type { UpdatePrivMonUserRequestBody } from '../../../../common/api/entity_analytics/privilege_monitoring/users/update.gen';
|
||||
|
||||
import type {
|
||||
CreatePrivMonUserRequestBody,
|
||||
CreatePrivMonUserResponse,
|
||||
} from '../../../../common/api/entity_analytics/privilege_monitoring/users/create.gen';
|
||||
import type { InitMonitoringEngineResponse } from '../../../../common/api/entity_analytics/privilege_monitoring/engine/init.gen';
|
||||
import type { MonitoredUserDoc } from '../../../../common/api/entity_analytics/privilege_monitoring/users/common.gen';
|
||||
import {
|
||||
EngineComponentResourceEnum,
|
||||
type EngineComponentResource,
|
||||
|
@ -38,6 +47,7 @@ import {
|
|||
PRIVMON_ENGINE_INITIALIZATION_EVENT,
|
||||
PRIVMON_ENGINE_RESOURCE_INIT_FAILURE_EVENT,
|
||||
} from '../../telemetry/event_based/events';
|
||||
import type { PrivMonUserSource } from './types';
|
||||
|
||||
interface PrivilegeMonitoringClientOpts {
|
||||
logger: Logger;
|
||||
|
@ -54,10 +64,12 @@ interface PrivilegeMonitoringClientOpts {
|
|||
export class PrivilegeMonitoringDataClient {
|
||||
private apiKeyGenerator?: ApiKeyManager;
|
||||
private esClient: ElasticsearchClient;
|
||||
private internalUserClient: ElasticsearchClient;
|
||||
private engineClient: PrivilegeMonitoringEngineDescriptorClient;
|
||||
|
||||
constructor(private readonly opts: PrivilegeMonitoringClientOpts) {
|
||||
this.esClient = opts.clusterClient.asCurrentUser;
|
||||
this.internalUserClient = opts.clusterClient.asInternalUser;
|
||||
this.apiKeyGenerator = opts.apiKeyManager;
|
||||
this.engineClient = new PrivilegeMonitoringEngineDescriptorClient({
|
||||
soClient: opts.soClient,
|
||||
|
@ -130,11 +142,14 @@ export class PrivilegeMonitoringDataClient {
|
|||
|
||||
public async createOrUpdateIndex() {
|
||||
await createOrUpdateIndex({
|
||||
esClient: this.esClient,
|
||||
esClient: this.internalUserClient,
|
||||
logger: this.opts.logger,
|
||||
options: {
|
||||
index: this.getIndex(),
|
||||
mappings: generateUserIndexMappings(),
|
||||
settings: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -165,6 +180,71 @@ export class PrivilegeMonitoringDataClient {
|
|||
return getPrivilegedMonitorUsersIndex(this.opts.namespace);
|
||||
}
|
||||
|
||||
public async createUser(
|
||||
user: CreatePrivMonUserRequestBody,
|
||||
source: PrivMonUserSource
|
||||
): Promise<CreatePrivMonUserResponse> {
|
||||
const doc = merge(user, {
|
||||
labels: {
|
||||
monitoring: { privileged_users: 'monitored' },
|
||||
sources: [source],
|
||||
},
|
||||
});
|
||||
const res = await this.esClient.index({
|
||||
index: this.getIndex(),
|
||||
refresh: 'wait_for',
|
||||
document: doc,
|
||||
});
|
||||
|
||||
const newUser = await this.getUser(res._id);
|
||||
if (!newUser) {
|
||||
throw new Error(`Failed to create user: ${res._id}`);
|
||||
}
|
||||
return newUser;
|
||||
}
|
||||
|
||||
public async getUser(id: string): Promise<MonitoredUserDoc | undefined> {
|
||||
const response = await this.esClient.get<MonitoredUserDoc>({
|
||||
index: this.getIndex(),
|
||||
id,
|
||||
});
|
||||
return response.found
|
||||
? ({ ...response._source, id: response._id } as MonitoredUserDoc)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
public async updateUser(
|
||||
id: string,
|
||||
user: UpdatePrivMonUserRequestBody
|
||||
): Promise<MonitoredUserDoc | undefined> {
|
||||
await this.esClient.update<MonitoredUserDoc>({
|
||||
index: this.getIndex(),
|
||||
refresh: 'wait_for',
|
||||
id,
|
||||
doc: user,
|
||||
});
|
||||
return this.getUser(id);
|
||||
}
|
||||
|
||||
public async deleteUser(id: string): Promise<void> {
|
||||
await this.esClient.delete({
|
||||
index: this.getIndex(),
|
||||
id,
|
||||
});
|
||||
}
|
||||
|
||||
public async listUsers(kuery?: string): Promise<MonitoredUserDoc[]> {
|
||||
const query = kuery ? toElasticsearchQuery(fromKueryExpression(kuery)) : { match_all: {} };
|
||||
const response = await this.esClient.search({
|
||||
index: this.getIndex(),
|
||||
query,
|
||||
});
|
||||
return response.hits.hits.map((hit) => ({
|
||||
id: hit._id,
|
||||
...(hit._source as {}),
|
||||
})) as MonitoredUserDoc[];
|
||||
}
|
||||
|
||||
private log(level: Exclude<keyof Logger, 'get' | 'log' | 'isLevelEnabled'>, msg: string) {
|
||||
this.opts.logger[level](
|
||||
`[Privileged Monitoring Engine][namespace: ${this.opts.namespace}] ${msg}`
|
||||
|
|
|
@ -10,13 +10,29 @@ import { healthCheckPrivilegeMonitoringRoute } from './health';
|
|||
import { initPrivilegeMonitoringEngineRoute } from './init';
|
||||
import { searchPrivilegeMonitoringIndicesRoute } from './search_indices';
|
||||
|
||||
import {
|
||||
getUserRoute,
|
||||
createUserRoute,
|
||||
deleteUserRoute,
|
||||
listUsersRoute,
|
||||
updateUserRoute,
|
||||
uploadUsersCSVRoute,
|
||||
uploadUsersJSONRoute,
|
||||
} from './users';
|
||||
|
||||
export const registerPrivilegeMonitoringRoutes = ({
|
||||
router,
|
||||
logger,
|
||||
getStartServices,
|
||||
config,
|
||||
}: EntityAnalyticsRoutesDeps) => {
|
||||
initPrivilegeMonitoringEngineRoute(router, logger, config);
|
||||
healthCheckPrivilegeMonitoringRoute(router, logger, config);
|
||||
searchPrivilegeMonitoringIndicesRoute(router, logger, config);
|
||||
getUserRoute(router, logger);
|
||||
createUserRoute(router, logger);
|
||||
deleteUserRoute(router, logger);
|
||||
listUsersRoute(router, logger);
|
||||
updateUserRoute(router, logger);
|
||||
uploadUsersCSVRoute(router, logger);
|
||||
uploadUsersJSONRoute(router, logger);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import { CreatePrivMonUserRequestBody } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/create.gen';
|
||||
import type { CreatePrivMonUserResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/create.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const createUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
body: CreatePrivMonUserRequestBody,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<CreatePrivMonUserResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol
|
||||
.getPrivilegeMonitoringDataClient()
|
||||
.createUser(request.body, 'api');
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error creating user: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import { DeletePrivMonUserRequestParams } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/delete.gen';
|
||||
import type { DeletePrivMonUserResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/delete.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const deleteUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => {
|
||||
router.versioned
|
||||
.delete({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/{id}',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: DeletePrivMonUserRequestParams,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<DeletePrivMonUserResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
await secSol.getPrivilegeMonitoringDataClient().deleteUser(request.params.id);
|
||||
return response.ok({ body: { aknowledged: true } });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error deleting user: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import { GetPrivMonUserRequestParams } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/get.gen';
|
||||
import type { GetPrivMonUserResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/get.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const getUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => {
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/{id}',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: GetPrivMonUserRequestParams,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<GetPrivMonUserResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol.getPrivilegeMonitoringDataClient().getUser(request.params.id);
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error retrieving user: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './create';
|
||||
export * from './get';
|
||||
export * from './list';
|
||||
export * from './update';
|
||||
export * from './delete';
|
||||
export * from './upload_json';
|
||||
export * from './upload_csv';
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import { ListPrivMonUsersRequestQuery } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/list.gen';
|
||||
import type { ListPrivMonUsersResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/list.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const listUsersRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => {
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/list',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
query: ListPrivMonUsersRequestQuery,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<ListPrivMonUsersResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol.getPrivilegeMonitoringDataClient().listUsers(request.query.kql);
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error listing users: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import {
|
||||
UpdatePrivMonUserRequestParams,
|
||||
UpdatePrivMonUserRequestBody,
|
||||
} from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/update.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => {
|
||||
router.versioned
|
||||
.put({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/{id}',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: UpdatePrivMonUserRequestParams,
|
||||
body: UpdatePrivMonUserRequestBody,
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol
|
||||
.getPrivilegeMonitoringDataClient()
|
||||
.updateUser(request.params.id, request.body);
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error updating user: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import type { BulkUploadUsersCSVResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/upload_csv.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const uploadUsersCSVRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/_csv',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<BulkUploadUsersCSVResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
// Placeholder for actual implementation
|
||||
return response.ok({ body: { upserted_count: 15 } });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error uploading users via CSV: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import type { BulkUploadUsersJSONResponse } from '../../../../../../common/api/entity_analytics/privilege_monitoring/users/upload_json.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../../types';
|
||||
|
||||
export const uploadUsersJSONRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_analytics/monitoring/users/_json',
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`],
|
||||
},
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {},
|
||||
},
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<BulkUploadUsersJSONResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
// Placeholder for actual implementation
|
||||
return response.ok({ body: { upserted_count: 10 } });
|
||||
} catch (e) {
|
||||
const error = transformError(e);
|
||||
logger.error(`Error uploading users via JSON: ${error.message}`);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 type PrivMonUserSource = 'csv' | 'api' | 'index_sync';
|
|
@ -27,6 +27,7 @@ import { ConfigureRiskEngineSavedObjectRequestBodyInput } from '@kbn/security-so
|
|||
import { CopyTimelineRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/copy_timeline/copy_timeline_route.gen';
|
||||
import { CreateAlertsMigrationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/signals_migration/create_signals_migration/create_signals_migration.gen';
|
||||
import { CreateAssetCriticalityRecordRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/asset_criticality/create_asset_criticality.gen';
|
||||
import { CreatePrivMonUserRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/privilege_monitoring/users/create.gen';
|
||||
import { CreateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen';
|
||||
import {
|
||||
CreateRuleMigrationRequestParamsInput,
|
||||
|
@ -43,6 +44,7 @@ import {
|
|||
DeleteEntityEngineRequestParamsInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/delete.gen';
|
||||
import { DeleteNoteRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_note/delete_note_route.gen';
|
||||
import { DeletePrivMonUserRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/privilege_monitoring/users/delete.gen';
|
||||
import { DeleteRuleRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen';
|
||||
import { DeleteTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_timelines/delete_timelines_route.gen';
|
||||
import { DeprecatedTriggerRiskScoreCalculationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/risk_engine/entity_calculation_route.gen';
|
||||
|
@ -81,6 +83,7 @@ import { GetEntityEngineRequestParamsInput } from '@kbn/security-solution-plugin
|
|||
import { GetEntityStoreStatusRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/status.gen';
|
||||
import { GetNotesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_notes/get_notes_route.gen';
|
||||
import { GetPolicyResponseRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy_response.gen';
|
||||
import { GetPrivMonUserRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/privilege_monitoring/users/get.gen';
|
||||
import { GetProtectionUpdatesNoteRequestParamsInput } from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen';
|
||||
import {
|
||||
GetRuleExecutionEventsRequestQueryInput,
|
||||
|
@ -118,6 +121,7 @@ import {
|
|||
} from '@kbn/security-solution-plugin/common/siem_migrations/model/api/rules/rule_migration.gen';
|
||||
import { InstallPrepackedTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen';
|
||||
import { ListEntitiesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/entities/list_entities.gen';
|
||||
import { ListPrivMonUsersRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/privilege_monitoring/users/list.gen';
|
||||
import { PatchRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen';
|
||||
import { PatchTimelineRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/patch_timelines/patch_timeline_route.gen';
|
||||
import {
|
||||
|
@ -150,6 +154,10 @@ import { StopEntityEngineRequestParamsInput } from '@kbn/security-solution-plugi
|
|||
import { StopRuleMigrationRequestParamsInput } from '@kbn/security-solution-plugin/common/siem_migrations/model/api/rules/rule_migration.gen';
|
||||
import { SuggestUserProfilesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/users/suggest_user_profiles_route.gen';
|
||||
import { TriggerRiskScoreCalculationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/risk_engine/entity_calculation_route.gen';
|
||||
import {
|
||||
UpdatePrivMonUserRequestParamsInput,
|
||||
UpdatePrivMonUserRequestBodyInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/entity_analytics/privilege_monitoring/users/update.gen';
|
||||
import { UpdateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen';
|
||||
import {
|
||||
UpdateRuleMigrationRequestParamsInput,
|
||||
|
@ -214,6 +222,20 @@ after 30 days. It also deletes other artifacts specific to the migration impleme
|
|||
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
bulkUploadUsersCsv(kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.post(routeWithNamespace('/api/entity_analytics/monitoring/users/_csv', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
bulkUploadUsersJson(kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.post(routeWithNamespace('/api/entity_analytics/monitoring/users/_json', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
/**
|
||||
* Bulk upsert up to 1000 asset criticality records.
|
||||
|
||||
|
@ -318,6 +340,14 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
createPrivMonUser(props: CreatePrivMonUserProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.post(routeWithNamespace('/api/entity_analytics/monitoring/users', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Create a new detection rule.
|
||||
> warn
|
||||
|
@ -474,6 +504,18 @@ For detailed information on Kibana actions and alerting, and additional API call
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
deletePrivMonUser(props: DeletePrivMonUserProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.delete(
|
||||
routeWithNamespace(
|
||||
replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
kibanaSpace
|
||||
)
|
||||
)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
/**
|
||||
* Delete a detection rule using the `rule_id` or `id` field.
|
||||
|
||||
|
@ -903,6 +945,18 @@ finalize it.
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
getPrivMonUser(props: GetPrivMonUserProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.get(
|
||||
routeWithNamespace(
|
||||
replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
kibanaSpace
|
||||
)
|
||||
)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
getProtectionUpdatesNote(
|
||||
props: GetProtectionUpdatesNoteProps,
|
||||
kibanaSpace: string = 'default'
|
||||
|
@ -1278,6 +1332,14 @@ providing you with the most current and effective threat detection capabilities.
|
|||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
listPrivMonUsers(props: ListPrivMonUsersProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.get(routeWithNamespace('/api/entity_analytics/monitoring/users/list', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
/**
|
||||
* Update specific fields of an existing detection rule using the `rule_id` or `id` field.
|
||||
|
||||
|
@ -1645,6 +1707,19 @@ The difference between the `id` and `rule_id` is that the `id` is a unique rule
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
updatePrivMonUser(props: UpdatePrivMonUserProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.put(
|
||||
routeWithNamespace(
|
||||
replaceParams('/api/entity_analytics/monitoring/users/{id}', props.params),
|
||||
kibanaSpace
|
||||
)
|
||||
)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Update a detection rule using the `rule_id` or `id` field. The original rule is replaced, and all unspecified fields are deleted.
|
||||
|
||||
|
@ -1742,6 +1817,9 @@ export interface CreateAlertsMigrationProps {
|
|||
export interface CreateAssetCriticalityRecordProps {
|
||||
body: CreateAssetCriticalityRecordRequestBodyInput;
|
||||
}
|
||||
export interface CreatePrivMonUserProps {
|
||||
body: CreatePrivMonUserRequestBodyInput;
|
||||
}
|
||||
export interface CreateRuleProps {
|
||||
body: CreateRuleRequestBodyInput;
|
||||
}
|
||||
|
@ -1766,6 +1844,9 @@ export interface DeleteEntityEngineProps {
|
|||
export interface DeleteNoteProps {
|
||||
body: DeleteNoteRequestBodyInput;
|
||||
}
|
||||
export interface DeletePrivMonUserProps {
|
||||
params: DeletePrivMonUserRequestParamsInput;
|
||||
}
|
||||
export interface DeleteRuleProps {
|
||||
query: DeleteRuleRequestQueryInput;
|
||||
}
|
||||
|
@ -1856,6 +1937,9 @@ export interface GetNotesProps {
|
|||
export interface GetPolicyResponseProps {
|
||||
query: GetPolicyResponseRequestQueryInput;
|
||||
}
|
||||
export interface GetPrivMonUserProps {
|
||||
params: GetPrivMonUserRequestParamsInput;
|
||||
}
|
||||
export interface GetProtectionUpdatesNoteProps {
|
||||
params: GetProtectionUpdatesNoteRequestParamsInput;
|
||||
}
|
||||
|
@ -1919,6 +2003,9 @@ export interface InstallPrepackedTimelinesProps {
|
|||
export interface ListEntitiesProps {
|
||||
query: ListEntitiesRequestQueryInput;
|
||||
}
|
||||
export interface ListPrivMonUsersProps {
|
||||
query: ListPrivMonUsersRequestQueryInput;
|
||||
}
|
||||
export interface PatchRuleProps {
|
||||
body: PatchRuleRequestBodyInput;
|
||||
}
|
||||
|
@ -1991,6 +2078,10 @@ export interface SuggestUserProfilesProps {
|
|||
export interface TriggerRiskScoreCalculationProps {
|
||||
body: TriggerRiskScoreCalculationRequestBodyInput;
|
||||
}
|
||||
export interface UpdatePrivMonUserProps {
|
||||
params: UpdatePrivMonUserRequestParamsInput;
|
||||
body: UpdatePrivMonUserRequestBodyInput;
|
||||
}
|
||||
export interface UpdateRuleProps {
|
||||
body: UpdateRuleRequestBodyInput;
|
||||
}
|
||||
|
|
|
@ -11,5 +11,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
describe('Entity Analytics - Privilege Monitoring', function () {
|
||||
loadTestFile(require.resolve('./engine'));
|
||||
loadTestFile(require.resolve('./search_indices'));
|
||||
loadTestFile(require.resolve('./privileged_users/api'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
import { dataViewRouteHelpersFactory } from '../../../utils/data_view';
|
||||
import { PrivMonUtils } from './utils';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const api = getService('securitySolutionApi');
|
||||
const supertest = getService('supertest');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
const privMonUtils = PrivMonUtils(getService);
|
||||
|
||||
describe('@ess @serverless @skipInServerlessMKI Entity Monitoring Privileged Users CRUD APIs', () => {
|
||||
const dataView = dataViewRouteHelpersFactory(supertest);
|
||||
before(async () => {
|
||||
await dataView.create('security-solution');
|
||||
await privMonUtils.initPrivMonEngine();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await dataView.delete('security-solution');
|
||||
});
|
||||
|
||||
describe('CRUD API', () => {
|
||||
it('should create a user', async () => {
|
||||
log.info(`creating a user`);
|
||||
const res = await api.createPrivMonUser({
|
||||
body: { user: { name: 'test_user1' } },
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Creating privmon user failed`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).eql(200);
|
||||
expect(res.body);
|
||||
});
|
||||
|
||||
it('should retrieve a user', async () => {
|
||||
log.info(`retrieving a user`);
|
||||
const { body } = await api.createPrivMonUser({
|
||||
body: { user: { name: 'test_user2' } },
|
||||
});
|
||||
|
||||
const res = await api.getPrivMonUser({ params: { id: body.id } });
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Retrieving privmon user failed`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).eql(200);
|
||||
});
|
||||
|
||||
it('should update a user', async () => {
|
||||
log.info(`updating a user`);
|
||||
const { body } = await api.createPrivMonUser({
|
||||
body: { user: { name: 'test_user3' } },
|
||||
});
|
||||
const res = await api.updatePrivMonUser({
|
||||
body: { user: { name: 'updated' } },
|
||||
params: { id: body.id },
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Updating privmon user failed`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).eql(200);
|
||||
expect(res.body.user.name).to.be('updated');
|
||||
});
|
||||
|
||||
it('should list users', async () => {
|
||||
log.info(`listing users`);
|
||||
|
||||
const { body } = await api.createPrivMonUser({
|
||||
body: { user: { name: 'test_user4' } },
|
||||
});
|
||||
|
||||
// Ensure the data is indexed and available for searching, in case we ever remove `refresh: wait_for` when indexing
|
||||
await es.indices.refresh({ index: body._index });
|
||||
|
||||
const res = await api.listPrivMonUsers({ query: { kql: `user.name: test*` } });
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Listing privmon users failed`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).eql(200);
|
||||
expect(res.body.length).to.be.greaterThan(0);
|
||||
});
|
||||
it('should delete a user', async () => {
|
||||
log.info(`deleting a user`);
|
||||
const { body } = await api.createPrivMonUser({
|
||||
body: { user: { name: 'test_user5' } },
|
||||
});
|
||||
const res = await api.deletePrivMonUser({ params: { id: body.id } });
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Deleting privmon user failed`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).eql(200);
|
||||
expect(res.body).to.eql({ aknowledged: true });
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
export const PrivMonUtils = (
|
||||
getService: FtrProviderContext['getService'],
|
||||
namespace: string = 'default'
|
||||
) => {
|
||||
const api = getService('securitySolutionApi');
|
||||
const log = getService('log');
|
||||
|
||||
log.info(`Monitoring: Privileged Users: Using namespace ${namespace}`);
|
||||
|
||||
const initPrivMonEngine = async () => {
|
||||
log.info(`Initializing Privilege Monitoring engine in namespace ${namespace || 'default'}`);
|
||||
const res = await api.initMonitoringEngine(namespace);
|
||||
|
||||
if (res.status !== 200) {
|
||||
log.error(`Failed to initialize engine`);
|
||||
log.error(JSON.stringify(res.body));
|
||||
}
|
||||
|
||||
expect(res.status).to.eql(200);
|
||||
};
|
||||
|
||||
const retry = async <T>(fn: () => Promise<T>, retries: number = 5, delay: number = 1000) => {
|
||||
for (let i = 0; i < retries; i++) {
|
||||
try {
|
||||
return await fn();
|
||||
} catch (error) {
|
||||
if (i === retries - 1) {
|
||||
throw error;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { initPrivMonEngine, retry };
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue