Skip to content

Commit

Permalink
Finalize removal of legacy audit logger (elastic#116282)
Browse files Browse the repository at this point in the history
  • Loading branch information
watson authored and kibanamachine committed Oct 30, 2021
1 parent c397556 commit c65acb1
Show file tree
Hide file tree
Showing 60 changed files with 175 additions and 2,600 deletions.
2 changes: 1 addition & 1 deletion docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ adds dynamic actions to every embeddables state, in order to support drilldowns.
|{kib-repo}blob/{branch}/x-pack/plugins/encrypted_saved_objects/README.md[encryptedSavedObjects]
|The purpose of this plugin is to provide a way to encrypt/decrypt attributes on the custom Saved Objects that works with
security and spaces filtering as well as performing audit logging.
security and spaces filtering.
|{kib-repo}blob/{branch}/x-pack/plugins/enterprise_search/README.md[enterpriseSearch]
Expand Down
42 changes: 11 additions & 31 deletions docs/settings/security-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -324,52 +324,32 @@ For more details and a reference of audit events, refer to <<xpack-security-audi
[cols="2*<"]
|======
| `xpack.security.audit.enabled` {ess-icon}
| Set to `true` _and_ configure an appender with `xpack.security.audit.appender` to enable ECS audit logging`. *Default:* `false`
| Set to `true` to enable audit logging`. *Default:* `false`

2+a| For example:
[source,yaml]
----------------------------------------
xpack.security.audit.enabled: true
xpack.security.audit.appender:
xpack.security.audit.appender: <1>
type: rolling-file
fileName: ./audit.log
fileName: ./data/audit.log
policy:
type: time-interval
interval: 24h <1>
interval: 24h <2>
strategy:
type: numeric
max: 10 <2>
max: 10 <3>
layout:
type: json
----------------------------------------
<1> Rotates log files every 24 hours.
<2> Keeps maximum of 10 log files before deleting older ones.
<1> This appender is the default and will be used if no `appender.*` config options are specified.
<2> Rotates log files every 24 hours.
<3> Keeps maximum of 10 log files before deleting older ones.

[NOTE]
============
{ess} does not support custom log file policies. To enable audit logging on {ess} only specify:
[source,yaml]
----------------------------------------
xpack.security.audit.enabled: true
xpack.security.audit.appender.type: rolling-file
----------------------------------------
============

[NOTE]
============
deprecated:[7.15.0,"In 8.0 and later, the legacy audit logger will be removed, and this setting will enable the ECS audit logger with a default appender."] To enable the legacy audit logger only specify:
[source,yaml]
----------------------------------------
xpack.security.audit.enabled: true
----------------------------------------
============

| `xpack.security.audit.appender` {ess-icon}
| Optional. Specifies where audit logs should be written to and how they should be formatted.
| `xpack.security.audit.appender`
| Optional. Specifies where audit logs should be written to and how they should be formatted. If no appender is specified, a default appender will be used (see above).

| `xpack.security.audit.appender.type` {ess-icon}
| `xpack.security.audit.appender.type`
| Required. Specifies where audit logs should be written to. Allowed values are `console`, `file`, or `rolling-file`.

Refer to <<audit-logging-file-appender>> and <<audit-logging-rolling-file-appender>> for appender specific settings.
Expand Down
40 changes: 6 additions & 34 deletions docs/user/security/audit-logging.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,15 @@ model for authentication, data index authorization, and features that are driven
by cluster-wide privileges. For more information on enabling audit logging in
{es}, refer to {ref}/auditing.html[Auditing security events].

[IMPORTANT]
============================================================================
Kibana offers two audit logs: a **deprecated** legacy audit logger, and a new
ECS-compliant audit logger. We strongly advise using the <<xpack-security-ecs-audit-logging, ECS audit logger>>,
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
set `xpack.security.audit.enabled` to `true` in `kibana.yml`, and configure
set `xpack.security.audit.enabled` to `true` in `kibana.yml`, and optionally configure
an <<audit-logging-settings, appender>> 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 <<settings>>.
The <<xpack-security-ecs-audit-logging, ECS audit logger>> uses a separate logger and can be configured using
the options in <<audit-logging-settings>>.

==== 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 <<kibana-privileges>>
| `saved_objects_authorization_failure` | Logged when a user isn't authorized to access a saved
objects when using a role with <<kibana-privileges>>
|======

[[xpack-security-ecs-audit-logging]]
==== ECS audit events

[IMPORTANT]
============================================================================
The following events are only logged if the ECS audit logger is enabled.
For information on how to configure `xpack.security.audit.appender`, refer to
<<audit-logging-settings>>.
============================================================================
==== Audit events

Refer to the table of events that can be logged for auditing purposes.

Expand Down Expand Up @@ -81,6 +50,9 @@ Refer to the corresponding {es} logs for potential write errors.
| `success` | User has logged in successfully.
| `failure` | Failed login attempt (e.g. due to invalid credentials).

| `access_agreement_acknowledged`
| N/A | User has acknowledged the access agreement.

3+a|
===== Category: database
====== Type: creation
Expand Down Expand Up @@ -255,7 +227,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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import { KibanaRequest } from 'kibana/server';
import { securityMock } from '../../../../plugins/security/server/mocks';
import { ActionsAuthorization } from './actions_authorization';
import { actionsAuthorizationAuditLoggerMock } from './audit_logger.mock';
import { ActionsAuthorizationAuditLogger, AuthorizationResult } from './audit_logger';
import {
ACTION_SAVED_OBJECT_TYPE,
ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE,
Expand All @@ -19,9 +17,6 @@ import { AuthorizationMode } from './get_authorization_mode_by_source';

const request = {} as KibanaRequest;

const auditLogger = actionsAuthorizationAuditLoggerMock.create();
const realAuditLogger = new ActionsAuthorizationAuditLogger();

const mockAuthorizationAction = (type: string, operation: string) => `${type}/${operation}`;
function mockSecurity() {
const security = securityMock.createSetup();
Expand All @@ -39,19 +34,12 @@ function mockSecurity() {

beforeEach(() => {
jest.resetAllMocks();
auditLogger.actionsAuthorizationFailure.mockImplementation((username, ...args) =>
realAuditLogger.getAuthorizationMessage(AuthorizationResult.Unauthorized, ...args)
);
auditLogger.actionsAuthorizationSuccess.mockImplementation((username, ...args) =>
realAuditLogger.getAuthorizationMessage(AuthorizationResult.Authorized, ...args)
);
});

describe('ensureAuthorized', () => {
test('is a no-op when there is no authorization api', async () => {
const actionsAuthorization = new ActionsAuthorization({
request,
auditLogger,
});

await actionsAuthorization.ensureAuthorized('create', 'myType');
Expand All @@ -63,7 +51,6 @@ describe('ensureAuthorized', () => {
const actionsAuthorization = new ActionsAuthorization({
request,
authorization,
auditLogger,
});

await actionsAuthorization.ensureAuthorized('create', 'myType');
Expand All @@ -78,7 +65,6 @@ describe('ensureAuthorized', () => {
const actionsAuthorization = new ActionsAuthorization({
request,
authorization,
auditLogger,
});

checkPrivileges.mockResolvedValueOnce({
Expand All @@ -98,16 +84,6 @@ describe('ensureAuthorized', () => {
expect(checkPrivileges).toHaveBeenCalledWith({
kibana: mockAuthorizationAction('action', 'create'),
});

expect(auditLogger.actionsAuthorizationSuccess).toHaveBeenCalledTimes(1);
expect(auditLogger.actionsAuthorizationFailure).not.toHaveBeenCalled();
expect(auditLogger.actionsAuthorizationSuccess.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"some-user",
"create",
"myType",
]
`);
});

test('ensures the user has privileges to execute an Actions Saved Object type', async () => {
Expand All @@ -119,7 +95,6 @@ describe('ensureAuthorized', () => {
const actionsAuthorization = new ActionsAuthorization({
request,
authorization,
auditLogger,
});

checkPrivileges.mockResolvedValueOnce({
Expand Down Expand Up @@ -149,16 +124,6 @@ describe('ensureAuthorized', () => {
mockAuthorizationAction(ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, 'create'),
],
});

expect(auditLogger.actionsAuthorizationSuccess).toHaveBeenCalledTimes(1);
expect(auditLogger.actionsAuthorizationFailure).not.toHaveBeenCalled();
expect(auditLogger.actionsAuthorizationSuccess.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"some-user",
"execute",
"myType",
]
`);
});

test('throws if user lacks the required privieleges', async () => {
Expand All @@ -170,7 +135,6 @@ describe('ensureAuthorized', () => {
const actionsAuthorization = new ActionsAuthorization({
request,
authorization,
auditLogger,
});

checkPrivileges.mockResolvedValueOnce({
Expand All @@ -191,16 +155,6 @@ describe('ensureAuthorized', () => {
await expect(
actionsAuthorization.ensureAuthorized('create', 'myType')
).rejects.toThrowErrorMatchingInlineSnapshot(`"Unauthorized to create a \\"myType\\" action"`);

expect(auditLogger.actionsAuthorizationSuccess).not.toHaveBeenCalled();
expect(auditLogger.actionsAuthorizationFailure).toHaveBeenCalledTimes(1);
expect(auditLogger.actionsAuthorizationFailure.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"some-user",
"create",
"myType",
]
`);
});

test('exempts users from requiring privileges to execute actions when authorizationMode is Legacy', async () => {
Expand All @@ -213,7 +167,6 @@ describe('ensureAuthorized', () => {
request,
authorization,
authentication,
auditLogger,
authorizationMode: AuthorizationMode.Legacy,
});

Expand All @@ -225,15 +178,5 @@ describe('ensureAuthorized', () => {

expect(authorization.actions.savedObject.get).not.toHaveBeenCalled();
expect(checkPrivileges).not.toHaveBeenCalled();

expect(auditLogger.actionsAuthorizationSuccess).toHaveBeenCalledTimes(1);
expect(auditLogger.actionsAuthorizationFailure).not.toHaveBeenCalled();
expect(auditLogger.actionsAuthorizationSuccess.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"some-user",
"execute",
"myType",
]
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import Boom from '@hapi/boom';
import { KibanaRequest } from 'src/core/server';
import { SecurityPluginSetup } from '../../../security/server';
import { ActionsAuthorizationAuditLogger } from './audit_logger';
import {
ACTION_SAVED_OBJECT_TYPE,
ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE,
Expand All @@ -17,7 +16,6 @@ import { AuthorizationMode } from './get_authorization_mode_by_source';

export interface ConstructorOptions {
request: KibanaRequest;
auditLogger: ActionsAuthorizationAuditLogger;
authorization?: SecurityPluginSetup['authz'];
authentication?: SecurityPluginSetup['authc'];
// In order to support legacy Alerts which predate the introduction of the
Expand Down Expand Up @@ -46,44 +44,33 @@ const LEGACY_RBAC_EXEMPT_OPERATIONS = new Set(['get', 'execute']);
export class ActionsAuthorization {
private readonly request: KibanaRequest;
private readonly authorization?: SecurityPluginSetup['authz'];
private readonly authentication?: SecurityPluginSetup['authc'];
private readonly auditLogger: ActionsAuthorizationAuditLogger;
private readonly authorizationMode: AuthorizationMode;
constructor({
request,
authorization,
authentication,
auditLogger,
authorizationMode = AuthorizationMode.RBAC,
}: ConstructorOptions) {
this.request = request;
this.authorization = authorization;
this.authentication = authentication;
this.auditLogger = auditLogger;
this.authorizationMode = authorizationMode;
}

public async ensureAuthorized(operation: string, actionTypeId?: string) {
const { authorization } = this;
if (authorization?.mode?.useRbacForRequest(this.request)) {
if (this.isOperationExemptDueToLegacyRbac(operation)) {
this.auditLogger.actionsAuthorizationSuccess(
this.authentication?.getCurrentUser(this.request)?.username ?? '',
operation,
actionTypeId
);
} else {
if (!this.isOperationExemptDueToLegacyRbac(operation)) {
const checkPrivileges = authorization.checkPrivilegesDynamicallyWithRequest(this.request);
const { hasAllRequested, username } = await checkPrivileges({
const { hasAllRequested } = await checkPrivileges({
kibana: operationAlias[operation]
? operationAlias[operation](authorization)
: authorization.actions.savedObject.get(ACTION_SAVED_OBJECT_TYPE, operation),
});
if (hasAllRequested) {
this.auditLogger.actionsAuthorizationSuccess(username, operation, actionTypeId);
} else {
if (!hasAllRequested) {
throw Boom.forbidden(
this.auditLogger.actionsAuthorizationFailure(username, operation, actionTypeId)
`Unauthorized to ${operation} ${
actionTypeId ? `a "${actionTypeId}" action` : `actions`
}`
);
}
}
Expand Down
23 changes: 0 additions & 23 deletions x-pack/plugins/actions/server/authorization/audit_logger.mock.ts

This file was deleted.

Loading

0 comments on commit c65acb1

Please sign in to comment.