Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add audit events for spaces #86343

Merged
merged 2 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 37 additions & 21 deletions docs/user/security/audit-logging.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ authorization checks have passed, but before the response from {es} is received.
Refer to the corresponding {es} logs for potential write errors.
============================================================================


[cols="3*<"]
|======
3+a|
Expand Down Expand Up @@ -89,9 +88,12 @@ Refer to the corresponding {es} logs for potential write errors.
| `failure` | User is not authorized to create a connector.

.2+| `alert_create`
| `unknown` | User is creating an alert rule.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really part of this PR but decided to fix the docs for these since we went with "alert_" rather than "alert_rule_" in the end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We unfortunately can't backport this PR to 7.11, so we'll need another PR to update the 7.11 version of the docs for alerts

| `failure` | User is not authorized to create an alert rule.
| `unknown` | User is creating an alert.
| `failure` | User is not authorized to create an alert.

.2+| `space_create`
| `unknown` | User is creating a space.
| `failure` | User is not authorized to create a space.

3+a|
====== Type: change
Expand Down Expand Up @@ -121,28 +123,28 @@ Refer to the corresponding {es} logs for potential write errors.
| `failure` | User is not authorized to update a connector.

.2+| `alert_update`
| `unknown` | User is updating an alert rule.
| `failure` | User is not authorized to update an alert rule.
| `unknown` | User is updating an alert.
| `failure` | User is not authorized to update an alert.

.2+| `alert_update_api_key`
| `unknown` | User is updating the API key of an alert rule.
| `failure` | User is not authorized to update the API key of an alert rule.
| `unknown` | User is updating the API key of an alert.
| `failure` | User is not authorized to update the API key of an alert.

.2+| `alert_enable`
| `unknown` | User is enabling an alert rule.
| `failure` | User is not authorized to enable an alert rule.
| `unknown` | User is enabling an alert.
| `failure` | User is not authorized to enable an alert.

.2+| `alert_disable`
| `unknown` | User is disabling an alert rule.
| `failure` | User is not authorized to disable an alert rule.
| `unknown` | User is disabling an alert.
| `failure` | User is not authorized to disable an alert.

.2+| `alert_mute`
| `unknown` | User is muting an alert rule.
| `failure` | User is not authorized to mute an alert rule.
| `unknown` | User is muting an alert.
| `failure` | User is not authorized to mute an alert.

.2+| `alert_unmute`
| `unknown` | User is unmuting an alert rule.
| `failure` | User is not authorized to unmute an alert rule.
| `unknown` | User is unmuting an alert.
| `failure` | User is not authorized to unmute an alert.

.2+| `alert_instance_mute`
| `unknown` | User is muting an alert instance.
Expand All @@ -152,6 +154,9 @@ Refer to the corresponding {es} logs for potential write errors.
| `unknown` | User is unmuting an alert instance.
| `failure` | User is not authorized to unmute an alert instance.

.2+| `space_update`
| `unknown` | User is updating a space.
| `failure` | User is not authorized to update a space.

3+a|
====== Type: deletion
Expand All @@ -169,8 +174,12 @@ Refer to the corresponding {es} logs for potential write errors.
| `failure` | User is not authorized to delete a connector.

.2+| `alert_delete`
| `unknown` | User is deleting an alert rule.
| `failure` | User is not authorized to delete an alert rule.
| `unknown` | User is deleting an alert.
| `failure` | User is not authorized to delete an alert.

.2+| `space_delete`
| `unknown` | User is deleting a space.
| `failure` | User is not authorized to delete a space.

3+a|
====== Type: access
Expand All @@ -196,13 +205,20 @@ Refer to the corresponding {es} logs for potential write errors.
| `failure` | User is not authorized to search for connectors.

.2+| `alert_get`
| `success` | User has accessed an alert rule.
| `failure` | User is not authorized to access an alert rule.
| `success` | User has accessed an alert.
| `failure` | User is not authorized to access an alert.

.2+| `alert_find`
| `success` | User has accessed an alert rule as part of a search operation.
| `failure` | User is not authorized to search for alert rules.
| `success` | User has accessed an alert as part of a search operation.
| `failure` | User is not authorized to search for alerts.

.2+| `space_get`
| `success` | User has accessed a space.
| `failure` | User is not authorized to access a space.

.2+| `space_find`
| `success` | User has accessed a space as part of a search operation.
| `failure` | User is not authorized to search for spaces.

