Skip to content

Commit 6c4126f

Browse files
[9.0] [SecuritySolution] Update API key permissions on refreshing data view API (#215738) (#216004)
# Backport This will backport the following commits from `main` to `9.0`: - [[SecuritySolution] Update API key permissions on refreshing data view API (#215738)](#215738) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Pablo Machado","email":"pablo.nevesmachado@elastic.co"},"sourceCommit":{"committedDate":"2025-03-26T10:03:45Z","message":"[SecuritySolution] Update API key permissions on refreshing data view API (#215738)\n\nUpdate the API key when entity store `apply_dataview_indices` is called.\n\n## Summary\nThis change allows the user to update the privileges the entity store\ndata view refresh task uses. This will enable them to fix problems when\nthe user that enabled the entity store doesn't have all data view\nindices privileges.\n\nThis PR also improves some error messages that were hard to read.\n\n### Context\n* `apply_dataview_indices`is an API that updates the entity store\ntransform with the indices defined in the security solution data view.\n* There is a background task that calls `apply_dataview_indices` from\ntime to time\n* The background task uses the API key to access the security solution\ndata view indices.\n\n\n### How to test it\n* Create a kibana instance with security data\n* Create a user that only has access the necessary access to the entity\nstore indices\n* Enable the entity store with a the created user\n* Login with a superuser \n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task will fail because it uses the API key from the unprivileged\nuser.\n* Call `apply_dataview_indices` with the superuser (`POST\nkbn:api/entity_store/engines/apply_dataview_indices`)\n* The request should succeed because it is using the superuser\ncredentials\n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task should succeed because it is using the superuser API key\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] [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)","sha":"e201b947be53e4e903ab1126592c3853f66108df","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team: SecuritySolution","Team:Entity Analytics","backport:version","v9.1.0","v8.19.0","v8.18.1","v9.0.1"],"title":"[SecuritySolution] Update API key permissions on refreshing data view API","number":215738,"url":"https://github.com/elastic/kibana/pull/215738","mergeCommit":{"message":"[SecuritySolution] Update API key permissions on refreshing data view API (#215738)\n\nUpdate the API key when entity store `apply_dataview_indices` is called.\n\n## Summary\nThis change allows the user to update the privileges the entity store\ndata view refresh task uses. This will enable them to fix problems when\nthe user that enabled the entity store doesn't have all data view\nindices privileges.\n\nThis PR also improves some error messages that were hard to read.\n\n### Context\n* `apply_dataview_indices`is an API that updates the entity store\ntransform with the indices defined in the security solution data view.\n* There is a background task that calls `apply_dataview_indices` from\ntime to time\n* The background task uses the API key to access the security solution\ndata view indices.\n\n\n### How to test it\n* Create a kibana instance with security data\n* Create a user that only has access the necessary access to the entity\nstore indices\n* Enable the entity store with a the created user\n* Login with a superuser \n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task will fail because it uses the API key from the unprivileged\nuser.\n* Call `apply_dataview_indices` with the superuser (`POST\nkbn:api/entity_store/engines/apply_dataview_indices`)\n* The request should succeed because it is using the superuser\ncredentials\n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task should succeed because it is using the superuser API key\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] [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)","sha":"e201b947be53e4e903ab1126592c3853f66108df"}},"sourceBranch":"main","suggestedTargetBranches":["8.x","8.18","9.0"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/215738","number":215738,"mergeCommit":{"message":"[SecuritySolution] Update API key permissions on refreshing data view API (#215738)\n\nUpdate the API key when entity store `apply_dataview_indices` is called.\n\n## Summary\nThis change allows the user to update the privileges the entity store\ndata view refresh task uses. This will enable them to fix problems when\nthe user that enabled the entity store doesn't have all data view\nindices privileges.\n\nThis PR also improves some error messages that were hard to read.\n\n### Context\n* `apply_dataview_indices`is an API that updates the entity store\ntransform with the indices defined in the security solution data view.\n* There is a background task that calls `apply_dataview_indices` from\ntime to time\n* The background task uses the API key to access the security solution\ndata view indices.\n\n\n### How to test it\n* Create a kibana instance with security data\n* Create a user that only has access the necessary access to the entity\nstore indices\n* Enable the entity store with a the created user\n* Login with a superuser \n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task will fail because it uses the API key from the unprivileged\nuser.\n* Call `apply_dataview_indices` with the superuser (`POST\nkbn:api/entity_store/engines/apply_dataview_indices`)\n* The request should succeed because it is using the superuser\ncredentials\n* Add a new index to the security solution data view, which the created\nuser cannot access.\n* The task should succeed because it is using the superuser API key\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] [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)","sha":"e201b947be53e4e903ab1126592c3853f66108df"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.0","label":"v9.0.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Pablo Machado <pablo.nevesmachado@elastic.co>
1 parent abb4f2a commit 6c4126f

5 files changed

Lines changed: 27 additions & 10 deletions

File tree

x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ const createSecuritySolutionRequestContextMock = (
168168
getAssetCriticalityDataClient: jest.fn(() => clients.assetCriticalityDataClient),
169169
getAuditLogger: jest.fn(() => mockAuditLogger),
170170
getDataViewsService: jest.fn(),
171+
getEntityStoreApiKeyManager: jest.fn(),
171172
getEntityStoreDataClient: jest.fn(() => clients.entityStoreDataClient),
172173
getSiemRuleMigrationsClient: jest.fn(() => clients.siemRuleMigrationsClient),
173174
getInferenceClient: jest.fn(() => clients.getInferenceClient()),

x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/apply_dataview_indices.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ export const applyDataViewIndicesEntityEngineRoute = (
5858
});
5959
}
6060

