Skip to content

Commit

Permalink
Merge pull request aquasecurity#1278 from mehakseedat63/SAAS-5567
Browse files Browse the repository at this point in the history
SAAS-5567: OCI Boot Volume Encryption Plugin
  • Loading branch information
AkhtarAmir authored Jun 26, 2022
2 parents 5131a5b + 283eabc commit 713f047
Show file tree
Hide file tree
Showing 3 changed files with 285 additions and 0 deletions.
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ module.exports = {
'bootVolumeRestorable' : require(__dirname + '/plugins/oracle/compute/bootVolumeRestorable.js'),
'bootVolumeBackupEnabled' : require(__dirname + '/plugins/oracle/compute/bootVolumeBackupEnabled.js'),
'instancePolicyProtection' : require(__dirname + '/plugins/oracle/compute/instancePolicyProtection.js'),
'bootVolumeCMKEncryption' : require(__dirname + '/plugins/oracle/compute/bootVolumeCMKEncryption.js'),
'legacyEndpointDisabled' : require(__dirname + '/plugins/oracle/compute/legacyEndpointDisabled.js'),

'usersMfaEnabled' : require(__dirname + '/plugins/oracle/identity/usersMfaEnabled.js'),
Expand Down
95 changes: 95 additions & 0 deletions plugins/oracle/compute/bootVolumeCMKEncryption.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
var async = require('async');
var helpers = require('../../../helpers/oracle/');

module.exports = {
title: 'Boot Volume CMK Encryption',
category: 'Block Storage',
domain: 'Storage',
description: 'Ensures that boot volumes have encryption enabled using desired protection level.',
more_info: 'By default, boot volumes are encrypted using an Oracle-managed master encryption key. To have better control over the encryption process, you can use Customer-Managed Keys (CMKs).',
recommended_action: 'Ensure all boot volumes have desired encryption level.',
link: 'https://docs.oracle.com/en-us/iaas/Content/Security/Reference/blockstorage_security.htm#data-encryption',
apis: ['vault:list', 'keys:list', 'bootVolume:list'],
settings: {
volume_encryption_level: {
name: 'Boot Volume Encryption Level',
description: 'Desired protection level for boot volumes. default: oracle-managed, cloudcmek: customer managed encryption keys, ' +
'cloudhsm: customer managed HSM encryption key',
regex: '^(default|cloudcmek|cloudhsm)$',
default: 'cloudcmek'
}
},

run: function(cache, settings, callback) {
var results = [];
var source = {};
var regions = helpers.regions(settings.govcloud);
var keysObj = {};

let desiredEncryptionLevelStr = settings.volume_encryption_level || this.settings.volume_encryption_level.default;
var desiredEncryptionLevel = helpers.PROTECTION_LEVELS.indexOf(desiredEncryptionLevelStr);

async.series([
function(cb) {
async.each(regions.keys, function(region, rcb) {
let keys = helpers.addSource(
cache, source, ['keys', 'list', region]);
if (keys && keys.data && keys.data.length) helpers.listToObj(keysObj, keys.data, 'id');
rcb();
}, function() {
cb();
});
},
function(cb) {
async.each(regions.bootVolume, function(region, rcb) {

if (helpers.checkRegionSubscription(cache, source, results, region)) {

var bootVolumes = helpers.addSource(cache, source,
['bootVolume', 'list', region]);

if (!bootVolumes) return rcb();

if (bootVolumes.err || !bootVolumes.data) {
helpers.addResult(results, 3,
'Unable to query for boot volumes: ' + helpers.addError(bootVolumes), region);
return rcb();
}

if (!bootVolumes.data.length) {
helpers.addResult(results, 0, 'No boot volumes found', region);
return rcb();
}

bootVolumes.data.forEach(bootVolume => {
if (bootVolume.lifecycleState && bootVolume.lifecycleState === 'TERMINATED') return;

let currentEncryptionLevel = 1; //default

if (bootVolume.kmsKeyId) {
currentEncryptionLevel = helpers.getProtectionLevel(keysObj[bootVolume.kmsKeyId], helpers.PROTECTION_LEVELS);
}

let currentEncryptionLevelStr = helpers.PROTECTION_LEVELS[currentEncryptionLevel];

if (currentEncryptionLevel >= desiredEncryptionLevel) {
helpers.addResult(results, 0,
`Boot volume (${bootVolume.displayName}) has encryption level ${currentEncryptionLevelStr} which is greater than or equal to ${desiredEncryptionLevelStr}`, region, bootVolume.id);
} else {
helpers.addResult(results, 2,
`Boot volume (${bootVolume.displayName}) has encryption level ${currentEncryptionLevelStr} which is less than ${desiredEncryptionLevelStr}`, region, bootVolume.id);
}
});
}

rcb();
}, function() {
cb();
});
}
], function() {
// Global checking goes here
callback(null, results, source);
});
}
};
189 changes: 189 additions & 0 deletions plugins/oracle/compute/bootVolumeCMKEncryption.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
var expect = require('chai').expect;
var plugin = require('./bootVolumeCMKEncryption');

const bootVolumes = [
{
"compartmentId": "ocid1.tenancy.oc1.aaaaaa.111111",
"definedTags": {},
"displayName": "vol-2",
"freeformTags": {},
"systemTags": {},
"id": "ocid1.volume.oc1.aaaaaa.1111111",
"isHydrated": true,
"kmsKeyId": null,
"lifecycleState": "AVAILABLE",
"performanceTier": null,
"vpusPerGB": null,
"sizeInGBs": 1024,
"sizeInMBs": 1048576,
"sourceDetails": null,
"timeCreated": "2019-08-29T21:46:01.836Z",
"volumeGroupId": null
},
{
"compartmentId": "ocid1.tenancy.oc1.aaaaaa.111111",
"definedTags": {},
"displayName": "vol-2",
"freeformTags": {},
"systemTags": {},
"id": "ocid1.volume.oc1.aaaaaa.1111111",
"isHydrated": true,
"lifecycleState": "AVAILABLE",
"performanceTier": null,
"vpusPerGB": null,
"sizeInGBs": 1024,
"sizeInMBs": 1048576,
"sourceDetails": null,
"timeCreated": "2019-08-29T21:46:01.836Z",
"volumeGroupId": null,
"kmsKeyId": 'key-1'
}
];

const createCache = (err, data) => {
return {
regionSubscription: {
"list": {
"us-ashburn-1": {
"data": [
{
"regionKey": "IAD",
"regionName": "us-ashburn-1",
"status": "READY",
"isHomeRegion": true
},
{
"regionKey": "LHR",
"regionName": "uk-london-1",
"status": "READY",
"isHomeRegion": false
},
{
"regionKey": "PHX",
"regionName": "us-phoenix-1",
"status": "READY",
"isHomeRegion": false
}
]
}
}
},
bootVolume: {
list: {
'us-ashburn-1': {
err: err,
data: data
}
}
},
vault: {
list: {
'us-ashburn-1': {
data: [
{
"compartmentId": "compartment-1",
"displayName": "vault-1",
"freeformTags": {},
"id": "vault-1",
"lifecycleState": "ACTIVE",
},
]
}
}
},
keys: {
list: {
'us-ashburn-1': {
data: [
{
"compartmentId": "compartment-1",
"definedTags": {},
"displayName": "key-1",
"freeformTags": {},
"id": "key-1",
"lifecycleState": "ENABLED",
"timeCreated": "2022-04-30T19:49:12.841Z",
"vaultId": "vault-1",
"protectionMode": "SOFTWARE",
"algorithm": "AES"
}
],

}
}
}
}
};

describe('bootVolumeCMKEncryption', function () {
describe('run', function () {
it('should give unknown result if a boot volume error occurs', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0)
expect(results[0].status).to.equal(3)
expect(results[0].message).to.include('Unable to query for boot volumes')
expect(results[0].region).to.equal('us-ashburn-1')
done()
};

const cache = createCache(
['error'],
null
);

plugin.run(cache, {}, callback);
})

it('should give passing result if no boot volumes are found', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0)
expect(results[0].status).to.equal(0)
expect(results[0].message).to.include('No boot volumes found')
expect(results[0].region).to.equal('us-ashburn-1')
done()
};

const cache = createCache(
null,
[]
);

plugin.run(cache, {}, callback);
})


it('should give failing result if boot volume does not have desired encryption level', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0)
expect(results[0].status).to.equal(2)
expect(results[0].message).to.include('which is less')
expect(results[0].region).to.equal('us-ashburn-1')
done()
};

const cache = createCache(
null,
[bootVolumes[0]]
);

plugin.run(cache, {}, callback);
})

it('should give passing result if boot volume has desired encryption level', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0)
expect(results[0].status).to.equal(0)
expect(results[0].message).to.include('which is greater than or equal to')
expect(results[0].region).to.equal('us-ashburn-1')
done()
};

const cache = createCache(
null,
[bootVolumes[1]]
);

plugin.run(cache, {}, callback);
});
});
});

0 comments on commit 713f047

Please sign in to comment.