From 5c3c237659cc8c938bdd1c2155556a639bf6775a Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Tue, 7 Jan 2025 13:34:54 +0100 Subject: [PATCH] Conditionally add agentless index permissions (#203810) ## Summary Adds necessary permissions to write to the `agentless-*` index. See: - Elasticsearch PR: https://github.com/elastic/elasticsearch/pull/118644 - Context: https://github.com/elastic/security-team/issues/11104 As part of https://github.com/elastic/security-team/issues/11104, we need to write integration data that needs to be persistent. The implementation we are working on, uses Elasticsearch as the storage mechanism for this data. Normally, integrations write to data streams instead of normal ES indices. However, data streams cannot provide a generic implementation for our use case and thus we need a normal ES index. This PR grants permissions from the fleet service account to the agentless integrations to write to `agentless-*` ES indices. In `x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts` there are other examples of other integrations that need ES index permissions so there is prior art in doing this. The difference with this PR however, is that we need to conditionally merge the extra `agentless-*` permissions with any potential existing data stream permissions since we are dealing with arbitrary agentless integrations. --- .../package_policies_to_agent_permissions.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts index 914cde14e1797..f1d8bfab82510 100644 --- a/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts +++ b/x-pack/platform/plugins/shared/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts @@ -52,6 +52,16 @@ export const ELASTIC_CONNECTORS_INDEX_PERMISSIONS = [ 'view_index_metadata', ]; +export const AGENTLESS_INDEX_PERMISSIONS = [ + 'read', + 'write', + 'monitor', + 'create_index', + 'auto_configure', + 'maintenance', + 'view_index_metadata', +]; + export function storedPackagePoliciesToAgentPermissions( packageInfoCache: Map, agentPolicyNamespace: string, @@ -173,13 +183,10 @@ export function storedPackagePoliciesToAgentPermissions( } // namespace is either the package policy's or the agent policy one const namespace = packagePolicy?.namespace || agentPolicyNamespace; - return [ - packagePolicy.id, - { - indices: dataStreamsForPermissions.map((ds) => getDataStreamPrivileges(ds, namespace)), - ...clusterRoleDescriptor, - }, - ]; + return maybeAddAgentlessPermissions(packagePolicy, { + indices: dataStreamsForPermissions.map((ds) => getDataStreamPrivileges(ds, namespace)), + ...clusterRoleDescriptor, + }); }); return Object.fromEntries(permissionEntries); @@ -244,6 +251,20 @@ function universalProfilingPermissions(packagePolicyId: string): [string, Securi ]; } +function maybeAddAgentlessPermissions( + packagePolicy: PackagePolicy, + existing: SecurityRoleDescriptor +): [string, SecurityRoleDescriptor] { + if (!packagePolicy.supports_agentless) { + return [packagePolicy.id, existing]; + } + existing.indices!.push({ + names: ['agentless-*'], + privileges: AGENTLESS_INDEX_PERMISSIONS, + }); + return [packagePolicy.id, existing]; +} + function apmPermissions(packagePolicyId: string): [string, SecurityRoleDescriptor] { return [ packagePolicyId,