diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_base_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_base_client.ts index 31931fce0b1d9..e80e880545f68 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_base_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_base_client.ts @@ -11,7 +11,12 @@ import type { SearchResponse, Duration, } from '@elastic/elasticsearch/lib/api/types'; -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import type { + AuthenticatedUser, + ElasticsearchClient, + IScopedClusterClient, + Logger, +} from '@kbn/core/server'; import assert from 'assert'; import type { Stored } from '../types'; import type { IndexNameProvider } from './rule_migrations_data_client'; @@ -19,12 +24,28 @@ import type { IndexNameProvider } from './rule_migrations_data_client'; const DEFAULT_PIT_KEEP_ALIVE: Duration = '30s' as const; export class RuleMigrationsDataBaseClient { + protected esClient: ElasticsearchClient; + constructor( protected getIndexName: IndexNameProvider, - protected username: string, - protected esClient: ElasticsearchClient, + protected currentUser: AuthenticatedUser, + protected esScopedClient: IScopedClusterClient, protected logger: Logger - ) {} + ) { + this.esClient = esScopedClient.asInternalUser; + } + + protected async getProfileUid() { + if (this.currentUser.profile_uid) { + return this.currentUser.profile_uid; + } + const username = this.currentUser.username; + const users = await this.esScopedClient.asCurrentUser.security.getUser({ + username, + with_profile_uid: true, + }); + return users[username].profile_uid; + } protected processResponseHits( response: SearchResponse, diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_client.ts index 9198a521bcb96..aec7a1931b502 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_client.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IScopedClusterClient, Logger } from '@kbn/core/server'; +import type { AuthenticatedUser, IScopedClusterClient, Logger } from '@kbn/core/server'; import type { PackageService } from '@kbn/fleet-plugin/server'; import { RuleMigrationsDataIntegrationsClient } from './rule_migrations_data_integrations_client'; import { RuleMigrationsDataPrebuiltRulesClient } from './rule_migrations_data_prebuilt_rules_client'; @@ -26,40 +26,36 @@ export class RuleMigrationsDataClient { constructor( indexNameProviders: IndexNameProviders, - username: string, + currentUser: AuthenticatedUser, esScopedClient: IScopedClusterClient, logger: Logger, packageService?: PackageService ) { this.rules = new RuleMigrationsDataRulesClient( indexNameProviders.rules, - username, - esScopedClient.asInternalUser, + currentUser, + esScopedClient, logger ); this.resources = new RuleMigrationsDataResourcesClient( indexNameProviders.resources, - username, - esScopedClient.asInternalUser, + currentUser, + esScopedClient, logger ); this.integrations = new RuleMigrationsDataIntegrationsClient( indexNameProviders.integrations, - username, - esScopedClient.asInternalUser, + currentUser, + esScopedClient, logger, packageService ); this.prebuiltRules = new RuleMigrationsDataPrebuiltRulesClient( indexNameProviders.prebuiltrules, - username, - esScopedClient.asInternalUser, - logger - ); - this.lookups = new RuleMigrationsDataLookupsClient( - username, - esScopedClient.asCurrentUser, + currentUser, + esScopedClient, logger ); + this.lookups = new RuleMigrationsDataLookupsClient(currentUser, esScopedClient, logger); } } diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_integrations_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_integrations_client.ts index 54a4f14a667e4..5df7cfe517f20 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_integrations_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_integrations_client.ts @@ -6,7 +6,7 @@ */ import type { PackageService } from '@kbn/fleet-plugin/server'; -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import type { AuthenticatedUser, IScopedClusterClient, Logger } from '@kbn/core/server'; import type { PackageList } from '@kbn/fleet-plugin/common'; import type { RuleMigrationIntegration } from '../types'; import { RuleMigrationsDataBaseClient } from './rule_migrations_data_base_client'; @@ -28,12 +28,12 @@ const INTEGRATIONS = integrationsFile as RuleMigrationIntegration[]; export class RuleMigrationsDataIntegrationsClient extends RuleMigrationsDataBaseClient { constructor( getIndexName: IndexNameProvider, - username: string, - esClient: ElasticsearchClient, + currentUser: AuthenticatedUser, + esScopedClient: IScopedClusterClient, logger: Logger, private packageService?: PackageService ) { - super(getIndexName, username, esClient, logger); + super(getIndexName, currentUser, esScopedClient, logger); } async getIntegrationPackages(): Promise { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_lookups_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_lookups_client.ts index 93763d6508cf0..24efc3ae7eb87 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_lookups_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_lookups_client.ts @@ -6,15 +6,15 @@ */ import { sha256 } from 'js-sha256'; -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import type { AuthenticatedUser, IScopedClusterClient, Logger } from '@kbn/core/server'; import { retryTransientEsErrors } from '@kbn/index-adapter'; export type LookupData = object[]; export class RuleMigrationsDataLookupsClient { constructor( - protected username: string, - protected esClient: ElasticsearchClient, + protected currentUser: AuthenticatedUser, + protected esScopedClient: IScopedClusterClient, protected logger: Logger ) {} @@ -22,7 +22,7 @@ export class RuleMigrationsDataLookupsClient { const indexName = `lookup_${lookupName}`; try { await this.executeEs(() => - this.esClient.indices.create({ + this.esScopedClient.asCurrentUser.indices.create({ index: indexName, settings: { index: { mode: 'lookup' } }, mappings: { dynamic: 'runtime' }, @@ -48,7 +48,9 @@ export class RuleMigrationsDataLookupsClient { ]); try { - await this.executeEs(() => this.esClient.bulk({ index: indexName, body })); + await this.executeEs(() => + this.esScopedClient.asCurrentUser.bulk({ index: indexName, body }) + ); } catch (error) { if (error?.statusCode !== 404) { this.logger.error(`Error indexing data for lookup index ${indexName} - ${error.message}`); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts index c2bd1ed2e50f8..fce0bec7e9d24 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts @@ -40,6 +40,7 @@ const DEFAULT_SEARCH_BATCH_SIZE = 500 as const; export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseClient { public async upsert(resources: CreateRuleMigrationResourceInput[]): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); let resourcesSlice: CreateRuleMigrationResourceInput[]; @@ -54,7 +55,7 @@ export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseCli doc: { ...resource, '@timestamp': createdAt, - updated_by: this.username, + updated_by: profileId, updated_at: createdAt, }, doc_as_upsert: true, @@ -71,6 +72,7 @@ export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseCli /** Creates the resources in the index only if they do not exist */ public async create(resources: CreateRuleMigrationResourceInput[]): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); let resourcesSlice: CreateRuleMigrationResourceInput[]; const createdAt = new Date().toISOString(); @@ -83,7 +85,7 @@ export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseCli { ...resource, '@timestamp': createdAt, - updated_by: this.username, + updated_by: profileId, updated_at: createdAt, }, ]), diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts index e65921ca2a9ac..675b9f7ed7c33 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts @@ -66,6 +66,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient /** Indexes an array of rule migrations to be processed */ async create(ruleMigrations: CreateRuleMigrationInput[]): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); let ruleMigrationsSlice: CreateRuleMigrationInput[]; const createdAt = new Date().toISOString(); @@ -79,8 +80,8 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient ...ruleMigration, '@timestamp': createdAt, status: SiemMigrationStatus.PENDING, - created_by: this.username, - updated_by: this.username, + created_by: profileId, + updated_by: profileId, updated_at: createdAt, }, ]), @@ -95,6 +96,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient /** Updates an array of rule migrations to be processed */ async update(ruleMigrations: UpdateRuleMigrationData[]): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); let ruleMigrationsSlice: UpdateRuleMigrationData[]; const updatedAt = new Date().toISOString(); @@ -117,7 +119,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient elastic_rule: elasticRule, translation_result: translationResult ?? convertEsqlQueryToTranslationResult(elasticRule?.query), - updated_by: this.username, + updated_by: profileId, updated_at: updatedAt, }, }, @@ -176,6 +178,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient */ async takePending(migrationId: string, size: number): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); const query = this.getFilterQuery(migrationId, { status: SiemMigrationStatus.PENDING }); const storedRuleMigrations = await this.esClient @@ -194,7 +197,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient operations: storedRuleMigrations.flatMap(({ id, status }) => [ { update: { _id: id, _index: index } }, { - doc: { status, updated_by: this.username, updated_at: new Date().toISOString() }, + doc: { status, updated_by: profileId, updated_at: new Date().toISOString() }, }, ]), }) @@ -211,10 +214,11 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient /** Updates one rule migration with the provided data and sets the status to `completed` */ async saveCompleted({ id, ...ruleMigration }: StoredRuleMigration): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); const doc = { ...ruleMigration, status: SiemMigrationStatus.COMPLETED, - updated_by: this.username, + updated_by: profileId, updated_at: new Date().toISOString(), }; await this.esClient.update({ index, id, doc, refresh: 'wait_for' }).catch((error) => { @@ -226,10 +230,11 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient /** Updates one rule migration with the provided data and sets the status to `failed` */ async saveError({ id, ...ruleMigration }: StoredRuleMigration): Promise { const index = await this.getIndexName(); + const profileId = await this.getProfileUid(); const doc = { ...ruleMigration, status: SiemMigrationStatus.FAILED, - updated_by: this.username, + updated_by: profileId, updated_at: new Date().toISOString(), }; await this.esClient.update({ index, id, doc, refresh: 'wait_for' }).catch((error) => { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_service.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_service.ts index 5cacaf5592407..094e48ab90771 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_service.ts @@ -118,7 +118,7 @@ export class RuleMigrationsDataService { return new RuleMigrationsDataClient( indexNameProviders, - currentUser.username, + currentUser, esScopedClient, this.logger, packageService