61+
const apiKeyManager = secSol.getEntityStoreApiKeyManager();
62+
await apiKeyManager.generate();
63+
6164
if (errors.length === 0) {
6265
return response.ok({
6366
body: {
@@ -75,7 +78,7 @@ export const applyDataViewIndicesEntityEngineRoute = (
7578
});
7679
}
7780
} catch (e) {
78-
logger.error('Error in ApplyEntityEngineDataViewIndices:', e);
81+
logger.error(`Error in ApplyEntityEngineDataViewIndices: ${e.message}`);
7982
const error = transformError(e);
8083
return siemResponse.error({
8184
statusCode: error.statusCode,

x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/entity_store/tasks/data_view_refresh/data_view_refresh_task.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ export const registerEntityStoreDataViewRefreshTask = ({
110110
request,
111111
});
112112

113-
await entityStoreClient.applyDataViewIndices();
113+
const { errors } = await entityStoreClient.applyDataViewIndices();
114+
115+
if (errors.length > 0) {
116+
logger.error(
117+
`Errors applying data view changes to the entity store. Errors: \n${errors.join('\n\n')}`
118+
);
119+
}
114120
};
115121

116122
taskManager.registerTaskDefinitions({

x-pack/solutions/security/plugins/security_solution/server/request_context_factory.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ export class RequestContextFactory implements IRequestContextFactory {
109109

110110
const getAuditLogger = () => security?.audit.asScoped(request);
111111

112+
const getEntityStoreApiKeyManager = () =>
113+
getApiKeyManager({
114+
core: coreStart,
115+
logger: options.logger,
116+
security: startPlugins.security,
117+
encryptedSavedObjects: startPlugins.encryptedSavedObjects,
118+
request,
119+
namespace: getSpaceId(),
120+
});
121+
112122
// List of endpoint authz for the current request's user. Will be initialized the first
113123
// time it is requested (see `getEndpointAuthz()` below)
114124
let endpointAuthz: Immutable<EndpointAuthz>;
@@ -145,6 +155,8 @@ export class RequestContextFactory implements IRequestContextFactory {
145155

146156
getDataViewsService: () => dataViewsService,
147157

158+
getEntityStoreApiKeyManager,
159+
148160
getDetectionRulesClient: memoize(() => {
149161
const mlAuthz = buildMlAuthz({
150162
license: licensing.license,
@@ -258,14 +270,7 @@ export class RequestContextFactory implements IRequestContextFactory {
258270
config: config.entityAnalytics.entityStore,
259271
experimentalFeatures: config.experimentalFeatures,
260272
telemetry: core.analytics,
261-
apiKeyManager: getApiKeyManager({
262-
core: coreStart,
263-
logger,
264-
security: startPlugins.security,
265-
encryptedSavedObjects: startPlugins.encryptedSavedObjects,
266-
request,
267-
namespace: getSpaceId(),
268-
}),
273+
apiKeyManager: getEntityStoreApiKeyManager(),
269274
security: startPlugins.security,
270275
request,
271276
});

x-pack/solutions/security/plugins/security_solution/server/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import type { IDetectionRulesClient } from './lib/detection_engine/rule_manageme
3939
import type { EntityStoreDataClient } from './lib/entity_analytics/entity_store/entity_store_data_client';
4040
import type { SiemRuleMigrationsClient } from './lib/siem_migrations/rules/siem_rule_migrations_service';
4141
import type { AssetInventoryDataClient } from './lib/asset_inventory/asset_inventory_data_client';
42+
import type { ApiKeyManager } from './lib/entity_analytics/entity_store/auth/api_key';
4243
export { AppClient };
4344

4445
export interface SecuritySolutionApiRequestHandlerContext {
@@ -56,6 +57,7 @@ export interface SecuritySolutionApiRequestHandlerContext {
5657
getRacClient: (req: KibanaRequest) => Promise<AlertsClient>;
5758
getAuditLogger: () => AuditLogger | undefined;
5859
getDataViewsService: () => DataViewsService;
60+
getEntityStoreApiKeyManager: () => ApiKeyManager;
5961
getExceptionListClient: () => ExceptionListClient | null;
6062
getInternalFleetServices: () => EndpointInternalFleetServicesInterface;
6163
getRiskEngineDataClient: () => RiskEngineDataClient;

0 commit comments

Comments
 (0)