Skip to content

Commit

Permalink
[8.x] [SecuritySolution] Update Entity analytics BE to support servic…
Browse files Browse the repository at this point in the history
…e entity type (elastic#203409) (elastic#205384)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[SecuritySolution] Update Entity analytics BE to support service
entity type (elastic#203409)](elastic#203409)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Pablo
Machado","email":"pablo.nevesmachado@elastic.co"},"sourceCommit":{"committedDate":"2025-01-02T12:50:08Z","message":"[SecuritySolution]
Update Entity analytics BE to support service entity type
(elastic#203409)\n\n## Summary\n\nUpdate Entity Analytics BE to support the new
entity type \"service\".\n* Hide all functionality behind an
Experimental Flag\n(`serviceEntityStoreEnabled`)\n* Update asset
criticality assignment\n* Update Bulk upload logic\n* Update Risk score
calculation\n* Create plugin setup mappings migration\n * Add service to
risk score indices and templates\n * Add service to asset criticality
index\n* Create a reusable migration workflow where we only need to
update the\nmappings and bump the version\n* Add a risk score transform
migration when the schedule is now called\n * It will delete and
reinstall the transform to apply the changes \n\n### issues\n* I had to
update the API doc to include service even though it is\nbehind an
Experimental Flag\n* The risk scope mappings migration runs on every
space. If the users\nhave thousands of spaces, it could take some
time.\n\n### What is not included?\n* UI changes\n\n\n## Documentation
for Entity Analytics future migrations\n\n### How to add a new field to
the risk score index and template\nmappings?\n* Update the mapping
object\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L102)\n*
Pump the `mappingsVersion`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts#L31)\n\n###
How to add a new field to the asset criticality index?\n* Update the
mapping
object\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L22)\n*
Pump the `ASSET_CRITICALITY_MAPPINGS_VERSIONS`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L20)\n\n###
How to update the risk score transform config?\n* Update the transform
config\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L162)\n*
Pump the
`version`\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L190)\n\n*note:
If you change the `latest` property, the transform will reinstall\nafter
the engine task runs\n\n## How to test it?\n* Enable the fla
`serviceEntityStoreEnabled`\n* Start ES and an old version of Kibana\n*
Populate it with data, start the risk engine\n * You could also run the
document generator `yarn start entity-store` \n* Make sure you have some
alerts with `service.name` field populated\n* Migrate to the version on
this PR\n* Run the risk engine\n* You should see risk score documents
created for service entities\n* All asset criticality API should support
`service` entities\n\n## Checklist\n- [x] Any text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\n-
[x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"1fbd86f199c738790bf53b92fd249abfbaed84f7","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:
SecuritySolution","Theme: entity_analytics","Feature:Entity
Analytics","Team:Entity
Analytics","backport:version","v8.18.0"],"number":203409,"url":"https://github.com/elastic/kibana/pull/203409","mergeCommit":{"message":"[SecuritySolution]
Update Entity analytics BE to support service entity type
(elastic#203409)\n\n## Summary\n\nUpdate Entity Analytics BE to support the new
entity type \"service\".\n* Hide all functionality behind an
Experimental Flag\n(`serviceEntityStoreEnabled`)\n* Update asset
criticality assignment\n* Update Bulk upload logic\n* Update Risk score
calculation\n* Create plugin setup mappings migration\n * Add service to
risk score indices and templates\n * Add service to asset criticality
index\n* Create a reusable migration workflow where we only need to
update the\nmappings and bump the version\n* Add a risk score transform
migration when the schedule is now called\n * It will delete and
reinstall the transform to apply the changes \n\n### issues\n* I had to
update the API doc to include service even though it is\nbehind an
Experimental Flag\n* The risk scope mappings migration runs on every
space. If the users\nhave thousands of spaces, it could take some
time.\n\n### What is not included?\n* UI changes\n\n\n## Documentation
for Entity Analytics future migrations\n\n### How to add a new field to
the risk score index and template\nmappings?\n* Update the mapping
object\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L102)\n*
Pump the `mappingsVersion`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts#L31)\n\n###
How to add a new field to the asset criticality index?\n* Update the
mapping
object\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L22)\n*
Pump the `ASSET_CRITICALITY_MAPPINGS_VERSIONS`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L20)\n\n###
How to update the risk score transform config?\n* Update the transform
config\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L162)\n*
Pump the
`version`\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L190)\n\n*note:
If you change the `latest` property, the transform will reinstall\nafter
the engine task runs\n\n## How to test it?\n* Enable the fla
`serviceEntityStoreEnabled`\n* Start ES and an old version of Kibana\n*
Populate it with data, start the risk engine\n * You could also run the
document generator `yarn start entity-store` \n* Make sure you have some
alerts with `service.name` field populated\n* Migrate to the version on
this PR\n* Run the risk engine\n* You should see risk score documents
created for service entities\n* All asset criticality API should support
`service` entities\n\n## Checklist\n- [x] Any text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\n-
[x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"1fbd86f199c738790bf53b92fd249abfbaed84f7"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203409","number":203409,"mergeCommit":{"message":"[SecuritySolution]
Update Entity analytics BE to support service entity type
(elastic#203409)\n\n## Summary\n\nUpdate Entity Analytics BE to support the new
entity type \"service\".\n* Hide all functionality behind an
Experimental Flag\n(`serviceEntityStoreEnabled`)\n* Update asset
criticality assignment\n* Update Bulk upload logic\n* Update Risk score
calculation\n* Create plugin setup mappings migration\n * Add service to
risk score indices and templates\n * Add service to asset criticality
index\n* Create a reusable migration workflow where we only need to
update the\nmappings and bump the version\n* Add a risk score transform
migration when the schedule is now called\n * It will delete and
reinstall the transform to apply the changes \n\n### issues\n* I had to
update the API doc to include service even though it is\nbehind an
Experimental Flag\n* The risk scope mappings migration runs on every
space. If the users\nhave thousands of spaces, it could take some
time.\n\n### What is not included?\n* UI changes\n\n\n## Documentation
for Entity Analytics future migrations\n\n### How to add a new field to
the risk score index and template\nmappings?\n* Update the mapping
object\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L102)\n*
Pump the `mappingsVersion`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts#L31)\n\n###
How to add a new field to the asset criticality index?\n* Update the
mapping
object\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L22)\n*
Pump the `ASSET_CRITICALITY_MAPPINGS_VERSIONS`
version\n[here](https://github.com/elastic/kibana/blob/8333bea86febd6dab97198d51bc3bb8f8cfa07ed/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/constants.ts#L20)\n\n###
How to update the risk score transform config?\n* Update the transform
config\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L162)\n*
Pump the
`version`\n[here](https://github.com/elastic/kibana/blob/6f8b5f6c51f5926929e2ae17450b11686085a980/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/configurations.ts#L190)\n\n*note:
If you change the `latest` property, the transform will reinstall\nafter
the engine task runs\n\n## How to test it?\n* Enable the fla
`serviceEntityStoreEnabled`\n* Start ES and an old version of Kibana\n*
Populate it with data, start the risk engine\n * You could also run the
document generator `yarn start entity-store` \n* Make sure you have some
alerts with `service.name` field populated\n* Migrate to the version on
this PR\n* Run the risk engine\n* You should see risk score documents
created for service entities\n* All asset criticality API should support
`service` entities\n\n## Checklist\n- [x] Any text added follows [EUI's
writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\nsentence case text and includes
[i18n\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\n-
[x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] The PR
description includes the appropriate Release Notes section,\nand the
correct `release_note:*` label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"1fbd86f199c738790bf53b92fd249abfbaed84f7"}},{"branch":"8.x","label":"v8.18.0","labelRegex":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
  • Loading branch information
machadoum authored Jan 3, 2025
1 parent e074de7 commit ced841e
Show file tree
Hide file tree
Showing 74 changed files with 1,885 additions and 562 deletions.
15 changes: 15 additions & 0 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45668,6 +45668,20 @@ components:
type: string
required:
- name
service:
type: object
properties:
asset:
type: object
properties:
criticality:
$ref: '#/components/schemas/Security_Entity_Analytics_API_AssetCriticalityLevel'
required:
- criticality
name:
type: string
required:
- name
user:
type: object
properties:
Expand Down Expand Up @@ -45964,6 +45978,7 @@ components:
enum:
- host.name
- user.name
- service.name
type: string
Security_Entity_Analytics_API_IndexPattern:
type: string
Expand Down
15 changes: 15 additions & 0 deletions oas_docs/output/kibana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34817,6 +34817,20 @@ components:
type: string
required:
- name
service:
type: object
properties:
asset:
type: object
properties:
criticality:
$ref: '#/components/schemas/Security_Entity_Analytics_API_AssetCriticalityLevel'
required:
- criticality
name:
type: string
required:
- name
user:
type: object
properties:
Expand Down Expand Up @@ -35114,6 +35128,7 @@ components:
enum:
- host.name
- user.name
- service.name
type: string
Security_Entity_Analytics_API_IndexPattern:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36955,7 +36955,6 @@
"xpack.securitySolution.assetCriticality.csvUpload.expectedColumnsError": "Trois colonnes attendues, {rowLength} reçues",
"xpack.securitySolution.assetCriticality.csvUpload.idTooLongError": "L’identificateur est trop long. Il devrait contenir moins de {maxChars} caractères, mais en contient {idLength}",
"xpack.securitySolution.assetCriticality.csvUpload.invalidCriticalityError": "Niveau de criticité non valide \"{criticalityLevel}\", un des {validLevels} attendu",
"xpack.securitySolution.assetCriticality.csvUpload.invalidEntityTypeError": "Type d'entité \"{entityType}\" non valide, hôte ou utilisateur attendu",
"xpack.securitySolution.assetCriticality.csvUpload.missingCriticalityError": "Niveau de criticité manquant",
"xpack.securitySolution.assetCriticality.csvUpload.missingEntityTypeError": "Type d'entité manquant",
"xpack.securitySolution.assetCriticality.csvUpload.missingIdError": "Identificateur manquant",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36813,7 +36813,6 @@
"xpack.securitySolution.assetCriticality.csvUpload.expectedColumnsError": "3列でなければなりませんが、{rowLength}列でした",
"xpack.securitySolution.assetCriticality.csvUpload.idTooLongError": "識別子が長すぎます。{maxChars}未満でなければなりませんが、{idLength}でした",
"xpack.securitySolution.assetCriticality.csvUpload.invalidCriticalityError": "無効な重要度レベル\"{criticalityLevel}\"です。{validLevels}のいずれかでなければなりません",
"xpack.securitySolution.assetCriticality.csvUpload.invalidEntityTypeError": "無効なエンティティタイプ\"{entityType}\"です。ホストまたはユーザーでなければなりません",
"xpack.securitySolution.assetCriticality.csvUpload.missingCriticalityError": "重要度レベルがありません",
"xpack.securitySolution.assetCriticality.csvUpload.missingEntityTypeError": "エンティティタイプがありません",
"xpack.securitySolution.assetCriticality.csvUpload.missingIdError": "識別子がありません",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36907,7 +36907,6 @@
"xpack.securitySolution.assetCriticality.csvUpload.expectedColumnsError": "应为 3 列,但得到 {rowLength}",
"xpack.securitySolution.assetCriticality.csvUpload.idTooLongError": "标识符过长,应少于 {maxChars} 个字符,但得到 {idLength}",
"xpack.securitySolution.assetCriticality.csvUpload.invalidCriticalityError": "关键度级别“{criticalityLevel}”无效,应为 {validLevels} 之一",
"xpack.securitySolution.assetCriticality.csvUpload.invalidEntityTypeError": "实体类型“{entityType}”无效,应为主机或用户",
"xpack.securitySolution.assetCriticality.csvUpload.missingCriticalityError": "关键度级别缺失",
"xpack.securitySolution.assetCriticality.csvUpload.missingEntityTypeError": "实体类型缺失",
"xpack.securitySolution.assetCriticality.csvUpload.missingIdError": "标识符缺失",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { z } from '@kbn/zod';

export type IdField = z.infer<typeof IdField>;
export const IdField = z.enum(['host.name', 'user.name']);
export const IdField = z.enum(['host.name', 'user.name', 'service.name']);
export type IdFieldEnum = typeof IdField.enum;
export const IdFieldEnum = IdField.enum;

Expand Down Expand Up @@ -78,6 +78,16 @@ export const AssetCriticalityRecordEcsParts = z.object({
.optional(),
})
.optional(),
service: z
.object({
name: z.string(),
asset: z
.object({
criticality: AssetCriticalityLevel,
})
.optional(),
})
.optional(),
});

