Skip to content

Commit

Permalink
Revised keyVaultKeyExpiry (#2105)
Browse files Browse the repository at this point in the history
* Revised keyVaultKeyExpiry

* Revised keyVaultKeyExpiry

* Apply suggestions from code review

* Update plugins/azure/keyvaults/keyVaultKeyExpiry.js

* Update keyVaultKeyExpiry.js

* Update keyVaultKeyExpiry.spec.js

* Apply suggestions from code review

* Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js

* Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js

* Update plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js

---------

Co-authored-by: AkhtarAmir <AkhtarAmir>
Co-authored-by: alphadev4 <113519745+alphadev4@users.noreply.github.com>
  • Loading branch information
AkhtarAmir and alphadev4 authored Nov 11, 2024
1 parent f75a336 commit 4af0f44
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 77 deletions.
30 changes: 19 additions & 11 deletions plugins/azure/keyvaults/keyVaultKeyExpiry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ var async = require('async');
var helpers = require('../../../helpers/azure');

module.exports = {
title: 'Key Vault Key Expiry',
title: 'Key Vault Key Expiry RBAC',
category: 'Key Vaults',
domain: 'Application Integration',
severity: 'High',
description: 'Proactively check for Key Vault keys expiry date and rotate them before expiry date is reached.',
more_info: 'After expiry date has reached for Key Vault key, it cannot be used for cryptographic operations anymore.',
recommended_action: 'Ensure that Key Vault keys are rotated before they get expired.',
description: 'Ensures that expiration date is set for all keys in RBAC Key Vaults.',
more_info: 'Setting an expiration date on keys helps in key lifecycle management and ensures that keys are rotated regularly.',
recommended_action: 'Modify keys in RBAC Key Vaults to have an expiration date set.',
link: 'https://learn.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates',
apis: ['vaults:list', 'vaults:getKeys'],
settings: {
Expand Down Expand Up @@ -45,38 +45,46 @@ module.exports = {
return rcb();
}

vaults.data.forEach(function(vault){
vaults.data.forEach(function(vault) {
if (!vault || !vault.properties) {
helpers.addResult(results, 3, 'Unable to read vault properties', location, vault.id);
return;
}
if (!vault.properties.enableRbacAuthorization) {
return;
}

var keys = helpers.addSource(cache, source,
['vaults', 'getKeys', location, vault.id]);

if (!keys || keys.err || !keys.data) {
helpers.addResult(results, 3, 'Unable to query for Key Vault keys: ' + helpers.addError(keys), location, vault.id);
} else if (!keys.data.length) {
helpers.addResult(results, 0, 'No Key Vault keys found', location, vault.id);
helpers.addResult(results, 0, 'No Key Vault keys found in RBAC vault', location, vault.id);
} else {
keys.data.forEach(function(key) {
var keyName = key.kid.substring(key.kid.lastIndexOf('/') + 1);
var keyId = `${vault.id}/keys/${keyName}`;

if (!key.attributes || !key.attributes.enabled) {
helpers.addResult(results, 0,
'Key is not enabled', location, keyId);
'Key in RBAC vault is not enabled', location, keyId);
} else if (key.attributes && (key.attributes.expires || key.attributes.exp)) {
let keyExpiry = key.attributes.exp ? key.attributes.exp * 1000 : key.attributes.expires;
let difference = Math.round((new Date(keyExpiry).getTime() - (new Date).getTime())/(24*60*60*1000));
if (difference > config.key_vault_key_expiry_fail) {
helpers.addResult(results, 0,
`Key expires in ${difference} days`, location, keyId);
`Key in RBAC vault expires in ${difference} days`, location, keyId);
} else if (difference > 0){
helpers.addResult(results, 2,
`Key expires in ${difference} days`, location, keyId);
`Key in RBAC vault expires in ${difference} days`, location, keyId);
} else {
helpers.addResult(results, 2,
`Key expired ${Math.abs(difference)} days ago`, location, keyId);
`Key in RBAC vault expired ${Math.abs(difference)} days ago`, location, keyId);
}
} else {
helpers.addResult(results, 0,
'Key expiration is not enabled', location, keyId);
'Key expiration is not enabled in RBAC vault', location, keyId);
}
});
}
Expand Down
107 changes: 41 additions & 66 deletions plugins/azure/keyvaults/keyVaultKeyExpiry.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,96 +12,71 @@ keyExpired.setMonth(keyExpired.getMonth() - 1);

const listKeyVaults = [
{
id: '/subscriptions/abcdfget-ebf6-437f-a3b0-28fc0d22111e/resourceGroups/akhtar-rg/providers/Microsoft.KeyVault/vaults/nauman-test',
name: 'nauman-test',
id: '/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault',
name: 'test-vault',
type: 'Microsoft.KeyVault/vaults',
location: 'eastus',
tags: { owner: 'kubernetes' },
sku: { family: 'A', name: 'Standard' },
tenantId: '2d4f0836-5935-47f5-954c-14e713119ac2',
accessPolicies: [
{
tenantId: '2d4f0836-5935-47f5-954c-14e713119ac2',
objectId: 'b4062000-c33b-448b-817e-fa0f17bef4b9',
permissions: {
keys: ['Get', 'List'],
secrets: ['Get', 'List'],
certificates: ['Get', 'List']
}
}
],
enableSoftDelete: true,
softDeleteRetentionInDays: 7,
enableRbacAuthorization: false,
vaultUri: 'https://nauman-test.vault.azure.net/',
provisioningState: 'Succeeded'
}
];

const getKeys = [
properties: {
enableRbacAuthorization: true,
vaultUri: 'https://test-vault.vault.azure.net/'
}
},
{
id: '/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault-2',
name: 'test-vault-2',
type: 'Microsoft.KeyVault/vaults',
location: 'eastus',
properties: {
enableRbacAuthorization: false,
vaultUri: 'https://test-vault-2.vault.azure.net/'
}
}
];

const getKeys = [
{
"attributes": {
"created": "2022-04-10T17:57:43+00:00",
"enabled": true,
"expires": null,
"notBefore": null,
"recoveryLevel": "CustomizedRecoverable+Purgeable",
"updated": "2022-04-10T17:57:43+00:00"
},
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
"managed": null,
"name": "nauman-test",
"tags": {
"hello": "world"
}
"kid": "https://test-vault.vault.azure.net/keys/test-key",
"name": "test-key"
},
{
"attributes": {
"created": "2022-04-10T17:57:43+00:00",
"enabled": true,
"expires": keyExpiryPass,
"notBefore": null,
"recoveryLevel": "CustomizedRecoverable+Purgeable",
"updated": "2022-04-10T17:57:43+00:00"
},
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
"managed": null,
"name": "nauman-test",
"tags": {
"hello": "world"
}
"kid": "https://test-vault.vault.azure.net/keys/test-key-2",
"name": "test-key-2"
},
{
"attributes": {
"created": "2022-04-10T17:57:43+00:00",
"enabled": true,
"expires": keyExpiryFail,
"notBefore": null,
"recoveryLevel": "CustomizedRecoverable+Purgeable",
"updated": "2022-04-10T17:57:43+00:00"
},
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
"managed": null,
"name": "nauman-test",
"tags": {
"hello": "world"
}
"kid": "https://test-vault.vault.azure.net/keys/test-key-3",
"name": "test-key-3"
},
{
"attributes": {
"created": "2022-04-10T17:57:43+00:00",
"enabled": true,
"expires": keyExpired,
"notBefore": null,
"recoveryLevel": "CustomizedRecoverable+Purgeable",
"updated": "2022-04-10T17:57:43+00:00"
},
"kid": "https://nauman-test.vault.azure.net/keys/nauman-test",
"managed": null,
"name": "nauman-test",
"tags": {
"hello": "world"
}
"kid": "https://test-vault.vault.azure.net/keys/test-key-4",
"name": "test-key-4"
}
];

Expand All @@ -116,7 +91,7 @@ const createCache = (err, list, keys) => {
},
getKeys: {
'eastus': {
'/subscriptions/abcdfget-ebf6-437f-a3b0-28fc0d22111e/resourceGroups/akhtar-rg/providers/Microsoft.KeyVault/vaults/nauman-test': {
'/subscriptions/123/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-vault': {
err: err,
data: keys
}
Expand All @@ -126,9 +101,9 @@ const createCache = (err, list, keys) => {
}
};

describe('keyVaultKeyExpiry', function() {
describe('keyVaultKeyExpiryRbac', function() {
describe('run', function() {
it('should give passing result if no keys found', function(done) {
it('should give passing result if no key vaults found', function(done) {
const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
Expand All @@ -144,7 +119,7 @@ describe('keyVaultKeyExpiry', function() {
const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('Key expiration is not enabled');
expect(results[0].message).to.include('Key expiration is not enabled in RBAC vault');
expect(results[0].region).to.equal('eastus');
done()
};
Expand All @@ -156,36 +131,36 @@ describe('keyVaultKeyExpiry', function() {
const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('Key expires in');
expect(results[0].message).to.include('Key in RBAC vault expires in');
expect(results[0].region).to.equal('eastus');
done()
};

auth.run(createCache(null, listKeyVaults, [getKeys[1]]), { key_vault_key_expiry_fail: '30' }, callback);
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[1]]), { key_vault_key_expiry_fail: '30' }, callback);
});

it('should give failing results if the key has reached', function(done) {
it('should give failing results if the key has expired', function(done) {
const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('Key expired');
expect(results[0].message).to.include('Key in RBAC vault expired');
expect(results[0].region).to.equal('eastus');
done()
};

auth.run(createCache(null, listKeyVaults, [getKeys[3]]), { key_vault_key_expiry_fail: '40' }, callback);
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[3]]), { key_vault_key_expiry_fail: '40' }, callback);
});

it('should give failing results if the key expired within failure expiry date', function(done) {
it('should give failing result if the key expires within failure expiry date', function(done) {
const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('Key expires');
expect(results[0].message).to.include('Key in RBAC vault expires');
expect(results[0].region).to.equal('eastus');
done()
};

auth.run(createCache(null, listKeyVaults, [getKeys[2]]), { key_vault_key_expiry_fail: '40' }, callback);
auth.run(createCache(null, [listKeyVaults[0]], [getKeys[2]]), { key_vault_key_expiry_fail: '40' }, callback);
});
});
});
});

0 comments on commit 4af0f44

Please sign in to comment.