From 1854694db8546bc0db402547d73ba23be515bb12 Mon Sep 17 00:00:00 2001 From: "Joey F. Poon" Date: Fri, 30 Sep 2022 09:47:21 -0500 Subject: [PATCH] [Security Solution] add new permission properties for endpoint rbac (#142243) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../endpoint/service/authz/authz.test.ts | 69 +++++++- .../common/endpoint/service/authz/authz.ts | 164 +++++++++++++++++- .../common/endpoint/types/authz.ts | 30 ++++ 3 files changed, 245 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts index d8f65cf07d28f..e5b2f78c25472 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts @@ -110,24 +110,60 @@ describe('Endpoint Authz service', () => { describe('and endpoint rbac is enabled', () => { it.each<[EndpointAuthzKeyList[number], string]>([ + ['canWriteEndpointList', 'writeEndpointList'], + ['canReadEndpointList', 'readEndpointList'], + ['canWritePolicyManagement', 'writePolicyManagement'], + ['canReadPolicyManagement', 'readPolicyManagement'], + ['canWriteActionsLogManagement', 'writeActionsLogManagement'], + ['canReadActionsLogManagement', 'readActionsLogManagement'], ['canIsolateHost', 'writeHostIsolation'], ['canUnIsolateHost', 'writeHostIsolation'], ['canKillProcess', 'writeProcessOperations'], ['canSuspendProcess', 'writeProcessOperations'], ['canGetRunningProcesses', 'writeProcessOperations'], + ['canWriteFileOperations', 'writeFileOperations'], + ['canWriteTrustedApplications', 'writeTrustedApplications'], + ['canReadTrustedApplications', 'readTrustedApplications'], + ['canWriteHostIsolationExceptions', 'writeHostIsolationExceptions'], + ['canReadHostIsolationExceptions', 'readHostIsolationExceptions'], + ['canWriteBlocklist', 'writeBlocklist'], + ['canReadBlocklist', 'readBlocklist'], + ['canWriteEventFilters', 'writeEventFilters'], + ['canReadEventFilters', 'readEventFilters'], ])('%s should be true if `packagePrivilege.%s` is `true`', (auth) => { const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); expect(authz[auth]).toBe(true); }); - it.each<[EndpointAuthzKeyList[number], string]>([ - ['canIsolateHost', 'writeHostIsolation'], - ['canUnIsolateHost', 'writeHostIsolation'], - ['canKillProcess', 'writeProcessOperations'], - ['canSuspendProcess', 'writeProcessOperations'], - ['canGetRunningProcesses', 'writeProcessOperations'], - ])('%s should be false if `packagePrivilege.%s` is `false`', (auth, privilege) => { - fleetAuthz.packagePrivileges!.endpoint.actions[privilege].executePackageAction = false; + it.each<[EndpointAuthzKeyList[number], string[]]>([ + ['canWriteEndpointList', ['writeEndpointList']], + ['canReadEndpointList', ['writeEndpointList', 'readEndpointList']], + ['canWritePolicyManagement', ['writePolicyManagement']], + ['canReadPolicyManagement', ['writePolicyManagement', 'readPolicyManagement']], + ['canWriteActionsLogManagement', ['writeActionsLogManagement']], + ['canReadActionsLogManagement', ['writeActionsLogManagement', 'readActionsLogManagement']], + ['canIsolateHost', ['writeHostIsolation']], + ['canUnIsolateHost', ['writeHostIsolation']], + ['canKillProcess', ['writeProcessOperations']], + ['canSuspendProcess', ['writeProcessOperations']], + ['canGetRunningProcesses', ['writeProcessOperations']], + ['canWriteFileOperations', ['writeFileOperations']], + ['canWriteTrustedApplications', ['writeTrustedApplications']], + ['canReadTrustedApplications', ['writeTrustedApplications', 'readTrustedApplications']], + ['canWriteHostIsolationExceptions', ['writeHostIsolationExceptions']], + [ + 'canReadHostIsolationExceptions', + ['writeHostIsolationExceptions', 'readHostIsolationExceptions'], + ], + ['canWriteBlocklist', ['writeBlocklist']], + ['canReadBlocklist', ['writeBlocklist', 'readBlocklist']], + ['canWriteEventFilters', ['writeEventFilters']], + ['canReadEventFilters', ['writeEventFilters', 'readEventFilters']], + ])('%s should be false if `packagePrivilege.%s` is `false`', (auth, privileges) => { + // read permission checks for write || read so we need to set both to false + privileges.forEach((privilege) => { + fleetAuthz.packagePrivileges!.endpoint.actions[privilege].executePackageAction = false; + }); const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); expect(authz[auth]).toBe(false); }); @@ -139,13 +175,28 @@ describe('Endpoint Authz service', () => { expect(getEndpointAuthzInitialState()).toEqual({ canAccessFleet: false, canAccessEndpointManagement: false, + canCreateArtifactsByPolicy: false, + canWriteEndpointList: false, + canReadEndpointList: false, + canWritePolicyManagement: false, + canReadPolicyManagement: false, + canWriteActionsLogManagement: false, + canReadActionsLogManagement: false, canIsolateHost: false, canUnIsolateHost: true, - canCreateArtifactsByPolicy: false, canKillProcess: false, canSuspendProcess: false, canGetRunningProcesses: false, canAccessResponseConsole: false, + canWriteFileOperations: false, + canWriteTrustedApplications: false, + canReadTrustedApplications: false, + canWriteHostIsolationExceptions: false, + canReadHostIsolationExceptions: false, + canWriteBlocklist: false, + canReadBlocklist: false, + canWriteEventFilters: false, + canReadEventFilters: false, }); }); }); diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts index 9e280f383cae3..dde2a7f92b1e0 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts @@ -5,11 +5,23 @@ * 2.0. */ -import type { FleetAuthz } from '@kbn/fleet-plugin/common'; +import type { ENDPOINT_PRIVILEGES } from '@kbn/fleet-plugin/common'; +import { type FleetAuthz } from '@kbn/fleet-plugin/common'; import type { LicenseService } from '../../../license'; import type { EndpointAuthz } from '../../types/authz'; import type { MaybeImmutable } from '../../types'; +function hasPermission( + fleetAuthz: FleetAuthz, + isEndpointRbacEnabled: boolean, + hasEndpointManagementAccess: boolean, + privilege: typeof ENDPOINT_PRIVILEGES[number] +) { + return isEndpointRbacEnabled + ? fleetAuthz.packagePrivileges?.endpoint?.actions[privilege].executePackageAction ?? false + : hasEndpointManagementAccess; +} + /** * Used by both the server and the UI to generate the Authorization for access to Endpoint related * functionality @@ -27,19 +39,128 @@ export const calculateEndpointAuthz = ( const isPlatinumPlusLicense = licenseService.isPlatinumPlus(); const isEnterpriseLicense = licenseService.isEnterprise(); const hasEndpointManagementAccess = userRoles.includes('superuser'); - const canIsolateHost = isEndpointRbacEnabled - ? fleetAuthz.packagePrivileges?.endpoint?.actions?.writeHostIsolation?.executePackageAction || - false - : hasEndpointManagementAccess; - const canWriteProcessOperations = isEndpointRbacEnabled - ? fleetAuthz.packagePrivileges?.endpoint?.actions?.writeProcessOperations - ?.executePackageAction || false - : hasEndpointManagementAccess; + const canWriteEndpointList = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeEndpointList' + ); + const canReadEndpointList = + canWriteEndpointList || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readEndpointList' + ); + const canWritePolicyManagement = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writePolicyManagement' + ); + const canReadPolicyManagement = + canWritePolicyManagement || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readPolicyManagement' + ); + const canWriteActionsLogManagement = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeActionsLogManagement' + ); + const canReadActionsLogManagement = + canWriteActionsLogManagement || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readActionsLogManagement' + ); + const canIsolateHost = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeHostIsolation' + ); + const canWriteProcessOperations = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeProcessOperations' + ); + const canWriteTrustedApplications = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeTrustedApplications' + ); + const canReadTrustedApplications = + canWriteTrustedApplications || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readTrustedApplications' + ); + const canWriteHostIsolationExceptions = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeHostIsolationExceptions' + ); + const canReadHostIsolationExceptions = + canWriteHostIsolationExceptions || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readHostIsolationExceptions' + ); + const canWriteBlocklist = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeBlocklist' + ); + const canReadBlocklist = + canWriteBlocklist || + hasPermission(fleetAuthz, isEndpointRbacEnabled, hasEndpointManagementAccess, 'readBlocklist'); + const canWriteEventFilters = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeEventFilters' + ); + const canReadEventFilters = + canWriteEventFilters || + hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'readEventFilters' + ); + const canWriteFileOperations = hasPermission( + fleetAuthz, + isEndpointRbacEnabled, + hasEndpointManagementAccess, + 'writeFileOperations' + ); return { canAccessFleet: fleetAuthz?.fleet.all ?? userRoles.includes('superuser'), canAccessEndpointManagement: hasEndpointManagementAccess, canCreateArtifactsByPolicy: hasEndpointManagementAccess && isPlatinumPlusLicense, + canWriteEndpointList, + canReadEndpointList, + canWritePolicyManagement, + canReadPolicyManagement, + canWriteActionsLogManagement, + canReadActionsLogManagement, // Response Actions canIsolateHost: canIsolateHost && isPlatinumPlusLicense, canUnIsolateHost: canIsolateHost, @@ -47,6 +168,16 @@ export const calculateEndpointAuthz = ( canSuspendProcess: canWriteProcessOperations && isEnterpriseLicense, canGetRunningProcesses: canWriteProcessOperations && isEnterpriseLicense, canAccessResponseConsole: hasEndpointManagementAccess && isEnterpriseLicense, + canWriteFileOperations: canWriteFileOperations && isEnterpriseLicense, + // artifacts + canWriteTrustedApplications, + canReadTrustedApplications, + canWriteHostIsolationExceptions: canWriteHostIsolationExceptions && isPlatinumPlusLicense, + canReadHostIsolationExceptions, + canWriteBlocklist, + canReadBlocklist, + canWriteEventFilters, + canReadEventFilters, }; }; @@ -55,11 +186,26 @@ export const getEndpointAuthzInitialState = (): EndpointAuthz => { canAccessFleet: false, canAccessEndpointManagement: false, canCreateArtifactsByPolicy: false, + canWriteEndpointList: false, + canReadEndpointList: false, + canWritePolicyManagement: false, + canReadPolicyManagement: false, + canWriteActionsLogManagement: false, + canReadActionsLogManagement: false, canIsolateHost: false, canUnIsolateHost: true, canKillProcess: false, canSuspendProcess: false, canGetRunningProcesses: false, canAccessResponseConsole: false, + canWriteFileOperations: false, + canWriteTrustedApplications: false, + canReadTrustedApplications: false, + canWriteHostIsolationExceptions: false, + canReadHostIsolationExceptions: false, + canWriteBlocklist: false, + canReadBlocklist: false, + canWriteEventFilters: false, + canReadEventFilters: false, }; }; diff --git a/x-pack/plugins/security_solution/common/endpoint/types/authz.ts b/x-pack/plugins/security_solution/common/endpoint/types/authz.ts index e237e4ba1fe9c..b8ca15d69d1a6 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/authz.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/authz.ts @@ -16,6 +16,18 @@ export interface EndpointAuthz { canAccessEndpointManagement: boolean; /** if user has permissions to create Artifacts by Policy */ canCreateArtifactsByPolicy: boolean; + /** if user has write permissions to endpoint list */ + canWriteEndpointList: boolean; + /** if user has read permissions to endpoint list */ + canReadEndpointList: boolean; + /** if user has write permissions for policy management */ + canWritePolicyManagement: boolean; + /** if user has read permissions for policy management */ + canReadPolicyManagement: boolean; + /** if user has write permissions for actions log management */ + canWriteActionsLogManagement: boolean; + /** if user has read permissions for actions log management */ + canReadActionsLogManagement: boolean; /** If user has permissions to isolate hosts */ canIsolateHost: boolean; /** If user has permissions to un-isolate (release) hosts */ @@ -28,6 +40,24 @@ export interface EndpointAuthz { canGetRunningProcesses: boolean; /** If user has permissions to use the Response Actions Console */ canAccessResponseConsole: boolean; + /** If user has write permissions to use file operations */ + canWriteFileOperations: boolean; + /** if user has write permissions for trusted applications */ + canWriteTrustedApplications: boolean; + /** if user has read permissions for trusted applications */ + canReadTrustedApplications: boolean; + /** if user has write permissions for host isolation exceptions */ + canWriteHostIsolationExceptions: boolean; + /** if user has read permissions for host isolation exceptions */ + canReadHostIsolationExceptions: boolean; + /** if user has write permissions for blocklist entries */ + canWriteBlocklist: boolean; + /** if user has read permissions for blocklist entries */ + canReadBlocklist: boolean; + /** if user has write permissions for event filters */ + canWriteEventFilters: boolean; + /** if user has read permissions for event filters */ + canReadEventFilters: boolean; } export type EndpointAuthzKeyList = Array;