3+a|
===== Category: web
Expand Down
87 changes: 87 additions & 0 deletions x-pack/plugins/security/server/audit/audit_events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
savedObjectEvent,
userLoginEvent,
httpRequestEvent,
spaceAuditEvent,
SpaceAuditAction,
} from './audit_events';
import { AuthenticationResult } from '../authentication';
import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock';
Expand Down Expand Up @@ -325,3 +327,88 @@ describe('#httpRequestEvent', () => {
`);
});
});

describe('#spaceAuditEvent', () => {
test('creates event with `unknown` outcome', () => {
expect(
spaceAuditEvent({
action: SpaceAuditAction.CREATE,
outcome: EventOutcome.UNKNOWN,
savedObject: { type: 'space', id: 'SPACE_ID' },
})
).toMatchInlineSnapshot(`
Object {
"error": undefined,
"event": Object {
"action": "space_create",
"category": "database",
"outcome": "unknown",
"type": "creation",
},
"kibana": Object {
"saved_object": Object {
"id": "SPACE_ID",
"type": "space",
},
},
"message": "User is creating space [id=SPACE_ID]",
}
`);
});

test('creates event with `success` outcome', () => {
expect(
spaceAuditEvent({
action: SpaceAuditAction.CREATE,
savedObject: { type: 'space', id: 'SPACE_ID' },
})
).toMatchInlineSnapshot(`
Object {
"error": undefined,
"event": Object {
"action": "space_create",
"category": "database",
"outcome": "success",
"type": "creation",
},
"kibana": Object {
"saved_object": Object {
"id": "SPACE_ID",
"type": "space",
},
},
"message": "User has created space [id=SPACE_ID]",
}
`);
});

test('creates event with `failure` outcome', () => {
expect(
spaceAuditEvent({
action: SpaceAuditAction.CREATE,
savedObject: { type: 'space', id: 'SPACE_ID' },
error: new Error('ERROR_MESSAGE'),
})
).toMatchInlineSnapshot(`
Object {
"error": Object {
"code": "Error",
"message": "ERROR_MESSAGE",
},
"event": Object {
"action": "space_create",
"category": "database",
"outcome": "failure",
"type": "creation",
},
"kibana": Object {
"saved_object": Object {
"id": "SPACE_ID",
"type": "space",
},
},
"message": "Failed attempt to create space [id=SPACE_ID]",
}
`);
});
});
74 changes: 69 additions & 5 deletions x-pack/plugins/security/server/audit/audit_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface AuditEvent {
* Human readable message describing action, outcome and user.
*
* @example
* User [jdoe] logged in using basic provider [name=basic1]
* Failed attempt to login using basic provider [name=basic1]
*/
message: string;
event: {
Expand Down Expand Up @@ -208,7 +208,7 @@ export enum SavedObjectAction {

type VerbsTuple = [string, string, string];

const eventVerbs: Record<SavedObjectAction, VerbsTuple> = {
const savedObjectAuditVerbs: Record<SavedObjectAction, VerbsTuple> = {
saved_object_create: ['create', 'creating', 'created'],
saved_object_get: ['access', 'accessing', 'accessed'],
saved_object_update: ['update', 'updating', 'updated'],
Expand All @@ -223,7 +223,7 @@ const eventVerbs: Record<SavedObjectAction, VerbsTuple> = {
],
};

const eventTypes: Record<SavedObjectAction, EventType> = {
const savedObjectAuditTypes: Record<SavedObjectAction, EventType> = {
saved_object_create: EventType.CREATION,
saved_object_get: EventType.ACCESS,
saved_object_update: EventType.CHANGE,
Expand Down Expand Up @@ -252,13 +252,13 @@ export function savedObjectEvent({
error,
}: SavedObjectEventParams): AuditEvent | undefined {
const doc = savedObject ? `${savedObject.type} [id=${savedObject.id}]` : 'saved objects';
const [present, progressive, past] = eventVerbs[action];
const [present, progressive, past] = savedObjectAuditVerbs[action];
const message = error
? `Failed attempt to ${present} ${doc}`
: outcome === EventOutcome.UNKNOWN
? `User is ${progressive} ${doc}`
: `User has ${past} ${doc}`;
const type = eventTypes[action];
const type = savedObjectAuditTypes[action];

if (
type === EventType.ACCESS &&
Expand Down Expand Up @@ -287,3 +287,67 @@ export function savedObjectEvent({
},
};
}

export enum SpaceAuditAction {
CREATE = 'space_create',
GET = 'space_get',
UPDATE = 'space_update',
DELETE = 'space_delete',
FIND = 'space_find',
}

const spaceAuditVerbs: Record<SpaceAuditAction, VerbsTuple> = {
space_create: ['create', 'creating', 'created'],
space_get: ['access', 'accessing', 'accessed'],
space_update: ['update', 'updating', 'updated'],
space_delete: ['delete', 'deleting', 'deleted'],
space_find: ['access', 'accessing', 'accessed'],
};

const spaceAuditTypes: Record<SpaceAuditAction, EventType> = {
space_create: EventType.CREATION,
space_get: EventType.ACCESS,
space_update: EventType.CHANGE,
space_delete: EventType.DELETION,
space_find: EventType.ACCESS,
};

export interface SpacesAuditEventParams {
action: SpaceAuditAction;
outcome?: EventOutcome;
savedObject?: NonNullable<AuditEvent['kibana']>['saved_object'];
error?: Error;
}

export function spaceAuditEvent({
action,
savedObject,
outcome,
error,
}: SpacesAuditEventParams): AuditEvent {
const doc = savedObject ? `space [id=${savedObject.id}]` : 'spaces';
const [present, progressive, past] = spaceAuditVerbs[action];
const message = error
? `Failed attempt to ${present} ${doc}`
: outcome === EventOutcome.UNKNOWN
? `User is ${progressive} ${doc}`
: `User has ${past} ${doc}`;
const type = spaceAuditTypes[action];

return {
message,
event: {
action,
category: EventCategory.DATABASE,
type,
outcome: outcome ?? (error ? EventOutcome.FAILURE : EventOutcome.SUCCESS),
},
kibana: {
saved_object: savedObject,
},
error: error && {
code: error.name,
message: error.message,
},
};
}
2 changes: 2 additions & 0 deletions x-pack/plugins/security/server/audit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export {
userLoginEvent,
httpRequestEvent,
savedObjectEvent,
spaceAuditEvent,
SavedObjectAction,
SpaceAuditAction,
} from './audit_events';
export { SecurityAuditLogger } from './security_audit_logger';
Loading