export type AssetCriticalityRecord = z.infer<typeof AssetCriticalityRecord>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ components:
enum:
- 'host.name'
- 'user.name'
- 'service.name'
AssetCriticalityRecordIdParts:
type: object
properties:
Expand Down Expand Up @@ -109,5 +110,19 @@ components:
- 'criticality'
required:
- 'name'
'service':
type: object
properties:
'name':
type: string
'asset':
type: object
properties:
'criticality':
$ref: '#/components/schemas/AssetCriticalityLevel'
required:
- 'criticality'
required:
- 'name'
required:
- 'asset'
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type AfterKeys = z.infer<typeof AfterKeys>;
export const AfterKeys = z.object({
host: EntityAfterKey.optional(),
user: EntityAfterKey.optional(),
service: EntityAfterKey.optional(),
});

/**
Expand Down Expand Up @@ -72,7 +73,7 @@ export const DateRange = z.object({
});

export type IdentifierType = z.infer<typeof IdentifierType>;
export const IdentifierType = z.enum(['host', 'user']);
export const IdentifierType = z.enum(['host', 'user', 'service']);
export type IdentifierTypeEnum = typeof IdentifierType.enum;
export const IdentifierTypeEnum = IdentifierType.enum;

Expand Down Expand Up @@ -169,22 +170,33 @@ export const RiskScoreWeightGlobalShared = z.object({
type: z.literal('global_identifier'),
});

export type RiskScoreWeight = z.infer<typeof RiskScoreWeight>;
export const RiskScoreWeight = z.union([
export const RiskScoreWeightInternal = z.union([
RiskScoreWeightGlobalShared.merge(
z.object({
host: RiskScoreEntityIdentifierWeights,
user: RiskScoreEntityIdentifierWeights.optional(),
service: RiskScoreEntityIdentifierWeights.optional(),
})
),
RiskScoreWeightGlobalShared.merge(
z.object({
host: RiskScoreEntityIdentifierWeights.optional(),
user: RiskScoreEntityIdentifierWeights,
service: RiskScoreEntityIdentifierWeights.optional(),
})
),
RiskScoreWeightGlobalShared.merge(
z.object({
host: RiskScoreEntityIdentifierWeights.optional(),
user: RiskScoreEntityIdentifierWeights.optional(),
service: RiskScoreEntityIdentifierWeights,
})
),
]);

export type RiskScoreWeight = z.infer<typeof RiskScoreWeightInternal>;
export const RiskScoreWeight = RiskScoreWeightInternal as z.ZodType<RiskScoreWeight>;

/**
* A list of weights to be applied to the scoring calculation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ components:
$ref: '#/components/schemas/EntityAfterKey'
user:
$ref: '#/components/schemas/EntityAfterKey'
service:
$ref: '#/components/schemas/EntityAfterKey'
example:
host:
'host.name': 'example.host'
user:
'user.name': 'example_user_name'
service:
'service.name': 'example_service_name'


DataViewId:
description: The identifier of the Kibana data view to be used when generating risk scores.
Expand Down Expand Up @@ -94,6 +99,7 @@ components:
enum:
- host
- user
- service

RiskScoreInput:
description: A generic representation of a document contributing to a Risk Score.
Expand Down Expand Up @@ -247,6 +253,8 @@ components:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
user:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
service:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'

- allOf:
- $ref: '#/components/schemas/RiskScoreWeightGlobalShared'
Expand All @@ -258,7 +266,20 @@ components:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
user:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'

service:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
- allOf:
- $ref: '#/components/schemas/RiskScoreWeightGlobalShared'
- type: object
required:
- service
properties:
host:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
user:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
service:
$ref: '#/components/schemas/RiskScoreEntityIdentifierWeights'
RiskScoreWeights:
description: 'A list of weights to be applied to the scoring calculation.'
type: array
Expand All @@ -268,6 +289,7 @@ components:
- type: 'global_identifier'
host: 0.5
user: 0.1
service: 0.4

TaskManagerUnavailableResponse:
description: Task manager is unavailable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ describe('risk weight schema', () => {

expect(decoded.success).toBeFalsy();
expect(stringifyZodError(decoded.error)).toEqual(
'type: Invalid literal value, expected "global_identifier", host: Required, type: Invalid literal value, expected "global_identifier"'
'type: Invalid literal value, expected "global_identifier", host: Required, type: Invalid literal value, expected "global_identifier", type: Invalid literal value, expected "global_identifier", service: Required'
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export const RiskScoresCalculationResponse = z.object({
* A list of user risk scores
*/
user: z.array(EntityRiskScoreRecord).optional(),
/**
* A list of service risk scores
*/
service: z.array(EntityRiskScoreRecord).optional(),
/**
* If 'wait_for' the request will wait for the index refresh.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ components:
items:
$ref: '../common/common.schema.yaml#/components/schemas/EntityRiskScoreRecord'
description: A list of user risk scores
service:
type: array
items:
$ref: '../common/common.schema.yaml#/components/schemas/EntityRiskScoreRecord'
description: A list of service risk scores
refresh:
type: string
enum: [wait_for]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export const RiskScoresPreviewResponse = z.object({
* A list of user risk scores
*/
user: z.array(EntityRiskScoreRecord).optional(),
/**
* A list of service risk scores
*/
service: z.array(EntityRiskScoreRecord).optional(),
}),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,8 @@ components:
items:
$ref: '../common/common.schema.yaml#/components/schemas/EntityRiskScoreRecord'
description: A list of user risk scores
service:
type: array
items:
$ref: '../common/common.schema.yaml#/components/schemas/EntityRiskScoreRecord'
description: A list of service risk scores
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('parseAssetCriticalityCsvRow', () => {

// @ts-ignore result can now only be InvalidRecord
expect(result.error).toMatchInlineSnapshot(
`"Invalid entity type \\"invalid\\", expected host or user"`
`"Invalid entity type \\"invalid\\", expected to be one of: user, host, service"`
);
});

