From 96982159b461640604ffa216c79258df41a84926 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 26 Oct 2021 14:39:13 +0200 Subject: [PATCH] WIP --- docs/settings/security-settings.asciidoc | 14 +- docs/user/security/audit-logging.asciidoc | 29 +- .../server/authorization/audit_logger.test.ts | 117 ++-- .../server/authorization/audit_logger.ts | 32 +- x-pack/plugins/actions/server/plugin.ts | 8 +- ...rting_authorization_client_factory.test.ts | 8 +- .../alerting_authorization_client_factory.ts | 17 +- .../server/authorization/audit_logger.test.ts | 617 +++++++++--------- .../server/authorization/audit_logger.ts | 64 +- .../server/rules_client_factory.test.ts | 6 - .../server/audit/audit_logger.test.ts | 173 ----- .../server/audit/audit_logger.ts | 73 --- .../server/audit/index.mock.ts | 19 - .../server/audit/index.ts | 8 - .../encrypted_saved_objects_service.test.ts | 349 ---------- .../crypto/encrypted_saved_objects_service.ts | 21 +- .../encrypted_saved_objects/server/plugin.ts | 6 - .../common/licensing/license_features.ts | 6 - .../common/licensing/license_service.test.ts | 9 - .../common/licensing/license_service.ts | 4 - .../server/audit/audit_service.test.ts | 181 +---- .../security/server/audit/audit_service.ts | 50 +- .../security/server/audit/index.mock.ts | 11 - x-pack/plugins/security/server/audit/index.ts | 3 +- .../audit/security_audit_logger.test.ts | 114 ---- .../server/audit/security_audit_logger.ts | 82 --- .../authentication_service.test.ts | 6 +- .../authentication/authentication_service.ts | 5 +- .../authentication/authenticator.test.ts | 20 +- .../server/authentication/authenticator.ts | 12 +- x-pack/plugins/security/server/config.test.ts | 5 +- x-pack/plugins/security/server/config.ts | 5 +- .../server/config_deprecations.test.ts | 62 -- .../security/server/config_deprecations.ts | 26 - x-pack/plugins/security/server/index.ts | 2 +- x-pack/plugins/security/server/plugin.ts | 5 +- .../server/routes/views/login.test.ts | 1 - .../security/server/saved_objects/index.ts | 5 +- ...ecure_saved_objects_client_wrapper.test.ts | 108 +-- .../secure_saved_objects_client_wrapper.ts | 45 +- .../server/spaces/legacy_audit_logger.test.ts | 94 --- .../server/spaces/legacy_audit_logger.ts | 52 -- .../secure_spaces_client_wrapper.test.ts | 153 +---- .../spaces/secure_spaces_client_wrapper.ts | 26 +- .../server/spaces/setup_spaces_client.test.ts | 6 +- .../server/spaces/setup_spaces_client.ts | 4 - .../security_usage_collector.test.ts | 35 +- .../security_usage_collector.ts | 26 +- .../schema/xpack_plugins.json | 6 - 49 files changed, 618 insertions(+), 2112 deletions(-) delete mode 100644 x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.test.ts delete mode 100644 x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.ts delete mode 100644 x-pack/plugins/encrypted_saved_objects/server/audit/index.mock.ts delete mode 100644 x-pack/plugins/encrypted_saved_objects/server/audit/index.ts delete mode 100644 x-pack/plugins/security/server/audit/security_audit_logger.test.ts delete mode 100644 x-pack/plugins/security/server/audit/security_audit_logger.ts delete mode 100644 x-pack/plugins/security/server/spaces/legacy_audit_logger.test.ts delete mode 100644 x-pack/plugins/security/server/spaces/legacy_audit_logger.ts diff --git a/docs/settings/security-settings.asciidoc b/docs/settings/security-settings.asciidoc index 7737745c7cfa853..2ffaf34c391708c 100644 --- a/docs/settings/security-settings.asciidoc +++ b/docs/settings/security-settings.asciidoc @@ -324,7 +324,7 @@ For more details and a reference of audit events, refer to <>, -as the legacy audit logger will be removed in an upcoming version. -============================================================================ - [NOTE] ============================================================================ Audit logs are **disabled** by default. To enable this functionality, you must @@ -26,29 +19,15 @@ set `xpack.security.audit.enabled` to `true` in `kibana.yml`, and configure an <> to write the audit log to a location of your choosing. ============================================================================ -The legacy audit logger uses the standard {kib} logging output, -which can be configured in `kibana.yml`. For more information, refer to <>. -The <> uses a separate logger and can be configured using +The <> uses a separate logger and can be configured using the options in <>. -==== Legacy audit event types - -When you are auditing security events, each request can generate multiple audit -events. The following is a list of the events that can be generated: - -|====== -| `saved_objects_authorization_success` | Logged when a user is authorized to access a saved - objects when using a role with <> -| `saved_objects_authorization_failure` | Logged when a user isn't authorized to access a saved - objects when using a role with <> -|====== - [[xpack-security-ecs-audit-logging]] -==== ECS audit events +==== Audit events [IMPORTANT] ============================================================================ -The following events are only logged if the ECS audit logger is enabled. +The following events are only logged if the audit logger is enabled. For information on how to configure `xpack.security.audit.appender`, refer to <>. ============================================================================ @@ -255,7 +234,7 @@ Refer to the corresponding {es} logs for potential write errors. [[xpack-security-ecs-audit-schema]] -==== ECS audit schema +==== Audit schema Audit logs are written in JSON using https://www.elastic.co/guide/en/ecs/1.6/index.html[Elastic Common Schema (ECS)] specification. diff --git a/x-pack/plugins/actions/server/authorization/audit_logger.test.ts b/x-pack/plugins/actions/server/authorization/audit_logger.test.ts index e304e7368a5148c..e0eee2bf76d83f3 100644 --- a/x-pack/plugins/actions/server/authorization/audit_logger.test.ts +++ b/x-pack/plugins/actions/server/authorization/audit_logger.test.ts @@ -5,73 +5,70 @@ * 2.0. */ -import { ActionsAuthorizationAuditLogger } from './audit_logger'; +// import { ActionsAuthorizationAuditLogger } from './audit_logger'; -const createMockAuditLogger = () => { - return { - log: jest.fn(), - }; -}; +// const createMockAuditLogger = () => { +// return { +// log: jest.fn(), +// }; +// }; describe(`#constructor`, () => { - test('initializes a noop auditLogger if security logger is unavailable', () => { - const actionsAuditLogger = new ActionsAuthorizationAuditLogger(undefined); - - const username = 'foo-user'; - const actionTypeId = 'action-type-id'; - const operation = 'create'; - expect(() => { - actionsAuditLogger.actionsAuthorizationFailure(username, operation, actionTypeId); - actionsAuditLogger.actionsAuthorizationSuccess(username, operation, actionTypeId); - }).not.toThrow(); - }); + // TODO: Update to use ECS audit logger? + // test('initializes a noop auditLogger if security logger is unavailable', () => { + // const actionsAuditLogger = new ActionsAuthorizationAuditLogger(undefined); + // const username = 'foo-user'; + // const actionTypeId = 'action-type-id'; + // const operation = 'create'; + // expect(() => { + // actionsAuditLogger.actionsAuthorizationFailure(username, operation, actionTypeId); + // actionsAuditLogger.actionsAuthorizationSuccess(username, operation, actionTypeId); + // }).not.toThrow(); + // }); }); describe(`#actionsAuthorizationFailure`, () => { - test('logs auth failure', () => { - const auditLogger = createMockAuditLogger(); - const actionsAuditLogger = new ActionsAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const actionTypeId = 'action-type-id'; - const operation = 'create'; - - actionsAuditLogger.actionsAuthorizationFailure(username, operation, actionTypeId); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "actions_authorization_failure", - "foo-user Unauthorized to create a \\"action-type-id\\" action", - Object { - "actionTypeId": "action-type-id", - "operation": "create", - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth failure', () => { + // const auditLogger = createMockAuditLogger(); + // const actionsAuditLogger = new ActionsAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const actionTypeId = 'action-type-id'; + // const operation = 'create'; + // actionsAuditLogger.actionsAuthorizationFailure(username, operation, actionTypeId); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "actions_authorization_failure", + // "foo-user Unauthorized to create a \\"action-type-id\\" action", + // Object { + // "actionTypeId": "action-type-id", + // "operation": "create", + // "username": "foo-user", + // }, + // ] + // `); + // }); }); describe(`#savedObjectsAuthorizationSuccess`, () => { - test('logs auth success', () => { - const auditLogger = createMockAuditLogger(); - const actionsAuditLogger = new ActionsAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const actionTypeId = 'action-type-id'; - - const operation = 'create'; - - actionsAuditLogger.actionsAuthorizationSuccess(username, operation, actionTypeId); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "actions_authorization_success", - "foo-user Authorized to create a \\"action-type-id\\" action", - Object { - "actionTypeId": "action-type-id", - "operation": "create", - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth success', () => { + // const auditLogger = createMockAuditLogger(); + // const actionsAuditLogger = new ActionsAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const actionTypeId = 'action-type-id'; + // const operation = 'create'; + // actionsAuditLogger.actionsAuthorizationSuccess(username, operation, actionTypeId); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "actions_authorization_success", + // "foo-user Authorized to create a \\"action-type-id\\" action", + // Object { + // "actionTypeId": "action-type-id", + // "operation": "create", + // "username": "foo-user", + // }, + // ] + // `); + // }); }); diff --git a/x-pack/plugins/actions/server/authorization/audit_logger.ts b/x-pack/plugins/actions/server/authorization/audit_logger.ts index ce2c6a63875626e..f1bbc3602de4442 100644 --- a/x-pack/plugins/actions/server/authorization/audit_logger.ts +++ b/x-pack/plugins/actions/server/authorization/audit_logger.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LegacyAuditLogger } from '../../../security/server'; +// import { LegacyAuditLogger } from '../../../security/server'; export enum AuthorizationResult { Unauthorized = 'Unauthorized', @@ -13,11 +13,11 @@ export enum AuthorizationResult { } export class ActionsAuthorizationAuditLogger { - private readonly auditLogger: LegacyAuditLogger; + // private readonly auditLogger: LegacyAuditLogger; - constructor(auditLogger: LegacyAuditLogger = { log() {} }) { - this.auditLogger = auditLogger; - } + // constructor(auditLogger: LegacyAuditLogger = { log() {} }) { + // this.auditLogger = auditLogger; + // } public getAuthorizationMessage( authorizationResult: AuthorizationResult, @@ -39,11 +39,12 @@ export class ActionsAuthorizationAuditLogger { operation, actionTypeId ); - this.auditLogger.log('actions_authorization_failure', `${username} ${message}`, { - username, - actionTypeId, - operation, - }); + // TODO: Update to use ECS audit logger? + // this.auditLogger.log('actions_authorization_failure', `${username} ${message}`, { + // username, + // actionTypeId, + // operation, + // }); return message; } @@ -57,11 +58,12 @@ export class ActionsAuthorizationAuditLogger { operation, actionTypeId ); - this.auditLogger.log('actions_authorization_success', `${username} ${message}`, { - username, - actionTypeId, - operation, - }); + // TODO: Update to use ECS audit logger? + // this.auditLogger.log('actions_authorization_success', `${username} ${message}`, { + // username, + // actionTypeId, + // operation, + // }); return message; } } diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 2942c7492906a8d..9e4c9489710aa65 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -479,9 +479,11 @@ export class ActionsPlugin implements Plugin { @@ -101,5 +102,6 @@ test('creates an alerting authorization client with proper constructor arguments }); expect(AlertingAuthorizationAuditLogger).toHaveBeenCalled(); - expect(securityPluginSetup.audit.getLogger).not.toHaveBeenCalled(); + // TODO: Update to use ECS audit logger? + // expect(securityPluginSetup.audit.getLogger).not.toHaveBeenCalled(); }); diff --git a/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts b/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts index 27b2d92eba2561a..4303aa35585c1f7 100644 --- a/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts +++ b/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts @@ -6,7 +6,7 @@ */ import { KibanaRequest } from 'src/core/server'; -import { ALERTS_FEATURE_ID } from '../common'; +// import { ALERTS_FEATURE_ID } from '../common'; import { RuleTypeRegistry } from './types'; import { SecurityPluginSetup, SecurityPluginStart } from '../../security/server'; import { PluginStartContract as FeaturesPluginStart } from '../../features/server'; @@ -27,7 +27,7 @@ export class AlertingAuthorizationClientFactory { private isInitialized = false; private ruleTypeRegistry!: RuleTypeRegistry; private securityPluginStart?: SecurityPluginStart; - private securityPluginSetup?: SecurityPluginSetup; + // private securityPluginSetup?: SecurityPluginSetup; private features!: FeaturesPluginStart; private getSpace!: (request: KibanaRequest) => Promise; private getSpaceId!: (request: KibanaRequest) => string | undefined; @@ -39,14 +39,15 @@ export class AlertingAuthorizationClientFactory { this.isInitialized = true; this.getSpace = options.getSpace; this.ruleTypeRegistry = options.ruleTypeRegistry; - this.securityPluginSetup = options.securityPluginSetup; + // this.securityPluginSetup = options.securityPluginSetup; this.securityPluginStart = options.securityPluginStart; this.features = options.features; this.getSpaceId = options.getSpaceId; } public create(request: KibanaRequest): AlertingAuthorization { - const { securityPluginSetup, securityPluginStart, features } = this; + // const { securityPluginSetup, securityPluginStart, features } = this; + const { securityPluginStart, features } = this; return new AlertingAuthorization({ authorization: securityPluginStart?.authz, request, @@ -54,9 +55,11 @@ export class AlertingAuthorizationClientFactory { getSpaceId: this.getSpaceId, ruleTypeRegistry: this.ruleTypeRegistry, features: features!, - auditLogger: new AlertingAuthorizationAuditLogger( - securityPluginSetup?.audit.getLogger(ALERTS_FEATURE_ID) - ), + auditLogger: new AlertingAuthorizationAuditLogger(), + // TODO: Update to use ECS audit logger? + // auditLogger: new AlertingAuthorizationAuditLogger( + // securityPluginSetup?.audit.getLogger(ALERTS_FEATURE_ID) + // ), }); } } diff --git a/x-pack/plugins/alerting/server/authorization/audit_logger.test.ts b/x-pack/plugins/alerting/server/authorization/audit_logger.test.ts index 7b0ffdb193c831d..343ef6d3b80ef0e 100644 --- a/x-pack/plugins/alerting/server/authorization/audit_logger.test.ts +++ b/x-pack/plugins/alerting/server/authorization/audit_logger.test.ts @@ -5,334 +5,321 @@ * 2.0. */ -import { AlertingAuthorizationAuditLogger, ScopeType } from './audit_logger'; +// import { AlertingAuthorizationAuditLogger, ScopeType } from './audit_logger'; -const createMockAuditLogger = () => { - return { - log: jest.fn(), - }; -}; +// const createMockAuditLogger = () => { +// return { +// log: jest.fn(), +// }; +// }; describe(`#constructor`, () => { - test('initializes a noop auditLogger if security logger is unavailable', () => { - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(undefined); - - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Consumer; - const scope = 'myApp'; - const operation = 'create'; - const entity = 'rule'; - expect(() => { - alertsAuditLogger.logAuthorizationFailure( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - alertsAuditLogger.logAuthorizationSuccess( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - }).not.toThrow(); - }); + // TODO: Update to use ECS audit logger? + // test('initializes a noop auditLogger if security logger is unavailable', () => { + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(undefined); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Consumer; + // const scope = 'myApp'; + // const operation = 'create'; + // const entity = 'rule'; + // expect(() => { + // alertsAuditLogger.logAuthorizationFailure( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // alertsAuditLogger.logAuthorizationSuccess( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // }).not.toThrow(); + // }); }); describe(`#logUnscopedAuthorizationFailure`, () => { - test('logs auth failure of operation', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logUnscopedAuthorizationFailure(username, operation, entity); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_unscoped_authorization_failure", - "foo-user Unauthorized to create rules for any rule types", - Object { - "operation": "create", - "username": "foo-user", - }, - ] - `); - }); - - test('logs auth failure with producer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Producer; - const scope = 'myOtherApp'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logAuthorizationFailure( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_failure", - "foo-user Unauthorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", - Object { - "alertTypeId": "alert-type-id", - "entity": "rule", - "operation": "create", - "scope": "myOtherApp", - "scopeType": 1, - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth failure of operation', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logUnscopedAuthorizationFailure(username, operation, entity); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_unscoped_authorization_failure", + // "foo-user Unauthorized to create rules for any rule types", + // Object { + // "operation": "create", + // "username": "foo-user", + // }, + // ] + // `); + // }); + // TODO: Update to use ECS audit logger? + // test('logs auth failure with producer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Producer; + // const scope = 'myOtherApp'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logAuthorizationFailure( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_failure", + // "foo-user Unauthorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", + // Object { + // "alertTypeId": "alert-type-id", + // "entity": "rule", + // "operation": "create", + // "scope": "myOtherApp", + // "scopeType": 1, + // "username": "foo-user", + // }, + // ] + // `); + // }); }); describe(`#logAuthorizationFailure`, () => { - test('logs auth failure with consumer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Consumer; - const scope = 'myApp'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logAuthorizationFailure( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_failure", - "foo-user Unauthorized to create a \\"alert-type-id\\" rule for \\"myApp\\"", - Object { - "alertTypeId": "alert-type-id", - "entity": "rule", - "operation": "create", - "scope": "myApp", - "scopeType": 0, - "username": "foo-user", - }, - ] - `); - }); - - test('logs auth failure with producer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Producer; - const scope = 'myOtherApp'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logAuthorizationFailure( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_failure", - "foo-user Unauthorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", - Object { - "alertTypeId": "alert-type-id", - "entity": "rule", - "operation": "create", - "scope": "myOtherApp", - "scopeType": 1, - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth failure with consumer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Consumer; + // const scope = 'myApp'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logAuthorizationFailure( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_failure", + // "foo-user Unauthorized to create a \\"alert-type-id\\" rule for \\"myApp\\"", + // Object { + // "alertTypeId": "alert-type-id", + // "entity": "rule", + // "operation": "create", + // "scope": "myApp", + // "scopeType": 0, + // "username": "foo-user", + // }, + // ] + // `); + // }); + // TODO: Update to use ECS audit logger? + // test('logs auth failure with producer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Producer; + // const scope = 'myOtherApp'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logAuthorizationFailure( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_failure", + // "foo-user Unauthorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", + // Object { + // "alertTypeId": "alert-type-id", + // "entity": "rule", + // "operation": "create", + // "scope": "myOtherApp", + // "scopeType": 1, + // "username": "foo-user", + // }, + // ] + // `); + // }); }); describe(`#logBulkAuthorizationSuccess`, () => { - test('logs auth success with consumer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const scopeType = ScopeType.Consumer; - const authorizedEntries: Array<[string, string]> = [ - ['alert-type-id', 'myApp'], - ['other-alert-type-id', 'myOtherApp'], - ]; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logBulkAuthorizationSuccess( - username, - authorizedEntries, - scopeType, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_success", - "foo-user Authorized to create: \\"alert-type-id\\" rules for \\"myApp\\", \\"other-alert-type-id\\" rules for \\"myOtherApp\\"", - Object { - "authorizedEntries": Array [ - Array [ - "alert-type-id", - "myApp", - ], - Array [ - "other-alert-type-id", - "myOtherApp", - ], - ], - "entity": "rule", - "operation": "create", - "scopeType": 0, - "username": "foo-user", - }, - ] - `); - }); - - test('logs auth success with producer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const scopeType = ScopeType.Producer; - const authorizedEntries: Array<[string, string]> = [ - ['alert-type-id', 'myApp'], - ['other-alert-type-id', 'myOtherApp'], - ]; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logBulkAuthorizationSuccess( - username, - authorizedEntries, - scopeType, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_success", - "foo-user Authorized to create: \\"alert-type-id\\" rules by \\"myApp\\", \\"other-alert-type-id\\" rules by \\"myOtherApp\\"", - Object { - "authorizedEntries": Array [ - Array [ - "alert-type-id", - "myApp", - ], - Array [ - "other-alert-type-id", - "myOtherApp", - ], - ], - "entity": "rule", - "operation": "create", - "scopeType": 1, - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth success with consumer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const scopeType = ScopeType.Consumer; + // const authorizedEntries: Array<[string, string]> = [ + // ['alert-type-id', 'myApp'], + // ['other-alert-type-id', 'myOtherApp'], + // ]; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logBulkAuthorizationSuccess( + // username, + // authorizedEntries, + // scopeType, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_success", + // "foo-user Authorized to create: \\"alert-type-id\\" rules for \\"myApp\\", \\"other-alert-type-id\\" rules for \\"myOtherApp\\"", + // Object { + // "authorizedEntries": Array [ + // Array [ + // "alert-type-id", + // "myApp", + // ], + // Array [ + // "other-alert-type-id", + // "myOtherApp", + // ], + // ], + // "entity": "rule", + // "operation": "create", + // "scopeType": 0, + // "username": "foo-user", + // }, + // ] + // `); + // }); + // TODO: Update to use ECS audit logger? + // test('logs auth success with producer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const scopeType = ScopeType.Producer; + // const authorizedEntries: Array<[string, string]> = [ + // ['alert-type-id', 'myApp'], + // ['other-alert-type-id', 'myOtherApp'], + // ]; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logBulkAuthorizationSuccess( + // username, + // authorizedEntries, + // scopeType, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_success", + // "foo-user Authorized to create: \\"alert-type-id\\" rules by \\"myApp\\", \\"other-alert-type-id\\" rules by \\"myOtherApp\\"", + // Object { + // "authorizedEntries": Array [ + // Array [ + // "alert-type-id", + // "myApp", + // ], + // Array [ + // "other-alert-type-id", + // "myOtherApp", + // ], + // ], + // "entity": "rule", + // "operation": "create", + // "scopeType": 1, + // "username": "foo-user", + // }, + // ] + // `); + // }); }); describe(`#savedObjectsAuthorizationSuccess`, () => { - test('logs auth success with consumer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Consumer; - const scope = 'myApp'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logAuthorizationSuccess( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_success", - "foo-user Authorized to create a \\"alert-type-id\\" rule for \\"myApp\\"", - Object { - "alertTypeId": "alert-type-id", - "entity": "rule", - "operation": "create", - "scope": "myApp", - "scopeType": 0, - "username": "foo-user", - }, - ] - `); - }); - - test('logs auth success with producer scope', () => { - const auditLogger = createMockAuditLogger(); - const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); - const username = 'foo-user'; - const alertTypeId = 'alert-type-id'; - const scopeType = ScopeType.Producer; - const scope = 'myOtherApp'; - const operation = 'create'; - const entity = 'rule'; - - alertsAuditLogger.logAuthorizationSuccess( - username, - alertTypeId, - scopeType, - scope, - operation, - entity - ); - - expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alerting_authorization_success", - "foo-user Authorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", - Object { - "alertTypeId": "alert-type-id", - "entity": "rule", - "operation": "create", - "scope": "myOtherApp", - "scopeType": 1, - "username": "foo-user", - }, - ] - `); - }); + // TODO: Update to use ECS audit logger? + // test('logs auth success with consumer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Consumer; + // const scope = 'myApp'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logAuthorizationSuccess( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_success", + // "foo-user Authorized to create a \\"alert-type-id\\" rule for \\"myApp\\"", + // Object { + // "alertTypeId": "alert-type-id", + // "entity": "rule", + // "operation": "create", + // "scope": "myApp", + // "scopeType": 0, + // "username": "foo-user", + // }, + // ] + // `); + // }); + // TODO: Update to use ECS audit logger? + // test('logs auth success with producer scope', () => { + // const auditLogger = createMockAuditLogger(); + // const alertsAuditLogger = new AlertingAuthorizationAuditLogger(auditLogger); + // const username = 'foo-user'; + // const alertTypeId = 'alert-type-id'; + // const scopeType = ScopeType.Producer; + // const scope = 'myOtherApp'; + // const operation = 'create'; + // const entity = 'rule'; + // alertsAuditLogger.logAuthorizationSuccess( + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity + // ); + // expect(auditLogger.log.mock.calls[0]).toMatchInlineSnapshot(` + // Array [ + // "alerting_authorization_success", + // "foo-user Authorized to create a \\"alert-type-id\\" rule by \\"myOtherApp\\"", + // Object { + // "alertTypeId": "alert-type-id", + // "entity": "rule", + // "operation": "create", + // "scope": "myOtherApp", + // "scopeType": 1, + // "username": "foo-user", + // }, + // ] + // `); + // }); }); diff --git a/x-pack/plugins/alerting/server/authorization/audit_logger.ts b/x-pack/plugins/alerting/server/authorization/audit_logger.ts index 2a0c85173380068..d77d7db75939d9d 100644 --- a/x-pack/plugins/alerting/server/authorization/audit_logger.ts +++ b/x-pack/plugins/alerting/server/authorization/audit_logger.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LegacyAuditLogger } from '../../../security/server'; +// import { LegacyAuditLogger } from '../../../security/server'; export enum ScopeType { Consumer, @@ -18,11 +18,11 @@ export enum AuthorizationResult { } export class AlertingAuthorizationAuditLogger { - private readonly auditLogger: LegacyAuditLogger; + // private readonly auditLogger: LegacyAuditLogger; - constructor(auditLogger: LegacyAuditLogger = { log() {} }) { - this.auditLogger = auditLogger; - } + // constructor(auditLogger: LegacyAuditLogger = { log() {} }) { + // this.auditLogger = auditLogger; + // } public getAuthorizationMessage( authorizationResult: AuthorizationResult, @@ -53,14 +53,14 @@ export class AlertingAuthorizationAuditLogger { operation, entity ); - this.auditLogger.log('alerting_authorization_failure', `${username} ${message}`, { - username, - alertTypeId, - scopeType, - scope, - operation, - entity, - }); + // this.auditLogger.log('alerting_authorization_failure', `${username} ${message}`, { + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity, + // }); return message; } @@ -70,10 +70,10 @@ export class AlertingAuthorizationAuditLogger { entity: string ): string { const message = `Unauthorized to ${operation} ${entity}s for any rule types`; - this.auditLogger.log('alerting_unscoped_authorization_failure', `${username} ${message}`, { - username, - operation, - }); + // this.auditLogger.log('alerting_unscoped_authorization_failure', `${username} ${message}`, { + // username, + // operation, + // }); return message; } @@ -93,14 +93,14 @@ export class AlertingAuthorizationAuditLogger { operation, entity ); - this.auditLogger.log('alerting_authorization_success', `${username} ${message}`, { - username, - alertTypeId, - scopeType, - scope, - operation, - entity, - }); + // this.auditLogger.log('alerting_authorization_success', `${username} ${message}`, { + // username, + // alertTypeId, + // scopeType, + // scope, + // operation, + // entity, + // }); return message; } @@ -119,13 +119,13 @@ export class AlertingAuthorizationAuditLogger { }` ) .join(', ')}`; - this.auditLogger.log('alerting_authorization_success', `${username} ${message}`, { - username, - scopeType, - authorizedEntries, - operation, - entity, - }); + // this.auditLogger.log('alerting_authorization_success', `${username} ${message}`, { + // username, + // scopeType, + // authorizedEntries, + // operation, + // entity, + // }); return message; } } diff --git a/x-pack/plugins/alerting/server/rules_client_factory.test.ts b/x-pack/plugins/alerting/server/rules_client_factory.test.ts index 6ccde13ff12a687..62e6fb9dea572bb 100644 --- a/x-pack/plugins/alerting/server/rules_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/rules_client_factory.test.ts @@ -20,7 +20,6 @@ import { AuthenticatedUser } from '../../security/common/model'; import { securityMock } from '../../security/server/mocks'; import { PluginStartContract as ActionsStartContract } from '../../actions/server'; import { actionsMock, actionsAuthorizationMock } from '../../actions/server/mocks'; -import { LegacyAuditLogger } from '../../security/server'; import { eventLogMock } from '../../event_log/server/mocks'; import { alertingAuthorizationMock } from './authorization/alerting_authorization.mock'; import { alertingAuthorizationClientFactoryMock } from './alerting_authorization_client_factory.mock'; @@ -93,11 +92,6 @@ test('creates an alerts client with proper constructor arguments when security i alertsAuthorization as unknown as AlertingAuthorization ); - const logger = { - log: jest.fn(), - } as jest.Mocked; - securityPluginSetup.audit.getLogger.mockReturnValue(logger); - factory.create(request, savedObjectsService); expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { diff --git a/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.test.ts b/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.test.ts deleted file mode 100644 index 695dafe77d3bcf1..000000000000000 --- a/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.test.ts +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mockAuthenticatedUser } from '../../../security/common/model/authenticated_user.mock'; -import { EncryptedSavedObjectsAuditLogger } from './audit_logger'; - -it('properly logs audit events', () => { - const mockInternalAuditLogger = { log: jest.fn() }; - const audit = new EncryptedSavedObjectsAuditLogger(mockInternalAuditLogger); - - audit.encryptAttributesSuccess(['one', 'two'], { - type: 'known-type', - id: 'object-id', - }); - audit.encryptAttributesSuccess(['one', 'two'], { - type: 'known-type-ns', - id: 'object-id-ns', - namespace: 'object-ns', - }); - audit.encryptAttributesSuccess( - ['one', 'two'], - { type: 'known-type-ns', id: 'object-id-ns', namespace: 'object-ns' }, - mockAuthenticatedUser() - ); - - audit.decryptAttributesSuccess(['three', 'four'], { - type: 'known-type-1', - id: 'object-id-1', - }); - audit.decryptAttributesSuccess(['three', 'four'], { - type: 'known-type-1-ns', - id: 'object-id-1-ns', - namespace: 'object-ns', - }); - audit.decryptAttributesSuccess( - ['three', 'four'], - { type: 'known-type-1-ns', id: 'object-id-1-ns', namespace: 'object-ns' }, - mockAuthenticatedUser() - ); - - audit.encryptAttributeFailure('five', { - type: 'known-type-2', - id: 'object-id-2', - }); - audit.encryptAttributeFailure('five', { - type: 'known-type-2-ns', - id: 'object-id-2-ns', - namespace: 'object-ns', - }); - audit.encryptAttributeFailure( - 'five', - { type: 'known-type-2-ns', id: 'object-id-2-ns', namespace: 'object-ns' }, - mockAuthenticatedUser() - ); - - audit.decryptAttributeFailure('six', { - type: 'known-type-3', - id: 'object-id-3', - }); - audit.decryptAttributeFailure('six', { - type: 'known-type-3-ns', - id: 'object-id-3-ns', - namespace: 'object-ns', - }); - audit.decryptAttributeFailure( - 'six', - { type: 'known-type-3-ns', id: 'object-id-3-ns', namespace: 'object-ns' }, - mockAuthenticatedUser() - ); - - expect(mockInternalAuditLogger.log).toHaveBeenCalledTimes(12); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_success', - 'Successfully encrypted attributes "[one,two]" for saved object "[known-type,object-id]".', - { id: 'object-id', type: 'known-type', attributesNames: ['one', 'two'] } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_success', - 'Successfully encrypted attributes "[one,two]" for saved object "[object-ns,known-type-ns,object-id-ns]".', - { - id: 'object-id-ns', - type: 'known-type-ns', - namespace: 'object-ns', - attributesNames: ['one', 'two'], - } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_success', - 'Successfully encrypted attributes "[one,two]" for saved object "[object-ns,known-type-ns,object-id-ns]".', - { - id: 'object-id-ns', - type: 'known-type-ns', - namespace: 'object-ns', - attributesNames: ['one', 'two'], - username: 'user', - } - ); - - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_success', - 'Successfully decrypted attributes "[three,four]" for saved object "[known-type-1,object-id-1]".', - { id: 'object-id-1', type: 'known-type-1', attributesNames: ['three', 'four'] } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_success', - 'Successfully decrypted attributes "[three,four]" for saved object "[object-ns,known-type-1-ns,object-id-1-ns]".', - { - id: 'object-id-1-ns', - type: 'known-type-1-ns', - namespace: 'object-ns', - attributesNames: ['three', 'four'], - } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_success', - 'Successfully decrypted attributes "[three,four]" for saved object "[object-ns,known-type-1-ns,object-id-1-ns]".', - { - id: 'object-id-1-ns', - type: 'known-type-1-ns', - namespace: 'object-ns', - attributesNames: ['three', 'four'], - username: 'user', - } - ); - - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_failure', - 'Failed to encrypt attribute "five" for saved object "[known-type-2,object-id-2]".', - { id: 'object-id-2', type: 'known-type-2', attributeName: 'five' } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_failure', - 'Failed to encrypt attribute "five" for saved object "[object-ns,known-type-2-ns,object-id-2-ns]".', - { id: 'object-id-2-ns', type: 'known-type-2-ns', namespace: 'object-ns', attributeName: 'five' } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'encrypt_failure', - 'Failed to encrypt attribute "five" for saved object "[object-ns,known-type-2-ns,object-id-2-ns]".', - { - id: 'object-id-2-ns', - type: 'known-type-2-ns', - namespace: 'object-ns', - attributeName: 'five', - username: 'user', - } - ); - - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_failure', - 'Failed to decrypt attribute "six" for saved object "[known-type-3,object-id-3]".', - { id: 'object-id-3', type: 'known-type-3', attributeName: 'six' } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_failure', - 'Failed to decrypt attribute "six" for saved object "[object-ns,known-type-3-ns,object-id-3-ns]".', - { id: 'object-id-3-ns', type: 'known-type-3-ns', namespace: 'object-ns', attributeName: 'six' } - ); - expect(mockInternalAuditLogger.log).toHaveBeenCalledWith( - 'decrypt_failure', - 'Failed to decrypt attribute "six" for saved object "[object-ns,known-type-3-ns,object-id-3-ns]".', - { - id: 'object-id-3-ns', - type: 'known-type-3-ns', - namespace: 'object-ns', - attributeName: 'six', - username: 'user', - } - ); -}); diff --git a/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.ts b/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.ts deleted file mode 100644 index e6290e4cc4dd8e5..000000000000000 --- a/x-pack/plugins/encrypted_saved_objects/server/audit/audit_logger.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { AuthenticatedUser, LegacyAuditLogger } from '../../../security/server'; -import type { SavedObjectDescriptor } from '../crypto'; -import { descriptorToArray } from '../crypto'; - -/** - * Represents all audit events the plugin can log. - */ -export class EncryptedSavedObjectsAuditLogger { - constructor(private readonly logger: LegacyAuditLogger = { log() {} }) {} - - public encryptAttributeFailure( - attributeName: string, - descriptor: SavedObjectDescriptor, - user?: AuthenticatedUser - ) { - this.logger.log( - 'encrypt_failure', - `Failed to encrypt attribute "${attributeName}" for saved object "[${descriptorToArray( - descriptor - )}]".`, - { ...descriptor, attributeName, username: user?.username } - ); - } - - public decryptAttributeFailure( - attributeName: string, - descriptor: SavedObjectDescriptor, - user?: AuthenticatedUser - ) { - this.logger.log( - 'decrypt_failure', - `Failed to decrypt attribute "${attributeName}" for saved object "[${descriptorToArray( - descriptor - )}]".`, - { ...descriptor, attributeName, username: user?.username } - ); - } - - public encryptAttributesSuccess( - attributesNames: readonly string[], - descriptor: SavedObjectDescriptor, - user?: AuthenticatedUser - ) { - this.logger.log( - 'encrypt_success', - `Successfully encrypted attributes "[${attributesNames}]" for saved object "[${descriptorToArray( - descriptor - )}]".`, - { ...descriptor, attributesNames, username: user?.username } - ); - } - - public decryptAttributesSuccess( - attributesNames: readonly string[], - descriptor: SavedObjectDescriptor, - user?: AuthenticatedUser - ) { - this.logger.log( - 'decrypt_success', - `Successfully decrypted attributes "[${attributesNames}]" for saved object "[${descriptorToArray( - descriptor - )}]".`, - { ...descriptor, attributesNames, username: user?.username } - ); - } -} diff --git a/x-pack/plugins/encrypted_saved_objects/server/audit/index.mock.ts b/x-pack/plugins/encrypted_saved_objects/server/audit/index.mock.ts deleted file mode 100644 index a74ef1cb4fd2dc6..000000000000000 --- a/x-pack/plugins/encrypted_saved_objects/server/audit/index.mock.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { EncryptedSavedObjectsAuditLogger } from './audit_logger'; - -export const encryptedSavedObjectsAuditLoggerMock = { - create() { - return { - encryptAttributesSuccess: jest.fn(), - encryptAttributeFailure: jest.fn(), - decryptAttributesSuccess: jest.fn(), - decryptAttributeFailure: jest.fn(), - } as unknown as jest.Mocked; - }, -}; diff --git a/x-pack/plugins/encrypted_saved_objects/server/audit/index.ts b/x-pack/plugins/encrypted_saved_objects/server/audit/index.ts deleted file mode 100644 index 99bf6adde22e9b7..000000000000000 --- a/x-pack/plugins/encrypted_saved_objects/server/audit/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { EncryptedSavedObjectsAuditLogger } from './audit_logger'; diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts index 15de21999fba32b..3b87362b6dea173 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts @@ -11,8 +11,6 @@ import nodeCrypto from '@elastic/node-crypto'; import { loggingSystemMock } from 'src/core/server/mocks'; import { mockAuthenticatedUser } from '../../../security/common/model/authenticated_user.mock'; -import type { EncryptedSavedObjectsAuditLogger } from '../audit'; -import { encryptedSavedObjectsAuditLoggerMock } from '../audit/index.mock'; import { EncryptedSavedObjectsService } from './encrypted_saved_objects_service'; import { EncryptionError } from './encryption_error'; @@ -44,15 +42,12 @@ function createNodeCryptMock(encryptionKey: string) { let mockNodeCrypto: jest.Mocked; let service: EncryptedSavedObjectsService; -let mockAuditLogger: jest.Mocked; beforeEach(() => { mockNodeCrypto = createNodeCryptMock('encryption-key-abc'); - mockAuditLogger = encryptedSavedObjectsAuditLoggerMock.create(); service = new EncryptedSavedObjectsService({ primaryCrypto: mockNodeCrypto, logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -148,13 +143,6 @@ describe('#stripOrDecryptAttributes', () => { { user: mockUser } ) ).resolves.toEqual({ attributes: { attrTwo: 'two', attrThree: 'three' } }); - - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('exposes values with `dangerouslyExposeValue` set to `true` using original attributes if provided', async () => { @@ -180,9 +168,6 @@ describe('#stripOrDecryptAttributes', () => { attributes ) ).resolves.toEqual({ attributes: { attrTwo: 'two', attrThree: 'three' } }); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).not.toHaveBeenCalled(); }); it('strips attributes with `dangerouslyExposeValue` set to `true` if failed to decrypt', async () => { @@ -218,13 +203,6 @@ describe('#stripOrDecryptAttributes', () => { expect(decryptedAttributes).toEqual({ attrZero: 'zero', attrTwo: 'two', attrFour: 'four' }); expect(error).toMatchInlineSnapshot(`[Error: Unable to decrypt attribute "attrThree"]`); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); @@ -232,7 +210,6 @@ describe('#stripOrDecryptAttributes', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -284,13 +261,6 @@ describe('#stripOrDecryptAttributes', () => { expect(encryptionError.cause).toEqual( new Error('Decryption is disabled because of missing decryption keys.') ); - - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); @@ -352,13 +322,6 @@ describe('#stripOrDecryptAttributesSync', () => { { user: mockUser } ) ).toEqual({ attributes: { attrTwo: 'two', attrThree: 'three' } }); - - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('exposes values with `dangerouslyExposeValue` set to `true` using original attributes if provided', () => { @@ -384,9 +347,6 @@ describe('#stripOrDecryptAttributesSync', () => { attributes ) ).toEqual({ attributes: { attrTwo: 'two', attrThree: 'three' } }); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).not.toHaveBeenCalled(); }); it('strips attributes with `dangerouslyExposeValue` set to `true` if failed to decrypt', () => { @@ -422,13 +382,6 @@ describe('#stripOrDecryptAttributesSync', () => { expect(decryptedAttributes).toEqual({ attrZero: 'zero', attrTwo: 'two', attrFour: 'four' }); expect(error).toMatchInlineSnapshot(`[Error: Unable to decrypt attribute "attrThree"]`); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); @@ -436,7 +389,6 @@ describe('#stripOrDecryptAttributesSync', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -488,13 +440,6 @@ describe('#stripOrDecryptAttributesSync', () => { expect(encryptionError.cause).toEqual( new Error('Decryption is disabled because of missing decryption keys.') ); - - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); @@ -508,7 +453,6 @@ describe('#encryptAttributes', () => { service = new EncryptedSavedObjectsService({ primaryCrypto: mockNodeCrypto, logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -522,7 +466,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not encrypt attributes for known, but not registered types', async () => { @@ -535,7 +478,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not encrypt attributes that are not supposed to be encrypted', async () => { @@ -550,7 +492,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); }); it('encrypts only attributes that are supposed to be encrypted', async () => { @@ -572,12 +513,6 @@ describe('#encryptAttributes', () => { attrThree: '|three|["known-type-1","object-id",{"attrTwo":"two"}]|', attrFour: null, }); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('encrypts only using primary crypto', async () => { @@ -588,7 +523,6 @@ describe('#encryptAttributes', () => { primaryCrypto: mockNodeCrypto, decryptionOnlyCryptos: [decryptionOnlyCrypto], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', @@ -625,12 +559,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: '|three|["known-type-1","object-id",{"attrTwo":"two"}]|', }); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('includes `namespace` into AAD if provided', async () => { @@ -652,12 +580,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: '|three|["object-ns","known-type-1","object-id",{"attrTwo":"two"}]|', }); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); it('does not include specified attributes to AAD', async () => { @@ -728,20 +650,12 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); describe('without encryption key', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -757,7 +671,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); }); it('fails if needs to encrypt any attribute', async () => { @@ -779,13 +692,6 @@ describe('#encryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledWith( - 'attrOne', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); @@ -801,7 +707,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not decrypt attributes for known, but not registered types', async () => { @@ -814,7 +719,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not decrypt attributes that are not supposed to be decrypted', async () => { @@ -829,7 +733,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); }); it('decrypts only attributes that are supposed to be decrypted', async () => { @@ -862,12 +765,6 @@ describe('#decryptAttributes', () => { attrThree: 'three', attrFour: null, }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('decrypts only attributes that are supposed to be encrypted even if not all provided', async () => { @@ -896,12 +793,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('decrypts if all attributes that contribute to AAD are present', async () => { @@ -934,12 +825,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('decrypts even if attributes in AAD are defined in a different order', async () => { @@ -978,12 +863,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('decrypts if correct namespace is provided', async () => { @@ -1016,12 +895,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); describe('with isTypeBeingConverted option', () => { @@ -1066,12 +939,6 @@ describe('#decryptAttributes', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); it('retries decryption without originId (old object ID)', async () => { @@ -1115,12 +982,6 @@ describe('#decryptAttributes', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: undefined }, - mockUser - ); }); it('retries decryption without namespace *and* without originId (old object ID)', async () => { @@ -1174,12 +1035,6 @@ describe('#decryptAttributes', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); }); @@ -1208,12 +1063,6 @@ describe('#decryptAttributes', () => { attrOne: 'one', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('decrypts non-string attributes and restores their original type', async () => { @@ -1257,12 +1106,6 @@ describe('#decryptAttributes', () => { attrFive: { nested: 'five' }, attrSix: 6, }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree', 'attrFive', 'attrSix'], - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); describe('decryption failures', () => { @@ -1296,13 +1139,6 @@ describe('#decryptAttributes', () => { { user: mockUser } ) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('fails to decrypt if ID does not match', async () => { @@ -1312,13 +1148,6 @@ describe('#decryptAttributes', () => { user: mockUser, }) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id*' }, - mockUser - ); }); it('fails to decrypt if type does not match', async () => { @@ -1328,13 +1157,6 @@ describe('#decryptAttributes', () => { user: mockUser, }) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-2', id: 'object-id' }, - mockUser - ); }); it('fails to decrypt if namespace does not match', async () => { @@ -1351,13 +1173,6 @@ describe('#decryptAttributes', () => { { user: mockUser } ) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id', namespace: 'object-NS' }, - mockUser - ); }); it('fails to decrypt if namespace is expected, but is not provided', async () => { @@ -1372,13 +1187,6 @@ describe('#decryptAttributes', () => { user: mockUser, }) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('fails if retry decryption without namespace is not correct', async () => { @@ -1413,13 +1221,6 @@ describe('#decryptAttributes', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); it('fails to decrypt if encrypted attribute is defined, but not a string', async () => { @@ -1433,13 +1234,6 @@ describe('#decryptAttributes', () => { ).rejects.toThrowError( 'Encrypted "attrThree" attribute should be a string, but found number' ); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('fails to decrypt if encrypted attribute is not correct', async () => { @@ -1451,13 +1245,6 @@ describe('#decryptAttributes', () => { { user: mockUser } ) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('fails to decrypt if the AAD attribute has changed', async () => { @@ -1469,20 +1256,12 @@ describe('#decryptAttributes', () => { { user: mockUser } ) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); it('fails if encrypted with another encryption key', async () => { service = new EncryptedSavedObjectsService({ primaryCrypto: nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ @@ -1496,13 +1275,6 @@ describe('#decryptAttributes', () => { user: mockUser, }) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); @@ -1512,7 +1284,6 @@ describe('#decryptAttributes', () => { primaryCrypto, decryptionOnlyCryptos, logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); esoService.registerType({ @@ -1543,12 +1314,6 @@ describe('#decryptAttributes', () => { await expect( service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); expect(decryptionOnlyCryptoOne.decrypt).not.toHaveBeenCalled(); expect(decryptionOnlyCryptoTwo.decrypt).not.toHaveBeenCalled(); @@ -1563,12 +1328,6 @@ describe('#decryptAttributes', () => { await expect( service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decrypt).toHaveBeenCalledTimes(2); @@ -1585,12 +1344,6 @@ describe('#decryptAttributes', () => { await expect( service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decrypt).toHaveBeenCalledTimes(2); @@ -1609,12 +1362,6 @@ describe('#decryptAttributes', () => { omitPrimaryEncryptionKey: true, }) ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decrypt).not.toHaveBeenCalled(); @@ -1627,7 +1374,6 @@ describe('#decryptAttributes', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -1637,7 +1383,6 @@ describe('#decryptAttributes', () => { service = new EncryptedSavedObjectsService({ decryptionOnlyCryptos: [], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) }); @@ -1648,7 +1393,6 @@ describe('#decryptAttributes', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not fail if can decrypt attributes with decryption only keys', async () => { @@ -1660,7 +1404,6 @@ describe('#decryptAttributes', () => { service = new EncryptedSavedObjectsService({ decryptionOnlyCryptos: [decryptionOnlyCryptoOne], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', @@ -1676,12 +1419,6 @@ describe('#decryptAttributes', () => { attrThree: 'three||["known-type-1","object-id",{"attrTwo":"two"}]', attrFour: null, }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); }); it('fails if needs to decrypt any attribute', async () => { @@ -1695,13 +1432,6 @@ describe('#decryptAttributes', () => { user: mockUser, }) ).rejects.toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrOne', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); @@ -1715,7 +1445,6 @@ describe('#encryptAttributesSync', () => { service = new EncryptedSavedObjectsService({ primaryCrypto: mockNodeCrypto, logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -1759,7 +1488,6 @@ describe('#encryptAttributesSync', () => { primaryCrypto: mockNodeCrypto, decryptionOnlyCryptos: [decryptionOnlyCrypto], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', @@ -1893,7 +1621,6 @@ describe('#encryptAttributesSync', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -1909,7 +1636,6 @@ describe('#encryptAttributesSync', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); }); it('fails if needs to encrypt any attribute', () => { @@ -1931,13 +1657,6 @@ describe('#encryptAttributesSync', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledWith( - 'attrOne', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); @@ -2154,12 +1873,6 @@ describe('#decryptAttributesSync', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); it('retries decryption without originId (old object ID)', () => { @@ -2203,12 +1916,6 @@ describe('#decryptAttributesSync', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: undefined }, - mockUser - ); }); it('retries decryption without namespace *and* without originId (old object ID)', () => { @@ -2262,12 +1969,6 @@ describe('#decryptAttributesSync', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrThree'], - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); }); @@ -2448,13 +2149,6 @@ describe('#decryptAttributesSync', () => { expect.anything(), `["known-type-1","object-id",{"attrOne":"one","attrTwo":"two"}]` ); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrThree', - { type: 'known-type-1', id: 'object-id', namespace: 'object-ns' }, - mockUser - ); }); it('fails to decrypt if encrypted attribute is defined, but not a string', () => { @@ -2497,7 +2191,6 @@ describe('#decryptAttributesSync', () => { service = new EncryptedSavedObjectsService({ primaryCrypto: nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ @@ -2520,7 +2213,6 @@ describe('#decryptAttributesSync', () => { primaryCrypto, decryptionOnlyCryptos, logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); esoService.registerType({ @@ -2554,12 +2246,6 @@ describe('#decryptAttributesSync', () => { encryptedAttributes ) ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); expect(decryptionOnlyCryptoOne.decryptSync).not.toHaveBeenCalled(); expect(decryptionOnlyCryptoTwo.decryptSync).not.toHaveBeenCalled(); @@ -2577,12 +2263,6 @@ describe('#decryptAttributesSync', () => { encryptedAttributes ) ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decryptSync).toHaveBeenCalledTimes(2); @@ -2602,12 +2282,6 @@ describe('#decryptAttributesSync', () => { encryptedAttributes ) ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decryptSync).toHaveBeenCalledTimes(2); @@ -2628,12 +2302,6 @@ describe('#decryptAttributesSync', () => { { omitPrimaryEncryptionKey: true } ) ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); // One call per attributes, we have 2 of them. expect(mockNodeCrypto.decryptSync).not.toHaveBeenCalled(); @@ -2646,7 +2314,6 @@ describe('#decryptAttributesSync', () => { beforeEach(() => { service = new EncryptedSavedObjectsService({ logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); }); @@ -2656,7 +2323,6 @@ describe('#decryptAttributesSync', () => { service = new EncryptedSavedObjectsService({ decryptionOnlyCryptos: [], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) }); @@ -2667,7 +2333,6 @@ describe('#decryptAttributesSync', () => { attrTwo: 'two', attrThree: 'three', }); - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); }); it('does not fail if can decrypt attributes with decryption only keys', () => { @@ -2679,7 +2344,6 @@ describe('#decryptAttributesSync', () => { service = new EncryptedSavedObjectsService({ decryptionOnlyCryptos: [decryptionOnlyCryptoOne], logger: loggingSystemMock.create().get(), - audit: mockAuditLogger, }); service.registerType({ type: 'known-type-1', @@ -2695,12 +2359,6 @@ describe('#decryptAttributesSync', () => { attrThree: 'three||["known-type-1","object-id",{"attrTwo":"two"}]', attrFour: null, }); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( - ['attrOne', 'attrThree'], - { type: 'known-type-1', id: 'object-id' }, - undefined - ); }); it('fails if needs to decrypt any attribute', () => { @@ -2714,13 +2372,6 @@ describe('#decryptAttributesSync', () => { user: mockUser, }) ).toThrowError(EncryptionError); - - expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled(); - expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith( - 'attrOne', - { type: 'known-type-1', id: 'object-id' }, - mockUser - ); }); }); }); diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts index 4980817393c5fec..f3982f0c8807d06 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts @@ -12,7 +12,6 @@ import typeDetect from 'type-detect'; import type { Logger } from 'src/core/server'; import type { AuthenticatedUser } from '../../../security/common/model'; -import type { EncryptedSavedObjectsAuditLogger } from '../audit'; import { EncryptedSavedObjectAttributesDefinition } from './encrypted_saved_object_type_definition'; import { EncryptionError, EncryptionErrorOperation } from './encryption_error'; @@ -84,11 +83,6 @@ interface EncryptedSavedObjectsServiceOptions { */ logger: Logger; - /** - * Audit logger instance. - */ - audit: EncryptedSavedObjectsAuditLogger; - /** * NodeCrypto instance used for both encryption and decryption. */ @@ -294,7 +288,8 @@ export class EncryptedSavedObjectsService { this.options.logger.error( `Failed to encrypt "${attributeName}" attribute: ${err.message || err}` ); - this.options.audit.encryptAttributeFailure(attributeName, descriptor, params?.user); + // TODO: Update to use ECS audit logger? + // this.options.audit.encryptAttributeFailure(attributeName, descriptor, params?.user); throw new EncryptionError( `Unable to encrypt attribute "${attributeName}"`, @@ -323,7 +318,8 @@ export class EncryptedSavedObjectsService { return attributes; } - this.options.audit.encryptAttributesSuccess(encryptedAttributesKeys, descriptor, params?.user); + // TODO: Update to use ECS audit logger? + // this.options.audit.encryptAttributesSuccess(encryptedAttributesKeys, descriptor, params?.user); return { ...attributes, @@ -523,7 +519,8 @@ export class EncryptedSavedObjectsService { } if (typeof attributeValue !== 'string') { - this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); + // TODO: Update to use ECS audit logger? + // this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); throw new Error( `Encrypted "${attributeName}" attribute should be a string, but found ${typeDetect( attributeValue @@ -556,7 +553,8 @@ export class EncryptedSavedObjectsService { this.options.logger.error( `Failed to decrypt "${attributeName}" attribute: ${err.message || err}` ); - this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); + // TODO: Update to use ECS audit logger? + // this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); throw new EncryptionError( `Unable to decrypt attribute "${attributeName}"`, @@ -584,7 +582,8 @@ export class EncryptedSavedObjectsService { return attributes; } - this.options.audit.decryptAttributesSuccess(decryptedAttributesKeys, descriptor, params?.user); + // TODO: Update to use ECS audit logger? + // this.options.audit.decryptAttributesSuccess(decryptedAttributesKeys, descriptor, params?.user); return { ...attributes, diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts index 565d4379014cc08..23738026e0ab696 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts @@ -10,7 +10,6 @@ import nodeCrypto from '@elastic/node-crypto'; import type { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/server'; import type { SecurityPluginSetup } from '../../security/server'; -import { EncryptedSavedObjectsAuditLogger } from './audit'; import type { ConfigType } from './config'; import type { CreateEncryptedSavedObjectsMigrationFn } from './create_migration'; import { getCreateMigration } from './create_migration'; @@ -72,15 +71,11 @@ export class EncryptedSavedObjectsPlugin const decryptionOnlyCryptos = config.keyRotation.decryptionOnlyKeys.map((decryptionKey) => nodeCrypto({ encryptionKey: decryptionKey }) ); - const auditLogger = new EncryptedSavedObjectsAuditLogger( - deps.security?.audit.getLogger('encryptedSavedObjects') - ); const service = Object.freeze( new EncryptedSavedObjectsService({ primaryCrypto, decryptionOnlyCryptos, logger: this.logger, - audit: auditLogger, }) ); @@ -116,7 +111,6 @@ export class EncryptedSavedObjectsPlugin primaryCrypto, decryptionOnlyCryptos, logger: this.logger, - audit: auditLogger, }); serviceForMigration.registerType(typeRegistration); return serviceForMigration; diff --git a/x-pack/plugins/security/common/licensing/license_features.ts b/x-pack/plugins/security/common/licensing/license_features.ts index ac80c89ae7be395..aa0bd7f1f11101a 100644 --- a/x-pack/plugins/security/common/licensing/license_features.ts +++ b/x-pack/plugins/security/common/licensing/license_features.ts @@ -44,12 +44,6 @@ export interface SecurityLicenseFeatures { */ readonly allowAuditLogging: boolean; - /** - * Indicates whether we allow logging of legacy audit events. - * @deprecated - */ - readonly allowLegacyAuditLogging: boolean; - /** * Indicates whether we allow users to define document level security in roles. */ diff --git a/x-pack/plugins/security/common/licensing/license_service.test.ts b/x-pack/plugins/security/common/licensing/license_service.test.ts index cdc80c1a038f154..44cf3803f500a66 100644 --- a/x-pack/plugins/security/common/licensing/license_service.test.ts +++ b/x-pack/plugins/security/common/licensing/license_service.test.ts @@ -28,7 +28,6 @@ describe('license features', function () { allowRbac: false, allowSubFeaturePrivileges: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, }); }); @@ -51,7 +50,6 @@ describe('license features', function () { allowRbac: false, allowSubFeaturePrivileges: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, }); }); @@ -73,7 +71,6 @@ describe('license features', function () { Object { "allowAccessAgreement": false, "allowAuditLogging": false, - "allowLegacyAuditLogging": false, "allowLogin": false, "allowRbac": false, "allowRoleDocumentLevelSecurity": false, @@ -95,7 +92,6 @@ describe('license features', function () { Object { "allowAccessAgreement": true, "allowAuditLogging": true, - "allowLegacyAuditLogging": true, "allowLogin": true, "allowRbac": true, "allowRoleDocumentLevelSecurity": true, @@ -134,7 +130,6 @@ describe('license features', function () { allowRbac: true, allowSubFeaturePrivileges: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, }); expect(getFeatureSpy).toHaveBeenCalledTimes(1); expect(getFeatureSpy).toHaveBeenCalledWith('security'); @@ -160,7 +155,6 @@ describe('license features', function () { allowRbac: false, allowSubFeaturePrivileges: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, }); }); @@ -185,7 +179,6 @@ describe('license features', function () { allowRbac: true, allowSubFeaturePrivileges: false, allowAuditLogging: false, - allowLegacyAuditLogging: true, }); }); @@ -210,7 +203,6 @@ describe('license features', function () { allowRbac: true, allowSubFeaturePrivileges: true, allowAuditLogging: true, - allowLegacyAuditLogging: true, }); }); @@ -235,7 +227,6 @@ describe('license features', function () { allowRbac: true, allowSubFeaturePrivileges: true, allowAuditLogging: true, - allowLegacyAuditLogging: true, }); }); }); diff --git a/x-pack/plugins/security/common/licensing/license_service.ts b/x-pack/plugins/security/common/licensing/license_service.ts index 51093428e84a03e..fdc99c3923983a6 100644 --- a/x-pack/plugins/security/common/licensing/license_service.ts +++ b/x-pack/plugins/security/common/licensing/license_service.ts @@ -81,7 +81,6 @@ export class SecurityLicenseService { showRoleMappingsManagement: false, allowAccessAgreement: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, allowRoleDocumentLevelSecurity: false, allowRoleFieldLevelSecurity: false, allowRbac: false, @@ -101,7 +100,6 @@ export class SecurityLicenseService { showRoleMappingsManagement: false, allowAccessAgreement: false, allowAuditLogging: false, - allowLegacyAuditLogging: false, allowRoleDocumentLevelSecurity: false, allowRoleFieldLevelSecurity: false, allowRbac: false, @@ -109,7 +107,6 @@ export class SecurityLicenseService { }; } - const isLicenseStandardOrBetter = rawLicense.hasAtLeast('standard'); const isLicenseGoldOrBetter = rawLicense.hasAtLeast('gold'); const isLicensePlatinumOrBetter = rawLicense.hasAtLeast('platinum'); return { @@ -119,7 +116,6 @@ export class SecurityLicenseService { showRoleMappingsManagement: isLicenseGoldOrBetter, allowAccessAgreement: isLicenseGoldOrBetter, allowAuditLogging: isLicenseGoldOrBetter, - allowLegacyAuditLogging: isLicenseStandardOrBetter, allowSubFeaturePrivileges: isLicenseGoldOrBetter, // Only platinum and trial licenses are compliant with field- and document-level security. allowRoleDocumentLevelSecurity: isLicensePlatinumOrBetter, diff --git a/x-pack/plugins/security/server/audit/audit_service.test.ts b/x-pack/plugins/security/server/audit/audit_service.test.ts index a1848068eac3530..83fc17426cf40bd 100644 --- a/x-pack/plugins/security/server/audit/audit_service.test.ts +++ b/x-pack/plugins/security/server/audit/audit_service.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { BehaviorSubject, Observable, of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { coreMock, @@ -14,7 +14,6 @@ import { loggingSystemMock, } from 'src/core/server/mocks'; -import type { SecurityLicenseFeatures } from '../../common/licensing'; import { licenseMock } from '../../common/licensing/index.mock'; import type { ConfigType } from '../config'; import { ConfigSchema } from '../config'; @@ -34,7 +33,10 @@ const createConfig = (settings: Partial) => { const logger = loggingSystemMock.createLogger(); const license = licenseMock.create(); -const config = createConfig({ enabled: true }); +const config = createConfig({ + enabled: true, + appender: { type: 'console', layout: { type: 'json' } }, +}); const { logging } = coreMock.createSetup(); const http = httpServiceMock.createSetupContract(); const getCurrentUser = jest.fn().mockReturnValue({ username: 'jdoe', roles: ['admin'] }); @@ -66,7 +68,6 @@ describe('#setup', () => { ).toMatchInlineSnapshot(` Object { "asScoped": [Function], - "getLogger": [Function], } `); audit.stop(); @@ -563,175 +564,3 @@ describe('#filterEvent', () => { ).toBeFalsy(); }); }); - -describe('#getLogger', () => { - test('calls the underlying logger with the provided message and requisite tags', () => { - const pluginId = 'foo'; - - const licenseWithFeatures = licenseMock.create(); - licenseWithFeatures.features$ = new BehaviorSubject({ - allowLegacyAuditLogging: true, - } as SecurityLicenseFeatures).asObservable(); - - const auditService = new AuditService(logger).setup({ - license: licenseWithFeatures, - config, - logging, - http, - getCurrentUser, - getSpaceId, - getSID, - recordAuditLoggingUsage, - }); - - const auditLogger = auditService.getLogger(pluginId); - - const eventType = 'bar'; - const message = 'this is my audit message'; - auditLogger.log(eventType, message); - - expect(logger.info).toHaveBeenCalledTimes(1); - expect(logger.info).toHaveBeenCalledWith(message, { - eventType, - tags: [pluginId, eventType], - }); - }); - - test('calls the underlying logger with the provided metadata', () => { - const pluginId = 'foo'; - - const licenseWithFeatures = licenseMock.create(); - licenseWithFeatures.features$ = new BehaviorSubject({ - allowLegacyAuditLogging: true, - } as SecurityLicenseFeatures).asObservable(); - - const auditService = new AuditService(logger).setup({ - license: licenseWithFeatures, - config, - logging, - http, - getCurrentUser, - getSpaceId, - getSID, - recordAuditLoggingUsage, - }); - - const auditLogger = auditService.getLogger(pluginId); - - const eventType = 'bar'; - const message = 'this is my audit message'; - const metadata = Object.freeze({ - property1: 'value1', - property2: false, - property3: 123, - }); - auditLogger.log(eventType, message, metadata); - - expect(logger.info).toHaveBeenCalledTimes(1); - expect(logger.info).toHaveBeenCalledWith(message, { - eventType, - tags: [pluginId, eventType], - property1: 'value1', - property2: false, - property3: 123, - }); - }); - - test('does not call the underlying logger if license does not support audit logging', () => { - const pluginId = 'foo'; - - const licenseWithFeatures = licenseMock.create(); - licenseWithFeatures.features$ = new BehaviorSubject({ - allowLegacyAuditLogging: false, - } as SecurityLicenseFeatures).asObservable(); - - const auditService = new AuditService(logger).setup({ - license: licenseWithFeatures, - config, - logging, - http, - getCurrentUser, - getSpaceId, - getSID, - recordAuditLoggingUsage, - }); - - const auditLogger = auditService.getLogger(pluginId); - - const eventType = 'bar'; - const message = 'this is my audit message'; - auditLogger.log(eventType, message); - - expect(logger.info).not.toHaveBeenCalled(); - }); - - test('does not call the underlying logger if security audit logging is not enabled', () => { - const pluginId = 'foo'; - - const licenseWithFeatures = licenseMock.create(); - licenseWithFeatures.features$ = new BehaviorSubject({ - allowLegacyAuditLogging: true, - } as SecurityLicenseFeatures).asObservable(); - - const auditService = new AuditService(logger).setup({ - license: licenseWithFeatures, - config: createConfig({ - enabled: false, - }), - logging, - http, - getCurrentUser, - getSpaceId, - getSID, - recordAuditLoggingUsage, - }); - - const auditLogger = auditService.getLogger(pluginId); - - const eventType = 'bar'; - const message = 'this is my audit message'; - auditLogger.log(eventType, message); - - expect(logger.info).not.toHaveBeenCalled(); - }); - - test('calls the underlying logger after license upgrade', () => { - const pluginId = 'foo'; - - const licenseWithFeatures = licenseMock.create(); - - const features$ = new BehaviorSubject({ - allowLegacyAuditLogging: false, - } as SecurityLicenseFeatures); - - licenseWithFeatures.features$ = features$.asObservable(); - - const auditService = new AuditService(logger).setup({ - license: licenseWithFeatures, - config, - logging, - http, - getCurrentUser, - getSpaceId, - getSID, - recordAuditLoggingUsage, - }); - - const auditLogger = auditService.getLogger(pluginId); - - const eventType = 'bar'; - const message = 'this is my audit message'; - auditLogger.log(eventType, message); - - expect(logger.info).not.toHaveBeenCalled(); - - // perform license upgrade - features$.next({ - allowLegacyAuditLogging: true, - } as SecurityLicenseFeatures); - - auditLogger.log(eventType, message); - - expect(logger.info).toHaveBeenCalledTimes(1); - }); -}); diff --git a/x-pack/plugins/security/server/audit/audit_service.ts b/x-pack/plugins/security/server/audit/audit_service.ts index a6205ff1965377e..b3e8032f2249f0e 100644 --- a/x-pack/plugins/security/server/audit/audit_service.ts +++ b/x-pack/plugins/security/server/audit/audit_service.ts @@ -26,20 +26,12 @@ import { httpRequestEvent } from './audit_events'; export const ECS_VERSION = '1.6.0'; export const RECORD_USAGE_INTERVAL = 60 * 60 * 1000; // 1 hour -/** - * @deprecated - */ -export interface LegacyAuditLogger { - log: (eventType: string, message: string, data?: Record) => void; -} - export interface AuditLogger { log: (event: AuditEvent | undefined) => void; } export interface AuditServiceSetup { asScoped: (request: KibanaRequest) => AuditLogger; - getLogger: (id?: string) => LegacyAuditLogger; } interface AuditServiceSetupParams { @@ -62,15 +54,11 @@ export class AuditService { * @deprecated */ private licenseFeaturesSubscription?: Subscription; - /** - * @deprecated - */ - private allowLegacyAuditLogging = false; - private ecsLogger: Logger; + private logger: Logger; private usageIntervalId?: NodeJS.Timeout; - constructor(private readonly logger: Logger) { - this.ecsLogger = logger.get('ecs'); + constructor(_logger: Logger) { + this.logger = _logger.get('ecs'); } setup({ @@ -83,14 +71,6 @@ export class AuditService { getSpaceId, recordAuditLoggingUsage, }: AuditServiceSetupParams): AuditServiceSetup { - if (config.enabled && !config.appender) { - this.licenseFeaturesSubscription = license.features$.subscribe( - ({ allowLegacyAuditLogging }) => { - this.allowLegacyAuditLogging = allowLegacyAuditLogging; - } - ); - } - // Configure logging during setup and when license changes logging.configure( license.features$.pipe( @@ -169,32 +149,12 @@ export class AuditService { }; if (filterEvent(meta, config.ignore_filters)) { const { message, ...eventMeta } = meta; - this.ecsLogger.info(message, eventMeta); + this.logger.info(message, eventMeta); } }; return { log }; }; - /** - * @deprecated - * Use `audit.asScoped(request)` method instead to create an audit logger - */ - const getLogger = (id?: string): LegacyAuditLogger => { - return { - log: (eventType: string, message: string, data?: Record) => { - if (!this.allowLegacyAuditLogging) { - return; - } - - this.logger.info(message, { - tags: id ? [id, eventType] : [eventType], - eventType, - ...data, - }); - }, - }; - }; - http.registerOnPostAuth((request, response, t) => { if (request.auth.isAuthenticated) { asScoped(request).log(httpRequestEvent({ request })); @@ -202,7 +162,7 @@ export class AuditService { return t.next(); }); - return { asScoped, getLogger }; + return { asScoped }; } stop() { diff --git a/x-pack/plugins/security/server/audit/index.mock.ts b/x-pack/plugins/security/server/audit/index.mock.ts index 15fb4c42c351678..ce6885aee50def5 100644 --- a/x-pack/plugins/security/server/audit/index.mock.ts +++ b/x-pack/plugins/security/server/audit/index.mock.ts @@ -6,17 +6,6 @@ */ import type { AuditService } from './audit_service'; -import type { SecurityAuditLogger } from './security_audit_logger'; - -export const securityAuditLoggerMock = { - create() { - return { - savedObjectsAuthorizationFailure: jest.fn(), - savedObjectsAuthorizationSuccess: jest.fn(), - accessAgreementAcknowledged: jest.fn(), - } as unknown as jest.Mocked; - }, -}; export const auditServiceMock = { create() { diff --git a/x-pack/plugins/security/server/audit/index.ts b/x-pack/plugins/security/server/audit/index.ts index c42022bc76aa9d4..b928a9b524a425c 100644 --- a/x-pack/plugins/security/server/audit/index.ts +++ b/x-pack/plugins/security/server/audit/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export { AuditService, AuditServiceSetup, AuditLogger, LegacyAuditLogger } from './audit_service'; +export { AuditService, AuditServiceSetup, AuditLogger } from './audit_service'; export { AuditEvent, userLoginEvent, @@ -15,4 +15,3 @@ export { SavedObjectAction, SpaceAuditAction, } from './audit_events'; -export { SecurityAuditLogger } from './security_audit_logger'; diff --git a/x-pack/plugins/security/server/audit/security_audit_logger.test.ts b/x-pack/plugins/security/server/audit/security_audit_logger.test.ts deleted file mode 100644 index aa32ee36b75bba0..000000000000000 --- a/x-pack/plugins/security/server/audit/security_audit_logger.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { SecurityAuditLogger } from './security_audit_logger'; - -const createMockAuditLogger = () => { - return { - log: jest.fn(), - }; -}; - -describe(`#savedObjectsAuthorizationFailure`, () => { - test('logs via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new SecurityAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - const types = ['foo-type-1', 'foo-type-2']; - const spaceIds = ['foo-space', 'bar-space']; - const missing = [ - { - spaceId: 'foo-space', - privilege: `saved_object:${types[0]}/${action}`, - }, - { - spaceId: 'foo-space', - privilege: `saved_object:${types[1]}/${action}`, - }, - ]; - const args = { - foo: 'bar', - baz: 'quz', - }; - - securityAuditLogger.savedObjectsAuthorizationFailure( - username, - action, - types, - spaceIds, - missing, - args - ); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'saved_objects_authorization_failure', - expect.any(String), - { - username, - action, - types, - spaceIds, - missing, - args, - } - ); - expect(auditLogger.log.mock.calls[0][1]).toMatchInlineSnapshot( - `"foo-user unauthorized to [foo-action] [foo-type-1,foo-type-2] in [foo-space,bar-space]: missing [(foo-space)saved_object:foo-type-1/foo-action,(foo-space)saved_object:foo-type-2/foo-action]"` - ); - }); -}); - -describe(`#savedObjectsAuthorizationSuccess`, () => { - test('logs via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new SecurityAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - const types = ['foo-type-1', 'foo-type-2']; - const spaceIds = ['foo-space', 'bar-space']; - const args = { - foo: 'bar', - baz: 'quz', - }; - - securityAuditLogger.savedObjectsAuthorizationSuccess(username, action, types, spaceIds, args); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'saved_objects_authorization_success', - expect.any(String), - { - username, - action, - types, - spaceIds, - args, - } - ); - expect(auditLogger.log.mock.calls[0][1]).toMatchInlineSnapshot( - `"foo-user authorized to [foo-action] [foo-type-1,foo-type-2] in [foo-space,bar-space]"` - ); - }); -}); - -describe(`#accessAgreementAcknowledged`, () => { - test('logs via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new SecurityAuditLogger(auditLogger); - const username = 'foo-user'; - const provider = { type: 'saml', name: 'saml1' }; - - securityAuditLogger.accessAgreementAcknowledged(username, provider); - - expect(auditLogger.log).toHaveBeenCalledTimes(1); - expect(auditLogger.log).toHaveBeenCalledWith( - 'access_agreement_acknowledged', - 'foo-user acknowledged access agreement (saml/saml1).', - { username, provider } - ); - }); -}); diff --git a/x-pack/plugins/security/server/audit/security_audit_logger.ts b/x-pack/plugins/security/server/audit/security_audit_logger.ts deleted file mode 100644 index 280cc233fca17c2..000000000000000 --- a/x-pack/plugins/security/server/audit/security_audit_logger.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { AuthenticationProvider } from '../../common/model'; -import type { LegacyAuditLogger } from './audit_service'; - -/** - * @deprecated - */ -export class SecurityAuditLogger { - constructor(private readonly logger: LegacyAuditLogger) {} - - /** - * @deprecated - */ - savedObjectsAuthorizationFailure( - username: string, - action: string, - types: string[], - spaceIds: string[], - missing: Array<{ spaceId?: string; privilege: string }>, - args?: Record - ) { - const typesString = types.join(','); - const spacesString = spaceIds.length ? ` in [${spaceIds.join(',')}]` : ''; - const missingString = missing - .map(({ spaceId, privilege }) => `${spaceId ? `(${spaceId})` : ''}${privilege}`) - .join(','); - this.logger.log( - 'saved_objects_authorization_failure', - `${username} unauthorized to [${action}] [${typesString}]${spacesString}: missing [${missingString}]`, - { - username, - action, - types, - spaceIds, - missing, - args, - } - ); - } - - /** - * @deprecated - */ - savedObjectsAuthorizationSuccess( - username: string, - action: string, - types: string[], - spaceIds: string[], - args?: Record - ) { - const typesString = types.join(','); - const spacesString = spaceIds.length ? ` in [${spaceIds.join(',')}]` : ''; - this.logger.log( - 'saved_objects_authorization_success', - `${username} authorized to [${action}] [${typesString}]${spacesString}`, - { - username, - action, - types, - spaceIds, - args, - } - ); - } - - /** - * @deprecated - */ - accessAgreementAcknowledged(username: string, provider: AuthenticationProvider) { - this.logger.log( - 'access_agreement_acknowledged', - `${username} acknowledged access agreement (${provider.type}/${provider.name}).`, - { username, provider } - ); - } -} diff --git a/x-pack/plugins/security/server/authentication/authentication_service.test.ts b/x-pack/plugins/security/server/authentication/authentication_service.test.ts index 3a11a21cfe1c36b..ea95f308eb04625 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.test.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.test.ts @@ -35,8 +35,8 @@ import type { SecurityLicense } from '../../common/licensing'; import { licenseMock } from '../../common/licensing/index.mock'; import type { AuthenticatedUser } from '../../common/model'; import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock'; -import type { AuditServiceSetup, SecurityAuditLogger } from '../audit'; -import { auditServiceMock, securityAuditLoggerMock } from '../audit/index.mock'; +import type { AuditServiceSetup } from '../audit'; +import { auditServiceMock } from '../audit/index.mock'; import type { ConfigType } from '../config'; import { ConfigSchema, createConfig } from '../config'; import type { SecurityFeatureUsageServiceStart } from '../feature_usage'; @@ -57,7 +57,6 @@ describe('AuthenticationService', () => { buildNumber: number; }; let mockStartAuthenticationParams: { - legacyAuditLogger: jest.Mocked; audit: jest.Mocked; config: ConfigType; loggers: LoggerFactory; @@ -86,7 +85,6 @@ describe('AuthenticationService', () => { const coreStart = coreMock.createStart(); mockStartAuthenticationParams = { - legacyAuditLogger: securityAuditLoggerMock.create(), audit: auditServiceMock.create(), config: createConfig( ConfigSchema.validate({ diff --git a/x-pack/plugins/security/server/authentication/authentication_service.ts b/x-pack/plugins/security/server/authentication/authentication_service.ts index 538bc26e6ffe343..ac66e62e97c8afb 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.ts @@ -19,7 +19,7 @@ import { NEXT_URL_QUERY_STRING_PARAMETER } from '../../common/constants'; import type { SecurityLicense } from '../../common/licensing'; import type { AuthenticatedUser } from '../../common/model'; import { shouldProviderUseLoginForm } from '../../common/model'; -import type { AuditServiceSetup, SecurityAuditLogger } from '../audit'; +import type { AuditServiceSetup } from '../audit'; import type { ConfigType } from '../config'; import { getDetailedErrorMessage, getErrorStatusCode } from '../errors'; import type { SecurityFeatureUsageServiceStart } from '../feature_usage'; @@ -44,7 +44,6 @@ interface AuthenticationServiceStartParams { http: Pick; config: ConfigType; clusterClient: IClusterClient; - legacyAuditLogger: SecurityAuditLogger; audit: AuditServiceSetup; featureUsageService: SecurityFeatureUsageServiceStart; session: PublicMethodsOf; @@ -224,7 +223,6 @@ export class AuthenticationService { clusterClient, featureUsageService, http, - legacyAuditLogger, loggers, session, }: AuthenticationServiceStartParams): InternalAuthenticationServiceStart { @@ -250,7 +248,6 @@ export class AuthenticationService { this.session = session; this.authenticator = new Authenticator({ - legacyAuditLogger, audit, loggers, clusterClient, diff --git a/x-pack/plugins/security/server/authentication/authenticator.test.ts b/x-pack/plugins/security/server/authentication/authenticator.test.ts index 4e35b84a93119a1..2cdbd352b795fdd 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.test.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.test.ts @@ -27,7 +27,7 @@ import { import type { SecurityLicenseFeatures } from '../../common/licensing'; import { licenseMock } from '../../common/licensing/index.mock'; import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock'; -import { auditServiceMock, securityAuditLoggerMock } from '../audit/index.mock'; +import { auditServiceMock } from '../audit/index.mock'; import { ConfigSchema, createConfig } from '../config'; import { securityFeatureUsageServiceMock } from '../feature_usage/index.mock'; import type { SessionValue } from '../session_management'; @@ -48,7 +48,6 @@ function getMockOptions({ selector?: AuthenticatorOptions['config']['authc']['selector']; } = {}) { return { - legacyAuditLogger: securityAuditLoggerMock.create(), audit: auditServiceMock.create(), getCurrentUser: jest.fn(), clusterClient: elasticsearchServiceMock.createClusterClient(), @@ -1953,14 +1952,15 @@ describe('Authenticator', () => { accessAgreementAcknowledged: true, }); - expect(mockOptions.legacyAuditLogger.accessAgreementAcknowledged).toHaveBeenCalledTimes(1); - expect(mockOptions.legacyAuditLogger.accessAgreementAcknowledged).toHaveBeenCalledWith( - 'user', - { - type: 'basic', - name: 'basic1', - } - ); + // TODO: Update to use ECS audit logger? + // expect(mockOptions.legacyAuditLogger.accessAgreementAcknowledged).toHaveBeenCalledTimes(1); + // expect(mockOptions.legacyAuditLogger.accessAgreementAcknowledged).toHaveBeenCalledWith( + // 'user', + // { + // type: 'basic', + // name: 'basic1', + // } + // ); expect(mockOptions.featureUsageService.recordPreAccessAgreementUsage).toHaveBeenCalledTimes( 1 diff --git a/x-pack/plugins/security/server/authentication/authenticator.ts b/x-pack/plugins/security/server/authentication/authenticator.ts index f0ade974e4d56ee..cfbaa70a8bf4c18 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.ts @@ -19,7 +19,7 @@ import { import type { SecurityLicense } from '../../common/licensing'; import type { AuthenticatedUser, AuthenticationProvider } from '../../common/model'; import { shouldProviderUseLoginForm } from '../../common/model'; -import type { AuditServiceSetup, SecurityAuditLogger } from '../audit'; +import type { AuditServiceSetup } from '../audit'; import { userLoginEvent } from '../audit'; import type { ConfigType } from '../config'; import { getErrorStatusCode } from '../errors'; @@ -77,7 +77,6 @@ export interface ProviderLoginAttempt { } export interface AuthenticatorOptions { - legacyAuditLogger: SecurityAuditLogger; audit: AuditServiceSetup; featureUsageService: SecurityFeatureUsageServiceStart; getCurrentUser: (request: KibanaRequest) => AuthenticatedUser | null; @@ -465,10 +464,11 @@ export class Authenticator { accessAgreementAcknowledged: true, }); - this.options.legacyAuditLogger.accessAgreementAcknowledged( - currentUser.username, - existingSessionValue.provider - ); + // TODO: Update to use ECS audit logger? + // this.options.legacyAuditLogger.accessAgreementAcknowledged( + // currentUser.username, + // existingSessionValue.provider + // ); this.options.featureUsageService.recordPreAccessAgreementUsage(); } diff --git a/x-pack/plugins/security/server/config.test.ts b/x-pack/plugins/security/server/config.test.ts index ababf435af3c98c..1049caa6f960f1e 100644 --- a/x-pack/plugins/security/server/config.test.ts +++ b/x-pack/plugins/security/server/config.test.ts @@ -1741,16 +1741,15 @@ describe('createConfig()', () => { ).toThrow('[audit.appender.1.layout]: expected at least one defined value but got [undefined]'); }); - it('rejects an ignore_filter when no appender is configured', () => { + it('rejects enabled when no appender is configured', () => { expect(() => ConfigSchema.validate({ audit: { enabled: true, - ignore_filters: [{ actions: ['some_action'] }], }, }) ).toThrow( - '[audit]: xpack.security.audit.ignore_filters can only be used with the ECS audit logger. To enable the ECS audit logger, specify where you want to write the audit events using xpack.security.audit.appender.' + 'xpack.security.audit.appender is required when xpack.security.audit.enabled is set to true.' ); }); diff --git a/x-pack/plugins/security/server/config.ts b/x-pack/plugins/security/server/config.ts index a9e22448e17258a..420deb97a81a8ba 100644 --- a/x-pack/plugins/security/server/config.ts +++ b/x-pack/plugins/security/server/config.ts @@ -289,8 +289,9 @@ export const ConfigSchema = schema.object({ }, { validate: (auditConfig) => { - if (auditConfig.ignore_filters && !auditConfig.appender) { - return 'xpack.security.audit.ignore_filters can only be used with the ECS audit logger. To enable the ECS audit logger, specify where you want to write the audit events using xpack.security.audit.appender.'; + if (!auditConfig.enabled) return; + if (!auditConfig.appender) { + return 'xpack.security.audit.appender is required when xpack.security.audit.enabled is set to true.'; } }, } diff --git a/x-pack/plugins/security/server/config_deprecations.test.ts b/x-pack/plugins/security/server/config_deprecations.test.ts index 3c674de97ad8ef5..7a85e614e4b6235 100644 --- a/x-pack/plugins/security/server/config_deprecations.test.ts +++ b/x-pack/plugins/security/server/config_deprecations.test.ts @@ -191,68 +191,6 @@ describe('Config Deprecations', () => { `); }); - it('warns when using the legacy audit logger', () => { - const config = { - xpack: { - security: { - audit: { - enabled: true, - }, - }, - }, - }; - const { messages, migrated } = applyConfigDeprecations(cloneDeep(config)); - expect(migrated.xpack.security.audit.appender).not.toBeDefined(); - expect(messages).toMatchInlineSnapshot(` - Array [ - "The legacy audit logger is deprecated in favor of the new ECS-compliant audit logger.", - ] - `); - }); - - it('does not warn when using the ECS audit logger', () => { - const config = { - xpack: { - security: { - audit: { - enabled: true, - appender: { - type: 'file', - fileName: './audit.log', - }, - }, - }, - }, - }; - const { messages, migrated } = applyConfigDeprecations(cloneDeep(config)); - expect(migrated).toEqual(config); - expect(messages).toHaveLength(0); - }); - - it('does not warn about using the legacy logger when using the ECS audit logger, even when using the deprecated ECS appender config', () => { - const config = { - xpack: { - security: { - audit: { - enabled: true, - appender: { - type: 'file', - path: './audit.log', - }, - }, - }, - }, - }; - const { messages, migrated } = applyConfigDeprecations(cloneDeep(config)); - expect(migrated.xpack.security.audit.appender.path).not.toBeDefined(); - expect(migrated.xpack.security.audit.appender.fileName).toEqual('./audit.log'); - expect(messages).toMatchInlineSnapshot(` - Array [ - "Setting \\"xpack.security.audit.appender.path\\" has been replaced by \\"xpack.security.audit.appender.fileName\\"", - ] - `); - }); - it(`warns that 'authorization.legacyFallback.enabled' is unused`, () => { const config = { xpack: { diff --git a/x-pack/plugins/security/server/config_deprecations.ts b/x-pack/plugins/security/server/config_deprecations.ts index 055818a159a7913..3a71dbb28add280 100644 --- a/x-pack/plugins/security/server/config_deprecations.ts +++ b/x-pack/plugins/security/server/config_deprecations.ts @@ -30,32 +30,6 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({ unused('authorization.legacyFallback.enabled', { level: 'warning' }), unused('authc.saml.maxRedirectURLSize', { level: 'warning' }), - // Deprecation warning for the legacy audit logger. - (settings, fromPath, addDeprecation, { branch }) => { - const auditLoggingEnabled = settings?.xpack?.security?.audit?.enabled ?? false; - const legacyAuditLoggerEnabled = !settings?.xpack?.security?.audit?.appender; - if (auditLoggingEnabled && legacyAuditLoggerEnabled) { - addDeprecation({ - configPath: 'xpack.security.audit.appender', - title: i18n.translate('xpack.security.deprecations.auditLoggerTitle', { - defaultMessage: 'The legacy audit logger is deprecated', - }), - message: i18n.translate('xpack.security.deprecations.auditLoggerMessage', { - defaultMessage: - 'The legacy audit logger is deprecated in favor of the new ECS-compliant audit logger.', - }), - documentationUrl: `https://www.elastic.co/guide/en/kibana/${branch}/security-settings-kb.html#audit-logging-settings`, - correctiveActions: { - manualSteps: [ - i18n.translate('xpack.security.deprecations.auditLogger.manualStepOneMessage', { - defaultMessage: - 'Declare an audit logger "appender" via "xpack.security.audit.appender" to enable the ECS audit logger.', - }), - ], - }, - }); - } - }, // Deprecation warning for the old array-based format of `xpack.security.authc.providers`. (settings, _fromPath, addDeprecation, { branch }) => { diff --git a/x-pack/plugins/security/server/index.ts b/x-pack/plugins/security/server/index.ts index b3bc85676b07ad8..d1600b52df0adbf 100644 --- a/x-pack/plugins/security/server/index.ts +++ b/x-pack/plugins/security/server/index.ts @@ -29,7 +29,7 @@ export type { } from './authentication'; export type { CheckPrivilegesPayload } from './authorization'; export type AuthorizationServiceSetup = SecurityPluginStart['authz']; -export { LegacyAuditLogger, AuditLogger, AuditEvent } from './audit'; +export { AuditLogger, AuditEvent } from './audit'; export type { SecurityPluginSetup, SecurityPluginStart }; export type { AuthenticatedUser } from '../common/model'; export { ROUTE_TAG_CAN_REDIRECT } from './routes/tags'; diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 0ebdae44c865c8a..80082e9b7dbce37 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -31,7 +31,7 @@ import { SecurityLicenseService } from '../common/licensing'; import type { AnonymousAccessServiceStart } from './anonymous_access'; import { AnonymousAccessService } from './anonymous_access'; import type { AuditServiceSetup } from './audit'; -import { AuditService, SecurityAuditLogger } from './audit'; +import { AuditService } from './audit'; import type { AuthenticationServiceStart, InternalAuthenticationServiceStart, @@ -278,7 +278,6 @@ export class SecurityPlugin }); setupSavedObjects({ - legacyAuditLogger: new SecurityAuditLogger(this.auditSetup.getLogger()), audit: this.auditSetup, authz: this.authorizationSetup, savedObjects: core.savedObjects, @@ -307,7 +306,6 @@ export class SecurityPlugin return Object.freeze({ audit: { asScoped: this.auditSetup.asScoped, - getLogger: this.auditSetup.getLogger, }, authc: { getCurrentUser: (request) => this.getAuthentication().getCurrentUser(request) }, authz: { @@ -355,7 +353,6 @@ export class SecurityPlugin config, featureUsageService: this.featureUsageServiceStart, http: core.http, - legacyAuditLogger: new SecurityAuditLogger(this.auditSetup!.getLogger()), loggers: this.initializerContext.logger, session, }); diff --git a/x-pack/plugins/security/server/routes/views/login.test.ts b/x-pack/plugins/security/server/routes/views/login.test.ts index 6def1b7d77df3da..ee728c29bdc92e1 100644 --- a/x-pack/plugins/security/server/routes/views/login.test.ts +++ b/x-pack/plugins/security/server/routes/views/login.test.ts @@ -171,7 +171,6 @@ describe('Login view routes', () => { showRoleMappingsManagement: true, allowSubFeaturePrivileges: true, allowAuditLogging: true, - allowLegacyAuditLogging: true, showLogin: true, }); diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts index c9c467f1f84658e..07bfe97f9de7db3 100644 --- a/x-pack/plugins/security/server/saved_objects/index.ts +++ b/x-pack/plugins/security/server/saved_objects/index.ts @@ -8,13 +8,12 @@ import type { CoreSetup } from 'src/core/server'; import { SavedObjectsClient } from '../../../../../src/core/server'; -import type { AuditServiceSetup, SecurityAuditLogger } from '../audit'; +import type { AuditServiceSetup } from '../audit'; import type { AuthorizationServiceSetupInternal } from '../authorization'; import type { SpacesService } from '../plugin'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; interface SetupSavedObjectsParams { - legacyAuditLogger: SecurityAuditLogger; audit: AuditServiceSetup; authz: Pick< AuthorizationServiceSetupInternal, @@ -38,7 +37,6 @@ export { } from './ensure_authorized'; export function setupSavedObjects({ - legacyAuditLogger, audit, authz, savedObjects, @@ -59,7 +57,6 @@ export function setupSavedObjects({ return authz.mode.useRbacForRequest(request) ? new SecureSavedObjectsClientWrapper({ actions: authz.actions, - legacyAuditLogger, auditLogger: audit.asScoped(request), baseClient: client, checkSavedObjectsPrivilegesAsCurrentUser: diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts index 0d7d8cfa480fac3..671c11bd6daf8db 100644 --- a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts @@ -18,7 +18,7 @@ import type { import { httpServerMock, savedObjectsClientMock } from 'src/core/server/mocks'; import type { AuditEvent } from '../audit'; -import { auditServiceMock, securityAuditLoggerMock } from '../audit/index.mock'; +import { auditServiceMock } from '../audit/index.mock'; import { Actions } from '../authorization'; import type { SavedObjectActions } from '../authorization/actions/saved_object'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; @@ -65,7 +65,6 @@ const createSecureSavedObjectsClientWrapperOptions = () => { checkSavedObjectsPrivilegesAsCurrentUser: jest.fn(), errors, getSpacesService, - legacyAuditLogger: securityAuditLoggerMock.create(), auditLogger: auditServiceMock.create().asScoped(httpServerMock.createKibanaRequest()), forbiddenError, generalError, @@ -81,8 +80,9 @@ const expectGeneralError = async (fn: Function, args: Record) => { clientOpts.generalError ); expect(clientOpts.errors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + // TODO: Update to use ECS audit logger? + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); }; /** @@ -98,50 +98,55 @@ const expectForbiddenError = async (fn: Function, args: Record, act await expect(fn.bind(client)(...Object.values(args))).rejects.toThrowError( clientOpts.forbiddenError ); - const getCalls = ( - clientOpts.actions.savedObject.get as jest.MockedFunction - ).mock.calls; - const actions = clientOpts.checkSavedObjectsPrivilegesAsCurrentUser.mock.calls[0][0]; - const spaceId = args.options?.namespaces - ? args.options?.namespaces[0] - : args.options?.namespace || 'default'; - - const ACTION = getCalls[0][1]; - const types = getCalls.map((x) => x[0]); - const missing = [{ spaceId, privilege: actions[0] }]; // if there was more than one type, only the first type was unauthorized - const spaceIds = [spaceId]; + // TODO: Update to use ECS audit logger? + // const getCalls = ( + // clientOpts.actions.savedObject.get as jest.MockedFunction + // ).mock.calls; + // const actions = clientOpts.checkSavedObjectsPrivilegesAsCurrentUser.mock.calls[0][0]; + // const spaceId = args.options?.namespaces + // ? args.options?.namespaces[0] + // : args.options?.namespace || 'default'; + + // TODO: Update to use ECS audit logger? + // const ACTION = getCalls[0][1]; + // const types = getCalls.map((x) => x[0]); + // const missing = [{ spaceId, privilege: actions[0] }]; // if there was more than one type, only the first type was unauthorized + // const spaceIds = [spaceId]; expect(clientOpts.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledTimes(1); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - USERNAME, - action ?? ACTION, - types, - spaceIds, - missing, - args - ); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + // TODO: Update to use ECS audit logger? + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledTimes(1); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + // USERNAME, + // action ?? ACTION, + // types, + // spaceIds, + // missing, + // args + // ); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); }; const expectSuccess = async (fn: Function, args: Record, action?: string) => { const result = await fn.bind(client)(...Object.values(args)); - const getCalls = ( - clientOpts.actions.savedObject.get as jest.MockedFunction - ).mock.calls; - const ACTION = getCalls[0][1]; - const types = getCalls.map((x) => x[0]); - const spaceIds = args.options?.namespaces || [args.options?.namespace || 'default']; - - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledTimes(1); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( - USERNAME, - action ?? ACTION, - types, - spaceIds, - args - ); + // TODO: Update to use ECS audit logger? + // const getCalls = ( + // clientOpts.actions.savedObject.get as jest.MockedFunction + // ).mock.calls; + // const ACTION = getCalls[0][1]; + // const types = getCalls.map((x) => x[0]); + // const spaceIds = args.options?.namespaces || [args.options?.namespace || 'default']; + + // TODO: Update to use ECS audit logger? + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledTimes(1); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + // USERNAME, + // action ?? ACTION, + // types, + // spaceIds, + // args + // ); return result; }; @@ -795,15 +800,16 @@ describe('#find', () => { const result = await client.find(options); expect(clientOpts.baseClient.find).not.toHaveBeenCalled(); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledTimes(1); - expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - USERNAME, - 'find', - [type1], - options.namespaces, - [{ spaceId: 'some-ns', privilege: 'mock-saved_object:foo/find' }], - { options } - ); + // TODO: Update to use ECS audit logger? + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledTimes(1); + // expect(clientOpts.legacyAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + // USERNAME, + // 'find', + // [type1], + // options.namespaces, + // [{ spaceId: 'some-ns', privilege: 'mock-saved_object:foo/find' }], + // { options } + // ); expect(result).toEqual({ page: 1, per_page: 20, total: 0, saved_objects: [] }); }); diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts index b0428be87a4f21e..7e0c14ef221072c 100644 --- a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { PublicMethodsOf } from '@kbn/utility-types'; import type { SavedObjectReferenceWithContext, SavedObjectsBaseOptions, @@ -32,7 +31,7 @@ import type { import { SavedObjectsErrorHelpers, SavedObjectsUtils } from '../../../../../src/core/server'; import { ALL_SPACES_ID, UNKNOWN_SPACE } from '../../common/constants'; -import type { AuditLogger, SecurityAuditLogger } from '../audit'; +import type { AuditLogger } from '../audit'; import { SavedObjectAction, savedObjectEvent } from '../audit'; import type { Actions, CheckSavedObjectsPrivileges } from '../authorization'; import type { CheckPrivilegesResponse } from '../authorization/types'; @@ -50,7 +49,6 @@ import { interface SecureSavedObjectsClientWrapperOptions { actions: Actions; - legacyAuditLogger: SecurityAuditLogger; auditLogger: AuditLogger; baseClient: SavedObjectsClientContract; errors: SavedObjectsClientContract['errors']; @@ -84,7 +82,6 @@ interface LegacyEnsureAuthorizedTypeResult { export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContract { private readonly actions: Actions; - private readonly legacyAuditLogger: PublicMethodsOf; private readonly auditLogger: AuditLogger; private readonly baseClient: SavedObjectsClientContract; private readonly checkSavedObjectsPrivilegesAsCurrentUser: CheckSavedObjectsPrivileges; @@ -93,7 +90,6 @@ export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContra constructor({ actions, - legacyAuditLogger, auditLogger, baseClient, checkSavedObjectsPrivilegesAsCurrentUser, @@ -102,7 +98,6 @@ export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContra }: SecureSavedObjectsClientWrapperOptions) { this.errors = errors; this.actions = actions; - this.legacyAuditLogger = legacyAuditLogger; this.auditLogger = auditLogger; this.baseClient = baseClient; this.checkSavedObjectsPrivilegesAsCurrentUser = checkSavedObjectsPrivilegesAsCurrentUser; @@ -900,7 +895,8 @@ export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContra namespaceOrNamespaces: undefined | string | Array, options: LegacyEnsureAuthorizedOptions = {} ): Promise { - const { args, auditAction = action, requireFullAuthorization = true } = options; + // const { args, auditAction = action, requireFullAuthorization = true } = options; + const { requireFullAuthorization = true } = options; const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes]; const actionsToTypesMap = new Map( types.map((type) => [this.actions.savedObject.get(type, action), type]) @@ -908,7 +904,8 @@ export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContra const actions = Array.from(actionsToTypesMap.keys()); const result = await this.checkPrivileges(actions, namespaceOrNamespaces); - const { hasAllRequested, username, privileges } = result; + // const { hasAllRequested, username, privileges } = result; + const { hasAllRequested, privileges } = result; const spaceIds = uniq( privileges.kibana.map(({ resource }) => resource).filter((x) => x !== undefined) ).sort() as string[]; @@ -931,23 +928,25 @@ export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContra ); const logAuthorizationFailure = () => { - this.legacyAuditLogger.savedObjectsAuthorizationFailure( - username, - auditAction, - types, - spaceIds, - missingPrivileges, - args - ); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.savedObjectsAuthorizationFailure( + // username, + // auditAction, + // types, + // spaceIds, + // missingPrivileges, + // args + // ); }; const logAuthorizationSuccess = (typeArray: string[], spaceIdArray: string[]) => { - this.legacyAuditLogger.savedObjectsAuthorizationSuccess( - username, - auditAction, - typeArray, - spaceIdArray, - args - ); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.savedObjectsAuthorizationSuccess( + // username, + // auditAction, + // typeArray, + // spaceIdArray, + // args + // ); }; if (hasAllRequested) { diff --git a/x-pack/plugins/security/server/spaces/legacy_audit_logger.test.ts b/x-pack/plugins/security/server/spaces/legacy_audit_logger.test.ts deleted file mode 100644 index 055e944a173d2ba..000000000000000 --- a/x-pack/plugins/security/server/spaces/legacy_audit_logger.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { LegacySpacesAuditLogger } from './legacy_audit_logger'; - -const createMockAuditLogger = () => { - return { - log: jest.fn(), - }; -}; - -describe(`#savedObjectsAuthorizationFailure`, () => { - test('logs auth failure with spaceIds via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new LegacySpacesAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - const spaceIds = ['foo-space-1', 'foo-space-2']; - - securityAuditLogger.spacesAuthorizationFailure(username, action, spaceIds); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'spaces_authorization_failure', - expect.stringContaining(`${username} unauthorized to ${action} ${spaceIds.join(',')} spaces`), - { - username, - action, - spaceIds, - } - ); - }); - - test('logs auth failure without spaceIds via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new LegacySpacesAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - - securityAuditLogger.spacesAuthorizationFailure(username, action); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'spaces_authorization_failure', - expect.stringContaining(`${username} unauthorized to ${action} spaces`), - { - username, - action, - } - ); - }); -}); - -describe(`#savedObjectsAuthorizationSuccess`, () => { - test('logs auth success with spaceIds via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new LegacySpacesAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - const spaceIds = ['foo-space-1', 'foo-space-2']; - - securityAuditLogger.spacesAuthorizationSuccess(username, action, spaceIds); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'spaces_authorization_success', - expect.stringContaining(`${username} authorized to ${action} ${spaceIds.join(',')} spaces`), - { - username, - action, - spaceIds, - } - ); - }); - - test('logs auth success without spaceIds via auditLogger', () => { - const auditLogger = createMockAuditLogger(); - const securityAuditLogger = new LegacySpacesAuditLogger(auditLogger); - const username = 'foo-user'; - const action = 'foo-action'; - - securityAuditLogger.spacesAuthorizationSuccess(username, action); - - expect(auditLogger.log).toHaveBeenCalledWith( - 'spaces_authorization_success', - expect.stringContaining(`${username} authorized to ${action} spaces`), - { - username, - action, - } - ); - }); -}); diff --git a/x-pack/plugins/security/server/spaces/legacy_audit_logger.ts b/x-pack/plugins/security/server/spaces/legacy_audit_logger.ts deleted file mode 100644 index 3ac4859eb7c8af7..000000000000000 --- a/x-pack/plugins/security/server/spaces/legacy_audit_logger.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { LegacyAuditLogger } from '../audit'; - -/** - * @deprecated will be removed in 8.0 - */ -export class LegacySpacesAuditLogger { - private readonly auditLogger: LegacyAuditLogger; - - /** - * @deprecated will be removed in 8.0 - */ - constructor(auditLogger: LegacyAuditLogger = { log() {} }) { - this.auditLogger = auditLogger; - } - - /** - * @deprecated will be removed in 8.0 - */ - public spacesAuthorizationFailure(username: string, action: string, spaceIds?: string[]) { - this.auditLogger.log( - 'spaces_authorization_failure', - `${username} unauthorized to ${action}${spaceIds ? ' ' + spaceIds.join(',') : ''} spaces`, - { - username, - action, - spaceIds, - } - ); - } - - /** - * @deprecated will be removed in 8.0 - */ - public spacesAuthorizationSuccess(username: string, action: string, spaceIds?: string[]) { - this.auditLogger.log( - 'spaces_authorization_success', - `${username} authorized to ${action}${spaceIds ? ' ' + spaceIds.join(',') : ''} spaces`, - { - username, - action, - spaceIds, - } - ); - } -} diff --git a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts index 10261b98b8f0a74..7f62948251d7cc6 100644 --- a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.test.ts @@ -23,7 +23,6 @@ import type { } from '../authorization'; import { authorizationMock } from '../authorization/index.mock'; import type { CheckPrivilegesResponse } from '../authorization/types'; -import type { LegacySpacesAuditLogger } from './legacy_audit_logger'; import { getAliasId, LEGACY_URL_ALIAS_TYPE, @@ -70,10 +69,6 @@ const setup = ({ securityEnabled = false }: Opts = {}) => { }); authorization.mode.useRbacForRequest.mockReturnValue(securityEnabled); - const legacyAuditLogger = { - spacesAuthorizationFailure: jest.fn(), - spacesAuthorizationSuccess: jest.fn(), - } as unknown as jest.Mocked; const auditLogger = auditServiceMock.create().asScoped(httpServerMock.createKibanaRequest()); const request = httpServerMock.createKibanaRequest(); @@ -89,7 +84,6 @@ const setup = ({ securityEnabled = false }: Opts = {}) => { request, authorization, auditLogger, - legacyAuditLogger, errors ); return { @@ -98,7 +92,6 @@ const setup = ({ securityEnabled = false }: Opts = {}) => { request, baseClient, auditLogger, - legacyAuditLogger, forbiddenError, }; }; @@ -111,49 +104,6 @@ const expectNoAuthorizationCheck = ( expect(authorization.checkSavedObjectsPrivilegesWithRequest).not.toHaveBeenCalled(); }; -const expectNoAuditLogging = (auditLogger: jest.Mocked) => { - expect(auditLogger.spacesAuthorizationFailure).not.toHaveBeenCalled(); - expect(auditLogger.spacesAuthorizationSuccess).not.toHaveBeenCalled(); -}; - -const expectForbiddenAuditLogging = ( - auditLogger: jest.Mocked, - username: string, - operation: string, - spaceId?: string -) => { - expect(auditLogger.spacesAuthorizationFailure).toHaveBeenCalledTimes(1); - if (spaceId) { - expect(auditLogger.spacesAuthorizationFailure).toHaveBeenCalledWith(username, operation, [ - spaceId, - ]); - } else { - expect(auditLogger.spacesAuthorizationFailure).toHaveBeenCalledWith(username, operation); - } - - expect(auditLogger.spacesAuthorizationSuccess).not.toHaveBeenCalled(); -}; - -const expectSuccessAuditLogging = ( - auditLogger: jest.Mocked, - username: string, - operation: string, - spaceIds?: string[] -) => { - expect(auditLogger.spacesAuthorizationSuccess).toHaveBeenCalledTimes(1); - if (spaceIds) { - expect(auditLogger.spacesAuthorizationSuccess).toHaveBeenCalledWith( - username, - operation, - spaceIds - ); - } else { - expect(auditLogger.spacesAuthorizationSuccess).toHaveBeenCalledWith(username, operation); - } - - expect(auditLogger.spacesAuthorizationFailure).not.toHaveBeenCalled(); -}; - const expectAuditEvent = ( auditLogger: AuditLogger, action: string, @@ -209,7 +159,7 @@ describe('SecureSpacesClientWrapper', () => { ]; it('delegates to base client when security is not enabled', async () => { - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger } = setup({ + const { wrapper, baseClient, authorization, auditLogger } = setup({ securityEnabled: false, }); @@ -218,7 +168,6 @@ describe('SecureSpacesClientWrapper', () => { expect(baseClient.getAll).toHaveBeenCalledWith({ purpose: 'any' }); expect(response).toEqual(spaces); expectNoAuthorizationCheck(authorization); - expectNoAuditLogging(legacyAuditLogger); expectAuditEvent(auditLogger, SpaceAuditAction.FIND, 'success', { type: 'space', id: spaces[0].id, @@ -269,10 +218,9 @@ describe('SecureSpacesClientWrapper', () => { describe(`with purpose='${scenario.purpose}'`, () => { test(`throws Boom.forbidden when user isn't authorized for any spaces`, async () => { const username = 'some-user'; - const { authorization, wrapper, baseClient, request, auditLogger, legacyAuditLogger } = - setup({ - securityEnabled: true, - }); + const { authorization, wrapper, baseClient, request, auditLogger } = setup({ + securityEnabled: true, + }); const privileges = scenario.expectedPrivilege(authorization); @@ -303,16 +251,14 @@ describe('SecureSpacesClientWrapper', () => { { kibana: privileges } ); - expectForbiddenAuditLogging(legacyAuditLogger, username, 'getAll'); expectAuditEvent(auditLogger, SpaceAuditAction.FIND, 'failure'); }); test(`returns spaces that the user is authorized for`, async () => { const username = 'some-user'; - const { authorization, wrapper, baseClient, request, auditLogger, legacyAuditLogger } = - setup({ - securityEnabled: true, - }); + const { authorization, wrapper, baseClient, request, auditLogger } = setup({ + securityEnabled: true, + }); const privileges = scenario.expectedPrivilege(authorization); @@ -342,7 +288,6 @@ describe('SecureSpacesClientWrapper', () => { { kibana: privileges } ); - expectSuccessAuditLogging(legacyAuditLogger, username, 'getAll', [spaces[0].id]); expectAuditEvent(auditLogger, SpaceAuditAction.FIND, 'success', { type: 'space', id: spaces[0].id, @@ -354,7 +299,7 @@ describe('SecureSpacesClientWrapper', () => { describe('#get', () => { it('delegates to base client when security is not enabled', async () => { - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger } = setup({ + const { wrapper, baseClient, authorization, auditLogger } = setup({ securityEnabled: false, }); @@ -363,7 +308,6 @@ describe('SecureSpacesClientWrapper', () => { expect(baseClient.get).toHaveBeenCalledWith('default'); expect(response).toEqual(spaces[0]); expectNoAuthorizationCheck(authorization); - expectNoAuditLogging(legacyAuditLogger); expectAuditEvent(auditLogger, SpaceAuditAction.GET, 'success', { type: 'space', id: spaces[0].id, @@ -374,11 +318,9 @@ describe('SecureSpacesClientWrapper', () => { const username = 'some_user'; const spaceId = 'default'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -404,7 +346,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.login, }); - expectForbiddenAuditLogging(legacyAuditLogger, username, 'get', spaceId); expectAuditEvent(auditLogger, SpaceAuditAction.GET, 'failure', { type: 'space', id: spaces[0].id, @@ -415,11 +356,9 @@ describe('SecureSpacesClientWrapper', () => { const username = 'some_user'; const spaceId = 'default'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -444,7 +383,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.login, }); - expectSuccessAuditLogging(legacyAuditLogger, username, 'get', [spaceId]); expectAuditEvent(auditLogger, SpaceAuditAction.GET, 'success', { type: 'space', id: spaceId, @@ -460,7 +398,7 @@ describe('SecureSpacesClientWrapper', () => { }); it('delegates to base client when security is not enabled', async () => { - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger } = setup({ + const { wrapper, baseClient, authorization, auditLogger } = setup({ securityEnabled: false, }); @@ -469,7 +407,6 @@ describe('SecureSpacesClientWrapper', () => { expect(baseClient.create).toHaveBeenCalledWith(space); expect(response).toEqual(space); expectNoAuthorizationCheck(authorization); - expectNoAuditLogging(legacyAuditLogger); expectAuditEvent(auditLogger, SpaceAuditAction.CREATE, 'unknown', { type: 'space', id: space.id, @@ -479,11 +416,9 @@ describe('SecureSpacesClientWrapper', () => { test(`throws a forbidden error when unauthorized`, async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -507,7 +442,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectForbiddenAuditLogging(legacyAuditLogger, username, 'create'); expectAuditEvent(auditLogger, SpaceAuditAction.CREATE, 'failure', { type: 'space', id: space.id, @@ -517,11 +451,9 @@ describe('SecureSpacesClientWrapper', () => { it('creates the space when authorized', async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -546,7 +478,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectSuccessAuditLogging(legacyAuditLogger, username, 'create'); expectAuditEvent(auditLogger, SpaceAuditAction.CREATE, 'unknown', { type: 'space', id: space.id, @@ -562,7 +493,7 @@ describe('SecureSpacesClientWrapper', () => { }); it('delegates to base client when security is not enabled', async () => { - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger } = setup({ + const { wrapper, baseClient, authorization, auditLogger } = setup({ securityEnabled: false, }); @@ -571,7 +502,6 @@ describe('SecureSpacesClientWrapper', () => { expect(baseClient.update).toHaveBeenCalledWith(space.id, space); expect(response).toEqual(space.id); expectNoAuthorizationCheck(authorization); - expectNoAuditLogging(legacyAuditLogger); expectAuditEvent(auditLogger, SpaceAuditAction.UPDATE, 'unknown', { type: 'space', id: space.id, @@ -581,11 +511,9 @@ describe('SecureSpacesClientWrapper', () => { test(`throws a forbidden error when unauthorized`, async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -609,7 +537,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectForbiddenAuditLogging(legacyAuditLogger, username, 'update'); expectAuditEvent(auditLogger, SpaceAuditAction.UPDATE, 'failure', { type: 'space', id: space.id, @@ -619,11 +546,9 @@ describe('SecureSpacesClientWrapper', () => { it('updates the space when authorized', async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -648,7 +573,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectSuccessAuditLogging(legacyAuditLogger, username, 'update'); expectAuditEvent(auditLogger, SpaceAuditAction.UPDATE, 'unknown', { type: 'space', id: space.id, @@ -664,7 +588,7 @@ describe('SecureSpacesClientWrapper', () => { }); it('delegates to base client when security is not enabled', async () => { - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger } = setup({ + const { wrapper, baseClient, authorization, auditLogger } = setup({ securityEnabled: false, }); @@ -672,7 +596,6 @@ describe('SecureSpacesClientWrapper', () => { expect(baseClient.delete).toHaveBeenCalledTimes(1); expect(baseClient.delete).toHaveBeenCalledWith(space.id); expectNoAuthorizationCheck(authorization); - expectNoAuditLogging(legacyAuditLogger); expectAuditEvent(auditLogger, SpaceAuditAction.DELETE, 'unknown', { type: 'space', id: space.id, @@ -682,11 +605,9 @@ describe('SecureSpacesClientWrapper', () => { test(`throws a forbidden error when unauthorized`, async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -710,7 +631,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectForbiddenAuditLogging(legacyAuditLogger, username, 'delete'); expectAuditEvent(auditLogger, SpaceAuditAction.DELETE, 'failure', { type: 'space', id: space.id, @@ -720,11 +640,9 @@ describe('SecureSpacesClientWrapper', () => { it('deletes the space when authorized', async () => { const username = 'some_user'; - const { wrapper, baseClient, authorization, auditLogger, legacyAuditLogger, request } = setup( - { - securityEnabled: true, - } - ); + const { wrapper, baseClient, authorization, auditLogger, request } = setup({ + securityEnabled: true, + }); const checkPrivileges = jest.fn().mockResolvedValue({ username, @@ -747,7 +665,6 @@ describe('SecureSpacesClientWrapper', () => { kibana: authorization.actions.space.manage, }); - expectSuccessAuditLogging(legacyAuditLogger, username, 'delete'); expectAuditEvent(auditLogger, SpaceAuditAction.DELETE, 'unknown', { type: 'space', id: space.id, diff --git a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.ts b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.ts index e2b57d01fe11cd4..577fa08c87658ae 100644 --- a/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.ts +++ b/x-pack/plugins/security/server/spaces/secure_spaces_client_wrapper.ts @@ -23,7 +23,6 @@ import type { AuthorizationServiceSetup } from '../authorization'; import type { SecurityPluginSetup } from '../plugin'; import type { EnsureAuthorizedDependencies, EnsureAuthorizedOptions } from '../saved_objects'; import { ensureAuthorized, isAuthorizedForObjectInAllSpaces } from '../saved_objects'; -import type { LegacySpacesAuditLogger } from './legacy_audit_logger'; const PURPOSE_PRIVILEGE_MAP: Record< GetAllSpacesPurpose, @@ -52,7 +51,6 @@ export class SecureSpacesClientWrapper implements ISpacesClient { private readonly request: KibanaRequest, private readonly authorization: AuthorizationServiceSetup, private readonly auditLogger: AuditLogger, - private readonly legacyAuditLogger: LegacySpacesAuditLogger, private readonly errors: SavedObjectsClientContract['errors'] ) {} @@ -89,7 +87,7 @@ export class SecureSpacesClientWrapper implements ISpacesClient { ); // Check all privileges against all spaces - const { username, privileges } = await checkPrivileges.atSpaces(spaceIds, { + const { privileges } = await checkPrivileges.atSpaces(spaceIds, { kibana: Object.values(allPrivileges).flat(), }); @@ -132,7 +130,6 @@ export class SecureSpacesClientWrapper implements ISpacesClient { if (authorizedSpaces.length === 0) { const error = Boom.forbidden(); - this.legacyAuditLogger.spacesAuthorizationFailure(username, 'getAll'); this.auditLogger.log( spaceAuditEvent({ action: SpaceAuditAction.FIND, @@ -143,9 +140,6 @@ export class SecureSpacesClientWrapper implements ISpacesClient { throw error; // Note: there is a catch for this in `SpacesSavedObjectsClient.find`; if we get rid of this error, remove that too } - const authorizedSpaceIds = authorizedSpaces.map((space) => space.id); - - this.legacyAuditLogger.spacesAuthorizationSuccess(username, 'getAll', authorizedSpaceIds); authorizedSpaces.forEach(({ id }) => this.auditLogger.log( spaceAuditEvent({ @@ -364,12 +358,15 @@ export class SecureSpacesClientWrapper implements ISpacesClient { private async ensureAuthorizedGlobally(action: string, method: string, forbiddenMessage: string) { const checkPrivileges = this.authorization.checkPrivilegesWithRequest(this.request); - const { username, hasAllRequested } = await checkPrivileges.globally({ kibana: action }); + // const { username, hasAllRequested } = await checkPrivileges.globally({ kibana: action }); + const { hasAllRequested } = await checkPrivileges.globally({ kibana: action }); if (hasAllRequested) { - this.legacyAuditLogger.spacesAuthorizationSuccess(username, method); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.spacesAuthorizationSuccess(username, method); } else { - this.legacyAuditLogger.spacesAuthorizationFailure(username, method); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.spacesAuthorizationFailure(username, method); throw Boom.forbidden(forbiddenMessage); } } @@ -381,14 +378,17 @@ export class SecureSpacesClientWrapper implements ISpacesClient { forbiddenMessage: string ) { const checkPrivileges = this.authorization.checkPrivilegesWithRequest(this.request); - const { username, hasAllRequested } = await checkPrivileges.atSpace(spaceId, { + // const { username, hasAllRequested } = await checkPrivileges.atSpace(spaceId, { + const { hasAllRequested } = await checkPrivileges.atSpace(spaceId, { kibana: action, }); if (hasAllRequested) { - this.legacyAuditLogger.spacesAuthorizationSuccess(username, method, [spaceId]); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.spacesAuthorizationSuccess(username, method, [spaceId]); } else { - this.legacyAuditLogger.spacesAuthorizationFailure(username, method, [spaceId]); + // TODO: Update to use ECS audit logger? + // this.legacyAuditLogger.spacesAuthorizationFailure(username, method, [spaceId]); throw Boom.forbidden(forbiddenMessage); } } diff --git a/x-pack/plugins/security/server/spaces/setup_spaces_client.test.ts b/x-pack/plugins/security/server/spaces/setup_spaces_client.test.ts index a6849c7ea9a8694..4b884b3bdcff490 100644 --- a/x-pack/plugins/security/server/spaces/setup_spaces_client.test.ts +++ b/x-pack/plugins/security/server/spaces/setup_spaces_client.test.ts @@ -19,7 +19,8 @@ describe('setupSpacesClient', () => { setupSpacesClient({ authz, audit }); - expect(audit.getLogger).not.toHaveBeenCalled(); + // TODO: `asScoped` isn't called synchronously. Figure out what else to check to perform this test + // expect(audit.asScoped).not.toHaveBeenCalled(); }); it('configures the repository factory, wrapper, and audit logger', () => { @@ -31,7 +32,8 @@ describe('setupSpacesClient', () => { expect(spaces.spacesClient.registerClientWrapper).toHaveBeenCalledTimes(1); expect(spaces.spacesClient.setClientRepositoryFactory).toHaveBeenCalledTimes(1); - expect(audit.getLogger).toHaveBeenCalledTimes(1); + // TODO: `asScoped` isn't called synchronously. Deside if we need to check this - and if so - how + // expect(audit.asScoped).toHaveBeenCalledTimes(1); }); it('creates a factory that creates an internal repository when RBAC is used for the request', () => { diff --git a/x-pack/plugins/security/server/spaces/setup_spaces_client.ts b/x-pack/plugins/security/server/spaces/setup_spaces_client.ts index b518a1cff2c0fd0..0d2f90290425f60 100644 --- a/x-pack/plugins/security/server/spaces/setup_spaces_client.ts +++ b/x-pack/plugins/security/server/spaces/setup_spaces_client.ts @@ -9,7 +9,6 @@ import { SavedObjectsClient } from '../../../../../src/core/server'; import type { SpacesPluginSetup } from '../../../spaces/server'; import type { AuditServiceSetup } from '../audit'; import type { AuthorizationServiceSetup } from '../authorization'; -import { LegacySpacesAuditLogger } from './legacy_audit_logger'; import { SecureSpacesClientWrapper } from './secure_spaces_client_wrapper'; interface Deps { @@ -31,8 +30,6 @@ export const setupSpacesClient = ({ audit, authz, spaces }: Deps) => { return savedObjectsStart.createScopedRepository(request, ['space']); }); - const spacesAuditLogger = new LegacySpacesAuditLogger(audit.getLogger()); - spacesClient.registerClientWrapper( (request, baseClient) => new SecureSpacesClientWrapper( @@ -40,7 +37,6 @@ export const setupSpacesClient = ({ audit, authz, spaces }: Deps) => { request, authz, audit.asScoped(request), - spacesAuditLogger, SavedObjectsClient.errors ) ); diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts index 3a53a2422770c94..d66e46994f65008 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts @@ -33,7 +33,6 @@ describe('Security UsageCollector', () => { license.getFeatures.mockReturnValue({ allowAccessAgreement, allowAuditLogging, - allowLegacyAuditLogging: allowAuditLogging, allowRbac, } as SecurityLicenseFeatures); return license; @@ -343,35 +342,7 @@ describe('Security UsageCollector', () => { }); describe('audit logging', () => { - it('reports when legacy audit logging is enabled (and ECS audit logging is not enabled)', async () => { - const config = createSecurityConfig( - ConfigSchema.validate({ - audit: { - enabled: true, - appender: undefined, - }, - }) - ); - const usageCollection = usageCollectionPluginMock.createSetupContract(); - const license = createSecurityLicense({ - isLicenseAvailable: true, - allowLegacyAuditLogging: true, - allowAuditLogging: true, - }); - registerSecurityUsageCollector({ usageCollection, config, license }); - - const usage = await usageCollection - .getCollectorByType('security') - ?.fetch(collectorFetchContext); - - expect(usage).toEqual({ - ...DEFAULT_USAGE, - auditLoggingEnabled: true, - auditLoggingType: 'legacy', - }); - }); - - it('reports when ECS audit logging is enabled (and legacy audit logging is not enabled)', async () => { + it('reports when audit logging is enabled', async () => { const config = createSecurityConfig( ConfigSchema.validate({ audit: { @@ -383,7 +354,6 @@ describe('Security UsageCollector', () => { const usageCollection = usageCollectionPluginMock.createSetupContract(); const license = createSecurityLicense({ isLicenseAvailable: true, - allowLegacyAuditLogging: true, allowAuditLogging: true, }); registerSecurityUsageCollector({ usageCollection, config, license }); @@ -395,7 +365,6 @@ describe('Security UsageCollector', () => { expect(usage).toEqual({ ...DEFAULT_USAGE, auditLoggingEnabled: true, - auditLoggingType: 'ecs', }); }); @@ -404,6 +373,7 @@ describe('Security UsageCollector', () => { ConfigSchema.validate({ audit: { enabled: true, + appender: { type: 'console', layout: { type: 'json' } }, }, }) ); @@ -418,7 +388,6 @@ describe('Security UsageCollector', () => { expect(usage).toEqual({ ...DEFAULT_USAGE, auditLoggingEnabled: false, - auditLoggingType: undefined, }); }); }); diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts index 66f414109d7bbf0..9b3826372bce232 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts @@ -12,7 +12,6 @@ import type { ConfigType } from '../config'; interface Usage { auditLoggingEnabled: boolean; - auditLoggingType?: 'ecs' | 'legacy'; loginSelectorEnabled: boolean; accessAgreementEnabled: boolean; authProviderCount: number; @@ -62,13 +61,6 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens 'Indicates if audit logging is both enabled and supported by the current license.', }, }, - auditLoggingType: { - type: 'keyword', - _meta: { - description: - 'If auditLoggingEnabled is true, indicates what type is enabled (ECS or legacy).', - }, - }, loginSelectorEnabled: { type: 'boolean', _meta: { @@ -132,8 +124,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens }, }, fetch: () => { - const { allowRbac, allowAccessAgreement, allowAuditLogging, allowLegacyAuditLogging } = - license.getFeatures(); + const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures(); if (!allowRbac) { return { auditLoggingEnabled: false, @@ -148,17 +139,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens }; } - const legacyAuditLoggingEnabled = allowLegacyAuditLogging && config.audit.enabled; - const ecsAuditLoggingEnabled = - allowAuditLogging && config.audit.enabled && config.audit.appender != null; - - let auditLoggingType: Usage['auditLoggingType']; - if (ecsAuditLoggingEnabled) { - auditLoggingType = 'ecs'; - } else if (legacyAuditLoggingEnabled) { - auditLoggingType = 'legacy'; - } - + const auditLoggingEnabled = allowAuditLogging && config.audit.enabled; const loginSelectorEnabled = config.authc.selector.enabled; const authProviderCount = config.authc.sortedProviders.length; const enabledAuthProviders = [ @@ -183,8 +164,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens const sessionCleanupInMinutes = config.session.cleanupInterval?.asMinutes() ?? 0; return { - auditLoggingEnabled: legacyAuditLoggingEnabled || ecsAuditLoggingEnabled, - auditLoggingType, + auditLoggingEnabled, loginSelectorEnabled, accessAgreementEnabled, authProviderCount, diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index b3ca5f17634d545..2786cab4fe9633f 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -6930,12 +6930,6 @@ "description": "Indicates if audit logging is both enabled and supported by the current license." } }, - "auditLoggingType": { - "type": "keyword", - "_meta": { - "description": "If auditLoggingEnabled is true, indicates what type is enabled (ECS or legacy)." - } - }, "loginSelectorEnabled": { "type": "boolean", "_meta": {