From c5aae322a9e0fcf5a93127f0b6a11008fa02c522 Mon Sep 17 00:00:00 2001 From: kshrutik <73834811+kshrutik@users.noreply.github.com> Date: Tue, 12 Jan 2021 01:32:18 +0530 Subject: [PATCH] PLA-21661 - Remediation job to enable logging for Key Vault (#42) --- .../README.md | 62 ++++++ .../__init__.py | 0 ..._key_vault_logging_for_keyvault_enabled.py | 206 ++++++++++++++++++ .../constraints.txt | 139 ++++++++++++ .../minimum_permissions.json | 22 ++ .../requirements-dev.txt | 33 +++ .../requirements.txt | 12 + ..._key_vault_logging_for_keyvault_enabled.py | 72 ++++++ tox.ini | 9 +- 9 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/README.md create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/__init__.py create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/azure_key_vault_logging_for_keyvault_enabled.py create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/constraints.txt create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/minimum_permissions.json create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements-dev.txt create mode 100644 remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements.txt create mode 100644 test/unit/test_azure_key_vault_logging_for_keyvault_enabled.py diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/README.md b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/README.md new file mode 100644 index 0000000..73e3e1e --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/README.md @@ -0,0 +1,62 @@ +# Enable Logging For Keyvault + +This job enables Key Vault Logging. + +### Applicable Rule + +##### Rule ID: +5c8c26687a550e1fb6560c72 + +##### Rule Name: +Logging For Keyvault Enabled + +## Getting Started +### Prerequisites +The provided Azure service principal must have the following permissions: +`Microsoft.Storage/storageAccounts/read` +`Microsoft.Storage/storageAccounts/write` +`Microsoft.Insights/DiagnosticSettings/Write` + +A sample role with requisite permissions can be found [here](minimum_permissions.json) + +More information about already builtin roles and permissions can be found [here](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles) + +### Running the script +You may run this script using following commands: + +```shell script + pip install -r requirements.txt + python3 azure_key_vault_logging_for_keyvault_enabled.py +``` +## Running the tests +You may run test using following command under vss-remediation-worker-job-code-python directory: + +```shell script + pip install -r requirements-dev.txt + python3 -m pytest test +``` +## Deployment +Provision a Virtual Machine Create an EC2 instance to use for the worker. The minimum required specifications are 128 MB memory and 1/2 Core CPU. +Setup Docker Install Docker on the newly provisioned EC2 instance. You can refer to the [docs here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-basics.html) for more information. +Deploy the worker image SSH into the EC2 instance and run the command below to deploy the worker image: + ```shell script + docker run --rm -it --name worker \ + -e VSS_CLIENT_ID={ENTER CLIENT ID} + -e VSS_CLIENT_SECRET={ENTER CLIENT SECRET} \ + vmware/vss-remediation-worker:latest-python + ``` +## Contributing +The Secure State team welcomes contributions from the community. If you wish to contribute code and you have not signed our contributor license agreement (CLA), our bot will update the issue when you open a Pull Request. For any questions about the CLA process, please refer to our [FAQ](https://cla.vmware.com/faq). + +All contributions to this repository must be signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on as an open-source patch. + +For more detailed information, refer to [CONTRIBUTING.md](../../../CONTRIBUTING.md). +## Versioning +We use SemVer for versioning. For the versions available, see the tags on this repository. + +## Authors +* **VMware Secure State** - *Initial work* +See also the list of [contributors](https://github.com/vmware-samples/secure-state-remediation-jobs/graphs/contributors) who participated in this project. + +## License +This project is licensed under the Apache License - see the [LICENSE](https://github.com/vmware-samples/secure-state-remediation-jobs/blob/master/LICENSE.txt) file for details diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/__init__.py b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/azure_key_vault_logging_for_keyvault_enabled.py b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/azure_key_vault_logging_for_keyvault_enabled.py new file mode 100644 index 0000000..01e2fff --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/azure_key_vault_logging_for_keyvault_enabled.py @@ -0,0 +1,206 @@ +# Copyright (c) 2020 VMware Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import sys +import logging + +from azure.identity import ClientSecretCredential +from azure.mgmt.keyvault import KeyVaultManagementClient +from azure.mgmt.monitor import MonitorClient +from azure.mgmt.storage import StorageManagementClient +from azure.mgmt.storage.models import ( + StorageAccountCreateParameters, + NetworkRuleSet, + Sku, + SkuName, + SkuTier, + DefaultAction, +) +from azure.mgmt.monitor.models import ( + DiagnosticSettingsResource, + LogSettings, + RetentionPolicy, +) + +logging.basicConfig(level=logging.INFO) + + +def generate_name(prefix): + prefix = "".join(i for i in prefix if i.islower() or i.isdigit()) + if len(prefix) >= 12: + prefix = str(prefix[:11]) + result_str = prefix + "keyvaultlogs" + return result_str + + +def create_storage_account( + resource_group_name, name, region, storage_client, +): + create_params = StorageAccountCreateParameters( + location=region, + sku=Sku(name=SkuName.STANDARD_LRS, tier=SkuTier.STANDARD), + kind="StorageV2", + enable_https_traffic_only=True, + network_rule_set=NetworkRuleSet(default_action=DefaultAction.DENY), + ) + poller = storage_client.storage_accounts.begin_create( + resource_group_name=resource_group_name, + account_name=name, + parameters=create_params, + ) + return poller.result() + + +class EnableKeyVaultLogging(object): + def parse(self, payload): + """Parse payload received from Remediation Service. + :param payload: JSON string containing parameters received from the remediation service. + :type payload: str. + :returns: Dictionary of parsed parameters + :rtype: dict + :raises: KeyError, JSONDecodeError + """ + remediation_entry = json.loads(payload) + + object_id = remediation_entry["notificationInfo"]["FindingInfo"]["ObjectId"] + + region = remediation_entry["notificationInfo"]["FindingInfo"]["Region"] + + object_chain = remediation_entry["notificationInfo"]["FindingInfo"][ + "ObjectChain" + ] + object_chain_dict = json.loads(object_chain) + subscription_id = object_chain_dict["cloudAccountId"] + + properties = object_chain_dict["properties"] + resource_group_name = "" + + for property in properties: + if property["name"] == "ResourceGroup" and property["type"] == "string": + resource_group_name = property["stringV"] + break + + logging.info("parsed params") + logging.info(f" resource_group_name: {resource_group_name}") + logging.info(f" account_name: {object_id}") + logging.info(f" subscription_id: {subscription_id}") + logging.info(f" region: {region}") + + return { + "resource_group_name": resource_group_name, + "key_vault_name": object_id, + "subscription_id": subscription_id, + "region": region, + } + + def remediate( + self, + keyvault_client, + monitor_client, + storage_client, + resource_group_name, + key_vault_name, + region, + ): + """Enable key vault logging + :param keyvault_client: Instance of the Azure KeyVaultManagementClient. + :param storage_client: Instance of the Azure StorageManagementClient. + :param monitor_client: Instance of the Azure MonitorClient. + :param resource_group_name: The name of the resource group to which the storage account belongs. + :param key_vault_name: The name of the key vault. + :param region: The region in which the key vault is present. + :type resource_group_name: str. + :type key_vault_name: str. + :type region: str. + :returns: Integer signaling success or failure + :rtype: int + :raises: msrestazure.azure_exceptions.CloudError + """ + key_vault = keyvault_client.vaults.get( + resource_group_name=resource_group_name, vault_name=key_vault_name, + ) + try: + stg_name = generate_name(key_vault_name) + logging.info(" Creating a Storage Account") + logging.info(" executing client_storage.storage_accounts.begin_create") + logging.info(f" resource_group_name={resource_group_name}") + logging.info(f" account_name={stg_name}") + stg_account = create_storage_account( + resource_group_name, stg_name, region, storage_client + ) + log = LogSettings( + category="AuditEvent", + enabled=True, + retention_policy=RetentionPolicy(enabled=True, days=180), + ) + + logging.info(" Creating a Diagnostic setting for key vault logs") + logging.info( + " executing monitor_client.diagnostic_settings.create_or_update" + ) + logging.info(f" resource_uri={key_vault.id}") + logging.info(f" name={key_vault_name}") + + monitor_client.diagnostic_settings.create_or_update( + resource_uri=key_vault.id, + name=key_vault_name, + parameters=DiagnosticSettingsResource( + storage_account_id=stg_account.id, logs=[log], + ), + ) + except Exception as e: + logging.error(f"{str(e)}") + raise + + return 0 + + def run(self, args): + """Run the remediation job. + :param args: List of arguments provided to the job. + :type args: list. + :returns: int + """ + params = self.parse(args[1]) + + credentials = ClientSecretCredential( + client_id=os.environ.get("AZURE_CLIENT_ID"), + client_secret=os.environ.get("AZURE_CLIENT_SECRET"), + tenant_id=os.environ.get("AZURE_TENANT_ID"), + ) + credentials_stg = ClientSecretCredential( + client_id=os.environ.get("AZURE_CLIENT_ID"), + client_secret=os.environ.get("AZURE_CLIENT_SECRET"), + tenant_id=os.environ.get("AZURE_TENANT_ID"), + ) + storage_client = StorageManagementClient( + credentials_stg, params["subscription_id"] + ) + keyvault_client = KeyVaultManagementClient( + credentials, params["subscription_id"] + ) + monitor_client = MonitorClient(credentials, params["subscription_id"]) + return self.remediate( + keyvault_client, + monitor_client, + storage_client, + params["resource_group_name"], + params["key_vault_name"], + params["region"], + ) + + +if __name__ == "__main__": + sys.exit(EnableKeyVaultLogging().run(sys.argv)) diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/constraints.txt b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/constraints.txt new file mode 100644 index 0000000..b184eeb --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/constraints.txt @@ -0,0 +1,139 @@ +adal==1.2.5 \ + --hash=sha256:7492aff8f0ba7dd4e1c477303295c645141540fff34c3ca6de0a0b0e6c1c122a \ + --hash=sha256:8003ba03ef04170195b3eddda8a5ab43649ef2c5f0287023d515affb1ccfcfc3 +azure-common==1.1.25 \ + --hash=sha256:ce0f1013e6d0e9faebaf3188cc069f4892fc60a6ec552e3f817c1a2f92835054 \ + --hash=sha256:fd02e4256dc9cdd2d4422bc795bdca2ef302f7a86148b154fbf4ea1f09da400a +azure-core==1.8.2 \ + --hash=sha256:621b53271f7988b766f8a7d7f7a2c44241e3d2c1d8db13e68089d6da6241748e \ + --hash=sha256:be23d411e19874f375c2ef0327c452be10b1e9a1023ac6afe334598f2920136b +azure-mgmt-core==1.2.1 \ + --hash=sha256:a3906fa77edfedfcc3229dc3b69489d5ed63b107c7eacbc50092e6cbfbfd83f0 \ + --hash=sha256:bd4503a2d81b86780f15936af2e4244c1345062f4c2422f0b377b56cb80d7796 +azure-identity==1.4.1 \ + --hash=sha256:6f95b3505fc134ad16bd16da053456e1933188ac43161704d48ddb4edebf72c9 \ + --hash=sha256:7b071089faf0789059ac24052e311e2b096a002c173d42b96896db09c6e2ba5d +azure-mgmt-network==16.0.0 \ + --hash=sha256:6159a8c44590cc58841690c27c7d4acb0cd9ad0a1e5178c1d35e0f48e3c3c0e9 \ + --hash=sha256:c0e8358e9d530790dbf3efef6b31bce26e664de5096cbd84c62845067da815d1 +azure-mgmt-storage==16.0.0 \ + --hash=sha256:2f9d714d9722b1ef4bac6563676612e6e795c4e90f6f3cd323616fdadb0a99e5 \ + --hash=sha256:a819e421d50c0b58416b551d3e9e9a9cf6029714cf977ffaaee86a37572e7113 +azure-mgmt-monitor==1.0.1 \ + --hash=sha256:04bd89d74fe47f966b09e3256ffefcfa5c1a51057a6b33c092afe5ae17a1a7b7 \ + --hash=sha256:92db4d133f58be900e5a2a9e3f44f4f0c068717bf534bf49c97e070c0280d203 +azure-mgmt-keyvault==8.0.0 \ + --hash=sha256:2c974c6114d8d27152642c82a975812790a5e86ccf609bf370a476d9ea0d2e7d \ + --hash=sha256:99da24e9455f195d1e45a605af04d663e15cb5d5eb005b0ef60638474bbb2b3f +certifi==2020.6.20 \ + --hash=sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3 \ + --hash=sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41 +cffi==1.14.3 \ + --hash=sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d \ + --hash=sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b \ + --hash=sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4 \ + --hash=sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f \ + --hash=sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3 \ + --hash=sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579 \ + --hash=sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537 \ + --hash=sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e \ + --hash=sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05 \ + --hash=sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171 \ + --hash=sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca \ + --hash=sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522 \ + --hash=sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c \ + --hash=sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc \ + --hash=sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d \ + --hash=sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808 \ + --hash=sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828 \ + --hash=sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869 \ + --hash=sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d \ + --hash=sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9 \ + --hash=sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0 \ + --hash=sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc \ + --hash=sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15 \ + --hash=sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c \ + --hash=sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a \ + --hash=sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3 \ + --hash=sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1 \ + --hash=sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768 \ + --hash=sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d \ + --hash=sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b \ + --hash=sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e \ + --hash=sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d \ + --hash=sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730 \ + --hash=sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394 \ + --hash=sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1 \ + --hash=sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591 +chardet==3.0.4 \ + --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ + --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 +cryptography==3.2.1 \ + --hash=sha256:07ca431b788249af92764e3be9a488aa1d39a0bc3be313d826bbec690417e538 \ + --hash=sha256:13b88a0bd044b4eae1ef40e265d006e34dbcde0c2f1e15eb9896501b2d8f6c6f \ + --hash=sha256:32434673d8505b42c0de4de86da8c1620651abd24afe91ae0335597683ed1b77 \ + --hash=sha256:3cd75a683b15576cfc822c7c5742b3276e50b21a06672dc3a800a2d5da4ecd1b \ + --hash=sha256:4e7268a0ca14536fecfdf2b00297d4e407da904718658c1ff1961c713f90fd33 \ + --hash=sha256:545a8550782dda68f8cdc75a6e3bf252017aa8f75f19f5a9ca940772fc0cb56e \ + --hash=sha256:55d0b896631412b6f0c7de56e12eb3e261ac347fbaa5d5e705291a9016e5f8cb \ + --hash=sha256:5849d59358547bf789ee7e0d7a9036b2d29e9a4ddf1ce5e06bb45634f995c53e \ + --hash=sha256:6dc59630ecce8c1f558277ceb212c751d6730bd12c80ea96b4ac65637c4f55e7 \ + --hash=sha256:7117319b44ed1842c617d0a452383a5a052ec6aa726dfbaffa8b94c910444297 \ + --hash=sha256:75e8e6684cf0034f6bf2a97095cb95f81537b12b36a8fedf06e73050bb171c2d \ + --hash=sha256:7b8d9d8d3a9bd240f453342981f765346c87ade811519f98664519696f8e6ab7 \ + --hash=sha256:a035a10686532b0587d58a606004aa20ad895c60c4d029afa245802347fab57b \ + --hash=sha256:a4e27ed0b2504195f855b52052eadcc9795c59909c9d84314c5408687f933fc7 \ + --hash=sha256:a733671100cd26d816eed39507e585c156e4498293a907029969234e5e634bc4 \ + --hash=sha256:a75f306a16d9f9afebfbedc41c8c2351d8e61e818ba6b4c40815e2b5740bb6b8 \ + --hash=sha256:bd717aa029217b8ef94a7d21632a3bb5a4e7218a4513d2521c2a2fd63011e98b \ + --hash=sha256:d25cecbac20713a7c3bc544372d42d8eafa89799f492a43b79e1dfd650484851 \ + --hash=sha256:d26a2557d8f9122f9bf445fc7034242f4375bd4e95ecda007667540270965b13 \ + --hash=sha256:d3545829ab42a66b84a9aaabf216a4dce7f16dbc76eb69be5c302ed6b8f4a29b \ + --hash=sha256:d3d5e10be0cf2a12214ddee45c6bd203dab435e3d83b4560c03066eda600bfe3 \ + --hash=sha256:efe15aca4f64f3a7ea0c09c87826490e50ed166ce67368a68f315ea0807a20df +idna==2.10 \ + --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \ + --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 +isodate==0.6.0 \ + --hash=sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8 \ + --hash=sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81 +msal==1.5.1 \ + --hash=sha256:7efb0256c96a7b2eadab49ce29ecdb91352a91440c12a40bed44303724b62fda \ + --hash=sha256:d84074a997e6fb2a47e22815dce376adcc8790838b6b1bf1fcea29378e2bf3eb +msal-extensions==0.2.2 \ + --hash=sha256:31414753c484679bb3b6c6401623eb4c3ccab630af215f2f78c1d5c4f8e1d1a9 \ + --hash=sha256:f092246787145ec96d6c3c9f7bedfb837830fe8a79b56180e531fbf28b8de532 +msrest==0.6.19 \ + --hash=sha256:55f8c3940bc5dc609f8cf9fcd639444716cc212a943606756272e0d0017bbb5b \ + --hash=sha256:87aa64948c3ef3dbf6f6956d2240493e68d714e4621b92b65b3c4d5808297929 +msrestazure==0.6.4 \ + --hash=sha256:3de50f56147ef529b31e099a982496690468ecef33f0544cb0fa0cfe1e1de5b9 \ + --hash=sha256:a06f0dabc9a6f5efe3b6add4bd8fb623aeadacf816b7a35b0f89107e0544d189 +oauthlib==3.1.0 \ + --hash=sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889 \ + --hash=sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea +portalocker==1.7.1 \ + --hash=sha256:34cb36c618d88bcd9079beb36dcdc1848a3e3d92ac4eac59055bdeafc39f9d4a \ + --hash=sha256:6d6f5de5a3e68c4dd65a98ec1babb26d28ccc5e770e07b672d65d5a35e4b2d8a +pycparser==2.20 \ + --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ + --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 +PyJWT==1.7.1 \ + --hash=sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e \ + --hash=sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96 +python-dateutil==2.8.1 \ + --hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \ + --hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a +requests==2.24.0 \ + --hash=sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b \ + --hash=sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898 +requests-oauthlib==1.3.0 \ + --hash=sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d \ + --hash=sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a \ + --hash=sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc +six==1.12.0 \ + --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ + --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 +urllib3==1.25.11 \ + --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \ + --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/minimum_permissions.json b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/minimum_permissions.json new file mode 100644 index 0000000..e59e8be --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/minimum_permissions.json @@ -0,0 +1,22 @@ +{ + "properties": { + "roleName": "remediate_set_default_network_access_deny", + "description": "This role has required permissions to make changes to the storage account", + "assignableScopes": [ + ], + "permissions": [ + { + "actions": [ + "Microsoft.Storage/storageAccounts/read", + "Microsoft.Storage/storageAccounts/write", + "Microsoft.Insights/DiagnosticSettings/Write", + "Microsoft.KeyVault/vaults/read", + "Microsoft.KeyVault/vaults/write" + ], + "notActions": [], + "dataActions": [], + "notDataActions": [] + } + ] + } + } diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements-dev.txt b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements-dev.txt new file mode 100644 index 0000000..759f2ca --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements-dev.txt @@ -0,0 +1,33 @@ +-r requirements.txt +-c constraints.txt + +attrs==20.1.0 \ + --hash=sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a \ + --hash=sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff +iniconfig==1.1.1 \ + --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ + --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 +mock==4.0.2 \ + --hash=sha256:3f9b2c0196c60d21838f307f5825a7b86b678cedc58ab9e50a8988187b4d81e0 \ + --hash=sha256:dd33eb70232b6118298d516bbcecd26704689c386594f0f3c4f13867b2c56f72 +packaging==20.4 \ + --hash=sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8 \ + --hash=sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181 +pluggy==0.13.1 \ + --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \ + --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d +py==1.9.0 \ + --hash=sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2 \ + --hash=sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342 +pyparsing==2.4.7 \ + --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \ + --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b +pytest==6.1.2 \ + --hash=sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe \ + --hash=sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e +toml==0.10.1 \ + --hash=sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f \ + --hash=sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88 +zipp==3.4.0 \ + --hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \ + --hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb diff --git a/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements.txt b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements.txt new file mode 100644 index 0000000..fbfcae4 --- /dev/null +++ b/remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements.txt @@ -0,0 +1,12 @@ +azure-identity==1.4.1 \ + --hash=sha256:6f95b3505fc134ad16bd16da053456e1933188ac43161704d48ddb4edebf72c9 \ + --hash=sha256:7b071089faf0789059ac24052e311e2b096a002c173d42b96896db09c6e2ba5d +azure-mgmt-storage==16.0.0 \ + --hash=sha256:2f9d714d9722b1ef4bac6563676612e6e795c4e90f6f3cd323616fdadb0a99e5 \ + --hash=sha256:a819e421d50c0b58416b551d3e9e9a9cf6029714cf977ffaaee86a37572e7113 +azure-mgmt-monitor==1.0.1 \ + --hash=sha256:04bd89d74fe47f966b09e3256ffefcfa5c1a51057a6b33c092afe5ae17a1a7b7 \ + --hash=sha256:92db4d133f58be900e5a2a9e3f44f4f0c068717bf534bf49c97e070c0280d203 +azure-mgmt-keyvault==8.0.0 \ + --hash=sha256:2c974c6114d8d27152642c82a975812790a5e86ccf609bf370a476d9ea0d2e7d \ + --hash=sha256:99da24e9455f195d1e45a605af04d663e15cb5d5eb005b0ef60638474bbb2b3f diff --git a/test/unit/test_azure_key_vault_logging_for_keyvault_enabled.py b/test/unit/test_azure_key_vault_logging_for_keyvault_enabled.py new file mode 100644 index 0000000..73901ef --- /dev/null +++ b/test/unit/test_azure_key_vault_logging_for_keyvault_enabled.py @@ -0,0 +1,72 @@ +# Copyright (c) 2020 VMware Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from mock import Mock +from remediation_worker.jobs.azure_key_vault_logging_for_keyvault_enabled.azure_key_vault_logging_for_keyvault_enabled import ( + EnableKeyVaultLogging, +) + + +@pytest.fixture +def valid_payload(): + return """ +{ + "notificationInfo": { + "RuleId": "5c8c26687a550e1fb6560c72", + "Service": "KeyVault", + "FindingInfo": { + "FindingId": "9b2da5e9-bb96-4298-b2c1-e6c341b44c5f", + "ObjectId": "key_vault_name", + "ObjectChain": "{\\"cloudAccountId\\":\\"subscription_id\\",\\"entityId\\":\\"Azure.KeyVault.d687b1a3-9b78-43b1-a17b-7de297fd1fce.accelerators-team-resources.Vault.key_vault_name\\",\\"entityName\\":\\"key_vault_name\\",\\"entityType\\":\\"Azure.KeyVault.Vault\\",\\"lastUpdateTime\\":\\"2020-09-09T00:36:35.000Z\\",\\"partitionKey\\":\\"d687b1a3-9b78-43b1-a17b-7de297fd1fce\\",\\"provider\\":\\"Azure\\",\\"region\\":\\"eastus\\",\\"service\\":\\"KeyVault\\", \\"properties\\":[{\\"name\\":\\"ResourceGroup\\",\\"stringV\\":\\"resource_group_name\\",\\"type\\":\\"string\\"}]}", + "Region": "region" + } + } +} +""" + + +class TestKeyVaultLoggingEnabled(object): + def test_parse_payload(self, valid_payload): + params = EnableKeyVaultLogging().parse(valid_payload) + assert params["key_vault_name"] == "key_vault_name" + assert params["resource_group_name"] == "resource_group_name" + assert params["subscription_id"] == "subscription_id" + assert params["region"] == "region" + + def test_remediate_success(self): + storage_client = Mock() + keyvault_client = Mock() + monitor_client = Mock() + action = EnableKeyVaultLogging() + assert ( + action.remediate( + keyvault_client, + monitor_client, + storage_client, + "resource_group", + "key_vault_name", + "region", + ) + == 0 + ) + assert storage_client.storage_accounts.begin_create.call_count == 1 + assert monitor_client.diagnostic_settings.create_or_update.call_count == 1 + + def test_remediate_with_exception(self): + client = Mock() + client.storage_accounts.update.side_effect = Exception + action = EnableKeyVaultLogging() + with pytest.raises(Exception): + assert action.remediate(client, "security_group_id", "resource_group") diff --git a/tox.ini b/tox.ini index 871765e..ea914af 100644 --- a/tox.ini +++ b/tox.ini @@ -23,6 +23,7 @@ envlist = unit-azure-sql-data-encryption-on unit-azure-sql-auditing-on-server unit-azure-sql-threat-detection-on-server + unit-azure-key-vault-logging-for-keyvault-enabled [testenv] passenv = @@ -166,4 +167,10 @@ deps = -r remediation_worker/jobs/azure_sql_auditing_on_server/requirements-dev. description = Unit test the project changedir = test commands = pytest --capture=no --basetemp="{envtmpdir}" unit/test_azure_sql_threat_detection_on_server.py -deps = -r remediation_worker/jobs/azure_sql_threat_detection_on_server/requirements-dev.txt \ No newline at end of file +deps = -r remediation_worker/jobs/azure_sql_threat_detection_on_server/requirements-dev.txt + +[testenv:unit-azure-key-vault-logging-for-keyvault-enabled] +description = Unit test the project +changedir = test +commands = pytest --capture=no --basetemp="{envtmpdir}" unit/test_azure_key_vault_logging_for_keyvault_enabled.py +deps = -r remediation_worker/jobs/azure_key_vault_logging_for_keyvault_enabled/requirements-dev.txt