Expand All @@ -57,7 +57,7 @@ describe('parseAssetCriticalityCsvRow', () => {

// @ts-ignore result can now only be InvalidRecord
expect(result.error).toMatchInlineSnapshot(
`"Invalid entity type \\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...\\", expected host or user"`
`"Invalid entity type \\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...\\", expected to be one of: user, host, service"`
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import { i18n } from '@kbn/i18n';
import type { CriticalityLevels } from './constants';
import { ValidCriticalityLevels } from './constants';
import type { AssetCriticalityUpsert, CriticalityLevel } from './types';
import { type AssetCriticalityUpsert, type CriticalityLevel } from './types';
import { IDENTITY_FIELD_MAP, getAvailableEntityTypes } from '../entity_store/constants';
import type { EntityType } from '../../api/entity_analytics';

const MAX_COLUMN_CHARS = 1000;

Expand Down Expand Up @@ -98,16 +100,19 @@ export const parseAssetCriticalityCsvRow = (row: string[]): ReturnType => {
);
}

if (entityType !== 'host' && entityType !== 'user') {
if (!getAvailableEntityTypes().includes(entityType as EntityType)) {
return validationErrorWithMessage(
i18n.translate('xpack.securitySolution.assetCriticality.csvUpload.invalidEntityTypeError', {
defaultMessage: 'Invalid entity type "{entityType}", expected host or user',
values: { entityType: trimColumn(entityType) },
defaultMessage: 'Invalid entity type "{entityType}", expected to be one of: {validTypes}',
values: {
entityType: trimColumn(entityType),
validTypes: getAvailableEntityTypes().join(', '),
},
})
);
}

const idField = entityType === 'host' ? 'host.name' : 'user.name';
const idField = IDENTITY_FIELD_MAP[entityType as EntityType];

return {
valid: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
* 2.0.
*/

import type { EntityType, IdField } from '../../api/entity_analytics';
import { EntityTypeEnum } from '../../api/entity_analytics';

/**
* Entity Store routes
*/
Expand All @@ -23,3 +26,12 @@ export const ENTITY_STORE_REQUIRED_ES_CLUSTER_PRIVILEGES = [

// The index pattern for the entity store has to support '.entities.v1.latest.noop' index
export const ENTITY_STORE_INDEX_PATTERN = '.entities.v1.latest.*';

export const IDENTITY_FIELD_MAP: Record<EntityType, IdField> = {
[EntityTypeEnum.host]: 'host.name',
[EntityTypeEnum.user]: 'user.name',
[EntityTypeEnum.service]: 'service.name',
};

export const getAvailableEntityTypes = (): EntityType[] =>
Object.keys(EntityTypeEnum) as EntityType[];
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

import * as t from 'io-ts';

export const identifierTypeSchema = t.keyof({ user: null, host: null });
export const identifierTypeSchema = t.keyof({ user: null, host: null, service: null });
export type IdentifierTypeSchema = t.TypeOf<typeof identifierTypeSchema>;
export type IdentifierType = IdentifierTypeSchema;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import type { EntityRiskScoreRecord, RiskScoreInput } from '../../api/entity_ana
export enum RiskScoreEntity {
host = 'host',
user = 'user',
// TODO Add service when FE is updated https://github.com/elastic/security-team/issues/11326
}
// TODO: Remove this when FE is updated https://github.com/elastic/security-team/issues/11326
export const SERVICE_RISK_SCORE_ENTITY = 'service';

export interface InitRiskEngineResult {
legacyRiskEngineDisabled: boolean;
Expand Down
Loading

0 comments on commit ced841e

Please sign in to comment.