Skip to content

Commit

Permalink
Require gold license for ECS audit logging (#85537)
Browse files Browse the repository at this point in the history
* Require gold license for ECS audit logging

* Fix unit test

* Add suggestions from code review
  • Loading branch information
thomheymann authored Dec 10, 2020
1 parent a34cd20 commit 051bbf0
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 32 deletions.
6 changes: 6 additions & 0 deletions x-pack/plugins/security/common/licensing/license_features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ 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.
*/
Expand Down
43 changes: 26 additions & 17 deletions x-pack/plugins/security/common/licensing/license_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('license features', function () {
allowRbac: false,
allowSubFeaturePrivileges: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
});
});

Expand All @@ -48,6 +49,7 @@ describe('license features', function () {
allowRbac: false,
allowSubFeaturePrivileges: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
});
});

Expand All @@ -69,6 +71,7 @@ describe('license features', function () {
Object {
"allowAccessAgreement": false,
"allowAuditLogging": false,
"allowLegacyAuditLogging": false,
"allowLogin": false,
"allowRbac": false,
"allowRoleDocumentLevelSecurity": false,
Expand All @@ -90,6 +93,7 @@ describe('license features', function () {
Object {
"allowAccessAgreement": true,
"allowAuditLogging": true,
"allowLegacyAuditLogging": true,
"allowLogin": true,
"allowRbac": true,
"allowRoleDocumentLevelSecurity": true,
Expand Down Expand Up @@ -128,6 +132,7 @@ describe('license features', function () {
allowRbac: true,
allowSubFeaturePrivileges: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
});
expect(getFeatureSpy).toHaveBeenCalledTimes(1);
expect(getFeatureSpy).toHaveBeenCalledWith('security');
Expand All @@ -153,12 +158,13 @@ describe('license features', function () {
allowRbac: false,
allowSubFeaturePrivileges: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
});
});

it('should allow role mappings, access agreement and sub-feature privileges, but not DLS/FLS if license = gold', () => {
it('should allow all basic features for standard license', () => {
const mockRawLicense = licenseMock.createLicense({
license: { mode: 'gold', type: 'gold' },
license: { mode: 'standard', type: 'standard' },
features: { security: { isEnabled: true, isAvailable: true } },
});

Expand All @@ -170,19 +176,20 @@ describe('license features', function () {
showLogin: true,
allowLogin: true,
showLinks: true,
showRoleMappingsManagement: true,
allowAccessAgreement: true,
showRoleMappingsManagement: false,
allowAccessAgreement: false,
allowRoleDocumentLevelSecurity: false,
allowRoleFieldLevelSecurity: false,
allowRbac: true,
allowSubFeaturePrivileges: true,
allowAuditLogging: true,
allowSubFeaturePrivileges: false,
allowAuditLogging: false,
allowLegacyAuditLogging: true,
});
});

it('should allow to login, allow RBAC, role mappings, access agreement, sub-feature privileges, and DLS if license >= platinum', () => {
it('should allow role mappings, access agreement, sub-feature privileges and audit logging, but not DLS/FLS if license = gold', () => {
const mockRawLicense = licenseMock.createLicense({
license: { mode: 'platinum', type: 'platinum' },
license: { mode: 'gold', type: 'gold' },
features: { security: { isEnabled: true, isAvailable: true } },
});

Expand All @@ -196,17 +203,18 @@ describe('license features', function () {
showLinks: true,
showRoleMappingsManagement: true,
allowAccessAgreement: true,
allowRoleDocumentLevelSecurity: true,
allowRoleFieldLevelSecurity: true,
allowRoleDocumentLevelSecurity: false,
allowRoleFieldLevelSecurity: false,
allowRbac: true,
allowSubFeaturePrivileges: true,
allowAuditLogging: true,
allowLegacyAuditLogging: true,
});
});

it('should allow all basic features + audit logging for standard license', () => {
it('should allow to login, allow RBAC, role mappings, access agreement, sub-feature privileges, and DLS if license >= platinum', () => {
const mockRawLicense = licenseMock.createLicense({
license: { mode: 'standard', type: 'standard' },
license: { mode: 'platinum', type: 'platinum' },
features: { security: { isEnabled: true, isAvailable: true } },
});

Expand All @@ -218,13 +226,14 @@ describe('license features', function () {
showLogin: true,
allowLogin: true,
showLinks: true,
showRoleMappingsManagement: false,
allowAccessAgreement: false,
allowRoleDocumentLevelSecurity: false,
allowRoleFieldLevelSecurity: false,
showRoleMappingsManagement: true,
allowAccessAgreement: true,
allowRoleDocumentLevelSecurity: true,
allowRoleFieldLevelSecurity: true,
allowRbac: true,
allowSubFeaturePrivileges: false,
allowSubFeaturePrivileges: true,
allowAuditLogging: true,
allowLegacyAuditLogging: true,
});
});
});
5 changes: 4 additions & 1 deletion x-pack/plugins/security/common/licensing/license_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export class SecurityLicenseService {
showRoleMappingsManagement: false,
allowAccessAgreement: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
allowRoleDocumentLevelSecurity: false,
allowRoleFieldLevelSecurity: false,
allowRbac: false,
Expand All @@ -98,6 +99,7 @@ export class SecurityLicenseService {
showRoleMappingsManagement: false,
allowAccessAgreement: false,
allowAuditLogging: false,
allowLegacyAuditLogging: false,
allowRoleDocumentLevelSecurity: false,
allowRoleFieldLevelSecurity: false,
allowRbac: false,
Expand All @@ -114,7 +116,8 @@ export class SecurityLicenseService {
showLinks: true,
showRoleMappingsManagement: isLicenseGoldOrBetter,
allowAccessAgreement: isLicenseGoldOrBetter,
allowAuditLogging: isLicenseStandardOrBetter,
allowAuditLogging: isLicenseGoldOrBetter,
allowLegacyAuditLogging: isLicenseStandardOrBetter,
allowSubFeaturePrivileges: isLicenseGoldOrBetter,
// Only platinum and trial licenses are compliant with field- and document-level security.
allowRoleDocumentLevelSecurity: isLicensePlatinumOrBetter,
Expand Down
12 changes: 6 additions & 6 deletions x-pack/plugins/security/server/audit/audit_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ describe('#getLogger', () => {

const licenseWithFeatures = licenseMock.create();
licenseWithFeatures.features$ = new BehaviorSubject({
allowAuditLogging: true,
allowLegacyAuditLogging: true,
} as SecurityLicenseFeatures).asObservable();

const auditService = new AuditService(logger).setup({
Expand Down Expand Up @@ -388,7 +388,7 @@ describe('#getLogger', () => {

const licenseWithFeatures = licenseMock.create();
licenseWithFeatures.features$ = new BehaviorSubject({
allowAuditLogging: true,
allowLegacyAuditLogging: true,
} as SecurityLicenseFeatures).asObservable();

const auditService = new AuditService(logger).setup({
Expand Down Expand Up @@ -426,7 +426,7 @@ describe('#getLogger', () => {

const licenseWithFeatures = licenseMock.create();
licenseWithFeatures.features$ = new BehaviorSubject({
allowAuditLogging: false,
allowLegacyAuditLogging: false,
} as SecurityLicenseFeatures).asObservable();

const auditService = new AuditService(logger).setup({
Expand All @@ -452,7 +452,7 @@ describe('#getLogger', () => {

const licenseWithFeatures = licenseMock.create();
licenseWithFeatures.features$ = new BehaviorSubject({
allowAuditLogging: true,
allowLegacyAuditLogging: true,
} as SecurityLicenseFeatures).asObservable();

const auditService = new AuditService(logger).setup({
Expand Down Expand Up @@ -481,7 +481,7 @@ describe('#getLogger', () => {
const licenseWithFeatures = licenseMock.create();

const features$ = new BehaviorSubject({
allowAuditLogging: false,
allowLegacyAuditLogging: false,
} as SecurityLicenseFeatures);

licenseWithFeatures.features$ = features$.asObservable();
Expand All @@ -505,7 +505,7 @@ describe('#getLogger', () => {

// perform license upgrade
features$.next({
allowAuditLogging: true,
allowLegacyAuditLogging: true,
} as SecurityLicenseFeatures);

auditLogger.log(eventType, message);
Expand Down
12 changes: 7 additions & 5 deletions x-pack/plugins/security/server/audit/audit_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class AuditService {
/**
* @deprecated
*/
private allowAuditLogging = false;
private allowLegacyAuditLogging = false;

private ecsLogger: Logger;

Expand All @@ -87,9 +87,11 @@ export class AuditService {
getSpaceId,
}: AuditServiceSetupParams): AuditServiceSetup {
if (config.enabled && !config.appender) {
this.licenseFeaturesSubscription = license.features$.subscribe(({ allowAuditLogging }) => {
this.allowAuditLogging = allowAuditLogging;
});
this.licenseFeaturesSubscription = license.features$.subscribe(
({ allowLegacyAuditLogging }) => {
this.allowLegacyAuditLogging = allowLegacyAuditLogging;
}
);
}

// Configure logging during setup and when license changes
Expand Down Expand Up @@ -169,7 +171,7 @@ export class AuditService {
const getLogger = (id?: string): LegacyAuditLogger => {
return {
log: (eventType: string, message: string, data?: Record<string, any>) => {
if (!this.allowAuditLogging) {
if (!this.allowLegacyAuditLogging) {
return;
}

Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/security/server/routes/views/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ describe('Login view routes', () => {
showRoleMappingsManagement: true,
allowSubFeaturePrivileges: true,
allowAuditLogging: true,
allowLegacyAuditLogging: true,
showLogin: true,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('Security UsageCollector', () => {
license.getFeatures.mockReturnValue({
allowAccessAgreement,
allowAuditLogging,
allowLegacyAuditLogging: allowAuditLogging,
allowRbac,
} as SecurityLicenseFeatures);
return license;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
},
},
fetch: () => {
const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures();
const {
allowRbac,
allowAccessAgreement,
allowAuditLogging,
allowLegacyAuditLogging,
} = license.getFeatures();
if (!allowRbac) {
return {
auditLoggingEnabled: false,
Expand All @@ -87,7 +92,10 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
};
}

const auditLoggingEnabled = allowAuditLogging && config.audit.enabled;
const legacyAuditLoggingEnabled = allowLegacyAuditLogging && config.audit.enabled;
const auditLoggingEnabled =
allowAuditLogging && config.audit.enabled && config.audit.appender != null;

const loginSelectorEnabled = config.authc.selector.enabled;
const authProviderCount = config.authc.sortedProviders.length;
const enabledAuthProviders = [
Expand All @@ -107,7 +115,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
);

return {
auditLoggingEnabled,
auditLoggingEnabled: legacyAuditLoggingEnabled || auditLoggingEnabled,
loginSelectorEnabled,
accessAgreementEnabled,
authProviderCount,
Expand Down

0 comments on commit 051bbf0

Please sign in to comment.