Skip to content

Commit c797335

Browse files
authored
Merge pull request aquasecurity#1325 from mehakseedat63/SAAS-7051
SAAS-7051: OCI - Key Rotation Plugin
2 parents 51b258a + ca70d28 commit c797335

7 files changed

Lines changed: 386 additions & 3 deletions

File tree

‎collectors/oracle/collector.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,26 @@ var finalcalls = {
490490
restVersion: '',
491491
}
492492
},
493+
keys: {
494+
get: {
495+
api: 'kms',
496+
reliesOnService: ['keys'],
497+
reliesOnCall: ['list'],
498+
filterKey: ['compartmentId', 'id'],
499+
filterValue: ['compartmentId', 'id'],
500+
restVersion: '/20180608'
501+
}
502+
},
503+
keyVersions: {
504+
list: {
505+
api: 'kms',
506+
reliesOnService: ['keys'],
507+
reliesOnCall: ['list'],
508+
filterKey: ['compartmentId', 'id'],
509+
filterValue: ['compartmentId', 'id'],
510+
restVersion: '/20180608'
511+
}
512+
},
493513
exprt: {
494514
get: {
495515
api: 'fileStorage',

‎exports.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ module.exports = {
921921
'okePrivateEndpoint' : require(__dirname + '/plugins/oracle/oke/okePrivateEndpoint.js'),
922922
'okeSecretsEncrypted' : require(__dirname + '/plugins/oracle/oke/okeSecretsEncrypted.js'),
923923
'okeSecurityGroups' : require(__dirname + '/plugins/oracle/oke/okeSecurityGroups.js'),
924+
925+
'keyRotation' : require(__dirname + '/plugins/oracle/vaults/keyRotation.js'),
926+
924927
},
925928
google: {
926929
'excessiveFirewallRules' : require(__dirname + '/plugins/google/vpcnetwork/excessiveFirewallRules.js'),

‎helpers/oracle/regions.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,6 @@ module.exports = {
8686
customerSecretKey: ['default'],
8787
vault: regions,
8888
keys: regions,
89+
keyVersions: regions,
8990
cluster: regions
9091
};

‎other_modules/oci/index.js‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ module.exports = function(api, service, key, OracleConfig, parameters, callback)
77
!services[api][service][key]) return callback({code: 'Invalid API'});
88

99
var localService = services[api][service][key];
10-
10+
1111
//replacing endpoint with managementRndpoint value from vault for keys api
1212
if (api === 'kms' && localService.path === 'keys') {
13-
localService.endpoint = parameters.managementEndpoint.replace('https://', '');
14-
delete parameters['managementEndpoint'];
13+
if (!localService.secondaryPath && key === 'list') {
14+
localService.endpoint = parameters.managementEndpoint.replace('https://', '');
15+
delete parameters['managementEndpoint'];
16+
} else if (key === 'get' || (localService.secondaryPath && localService.secondaryPath === 'keyVersions')) {
17+
localService.endpoint = localService.endpoint.replace(/^[^\s-]*(?=-)/, parameters.id.split('.')[4]);
18+
}
1519
}
1620

1721
var suffix = '';

‎other_modules/oci/services.json‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,27 @@
487487
"method": "GET",
488488
"path": "keys",
489489
"endpoint": "{{managementEndpoint}}"
490+
},
491+
"get": {
492+
"allowedQueryStrings": [
493+
"compartmentId", "page", "limit"
494+
],
495+
"encodedGet": "id",
496+
"method": "GET",
497+
"path": "keys",
498+
"endpoint": "-management.kms.{{region}}.oraclecloud.com"
499+
}
500+
},
501+
"keyVersions": {
502+
"list": {
503+
"allowedQueryStrings": [
504+
"compartmentId", "page", "limit"
505+
],
506+
"encodedGet": "id",
507+
"method": "GET",
508+
"path": "keys",
509+
"secondaryPath": "keyVersions",
510+
"endpoint": "-management.kms.{{region}}.oraclecloud.com"
490511
}
491512
}
492513
},
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
var async = require('async');
2+
var helpers = require('../../../helpers/oracle');
3+
4+
module.exports = {
5+
title: 'Key Rotation',
6+
category: 'Vaults',
7+
domain: 'Application Integration',
8+
description: 'Ensure that your OCI Vault Keys are periodically rotated.',
9+
more_info: 'Rotating keys periodically limits the data encrypted under one key version. Key rotation thereby reduces the risk in case a key is ever compromised.',
10+
link: 'https://docs.oracle.com/en-us/iaas/Content/KeyManagement/Tasks/managingkeys.htm',
11+
recommended_action: 'Ensure that all your cryptographic keys are regenerated (rotated) after a specific period.',
12+
apis: ['vault:list', 'keys:list', 'keys:get', 'keyVersions:list'],
13+
settings: {
14+
key_rotation_interval: {
15+
name: 'Key Rotation Interval',
16+
description: 'Return a failing result when keys exceed this number of days without being rotated',
17+
regex: '^[1-9]{1}[0-9]{0,3}$',
18+
default: '365'
19+
}
20+
},
21+
22+
run: function(cache, settings, callback) {
23+
var results = [];
24+
var source = {};
25+
var regions = helpers.regions(settings.govcloud);
26+
27+
var keyRotationInterval = parseInt(settings.key_rotation_interval || this.settings.key_rotation_interval.default);
28+
29+
async.each(regions.keys, function(region, rcb){
30+
31+
if (helpers.checkRegionSubscription(cache, source, results, region)) {
32+
33+
var keys = helpers.addSource(cache, source,
34+
['keys', 'get', region]);
35+
36+
if (!keys) return rcb();
37+
38+
if (keys.err || !keys.data) {
39+
helpers.addResult(results, 3,
40+
'Unable to query for cryptographic keys: ' + helpers.addError(keys), region);
41+
return rcb();
42+
}
43+
44+
if (!keys.data.length) {
45+
helpers.addResult(results, 0, 'No cryptographic keys found', region);
46+
return rcb();
47+
}
48+
49+
var keyVersions = helpers.addSource(cache, source,
50+
['keyVersions', 'list', region]);
51+
52+
if (!keyVersions) return rcb();
53+
54+
if (keyVersions.err || !keyVersions.data) {
55+
helpers.addResult(results, 3,
56+
'Unable to query for cryptographic key versions: ' + helpers.addError(keyVersions), region);
57+
return rcb();
58+
}
59+
60+
if (!keyVersions.data.length) {
61+
helpers.addResult(results, 0, 'No key versions found', region);
62+
return rcb();
63+
}
64+
65+
keys.data.forEach(key => {
66+
const currentKeyVersion = keyVersions.data.find(version => version.id === key.currentKeyVersion);
67+
68+
let timeCreated = currentKeyVersion ? currentKeyVersion.timeCreated : key.timeCreated;
69+
var diffInDays = helpers.daysBetween(timeCreated, new Date());
70+
71+
if (diffInDays > keyRotationInterval) {
72+
helpers.addResult(results, 2,
73+
`Cryptographic Key was last rotated ${diffInDays} days ago which is greater than ${keyRotationInterval}`, region, key.id);
74+
} else {
75+
helpers.addResult(results, 0,
76+
`Cryptographic Key was last rotated ${diffInDays} days ago which is equal to or less than ${keyRotationInterval}`, region, key.id);
77+
}
78+
});
79+
80+
81+
}
82+
rcb();
83+
}, function(){
84+
// Global checking goes here
85+
callback(null, results, source);
86+
});
87+
}
88+
};

0 commit comments

Comments
 (0)