diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/__init__.py b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/__init__.py index 5e90b419b58..23e70d3fa48 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/__init__.py +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/__init__.py @@ -6,18 +6,20 @@ import json from .sentinel import AzureSentinel from .exports_store import ExportsTableStore -from Exceptions.ArmisExceptions import ArmisException, ArmisDataNotFoundException +from Exceptions.ArmisExceptions import ArmisException, ArmisDataNotFoundException, ArmisTimeOutException from .utils import Utils from . import consts import inspect +import time class ArmisAlertsActivities(Utils): """This class will process the Alert Activity data and post it into the Microsoft sentinel.""" - def __init__(self): + def __init__(self, start_time): """__init__ method will initialize object of class.""" super().__init__() + self.start_time = start_time self.data_alert_from = 0 self.azuresentinel = AzureSentinel() self.total_alerts_posted = 0 @@ -174,6 +176,36 @@ def post_alert_activity_data( ) raise ArmisException() + def process_large_chunks_of_activity_data(self, activity_uuids): + """Process large chunks of activity data for specific alert. + + Args: + activity_uuids (list): list of activity uuids + """ + __method_name = inspect.currentframe().f_code.co_name + try: + for index in range(0, len(activity_uuids), consts.CHUNK_SIZE): + if int(time.time()) >= self.start_time + consts.FUNCTION_APP_TIMEOUT_SECONDS: + raise ArmisTimeOutException() + chunk_of_activity_uuids = activity_uuids[index: index + consts.CHUNK_SIZE] + activity_data = self.get_activity_data(chunk_of_activity_uuids) + self.azuresentinel.post_data( + json.dumps(activity_data, indent=2), + consts.ARMIS_ACTIVITIES_TABLE, + "armis_activity_time", + ) + self.total_activities_posted += len(activity_data) + logging.info( + consts.LOG_FORMAT.format( + __method_name, "Posted Activities count : {}.".format(len(activity_data)) + ) + ) + except ArmisException: + raise ArmisException() + + except ArmisTimeOutException: + raise ArmisTimeOutException() + def process_alerts_data(self, alerts, offset_to_post, checkpoint_table_object: ExportsTableStore): """Process alerts data to fetch related activity. @@ -185,6 +217,8 @@ def process_alerts_data(self, alerts, offset_to_post, checkpoint_table_object: E activity_uuid_list = [] alerts_data_to_post = [] for alert in alerts: + if int(time.time()) >= self.start_time + consts.FUNCTION_APP_TIMEOUT_SECONDS: + raise ArmisTimeOutException() activity_uuids = alert.get("activityUUIDs", []) if len(activity_uuid_list) + len(activity_uuids) <= consts.CHUNK_SIZE: activity_uuid_list.extend(activity_uuids) @@ -200,23 +234,13 @@ def process_alerts_data(self, alerts, offset_to_post, checkpoint_table_object: E alerts_data_to_post.append(alert) else: logging.info( - consts.LOG_FORMAT.format( - __method_name, "Chunk size is greater than {}.".format(consts.CHUNK_SIZE)) - ) - for index in range(0, len(activity_uuids), consts.CHUNK_SIZE): - chunk_of_activity_uuids = activity_uuids[index: index + consts.CHUNK_SIZE] - activity_data = self.get_activity_data(chunk_of_activity_uuids) - self.azuresentinel.post_data( - json.dumps(activity_data, indent=2), - consts.ARMIS_ACTIVITIES_TABLE, - "armis_activity_time", - ) - self.total_activities_posted += len(activity_data) - logging.info( - consts.LOG_FORMAT.format( - __method_name, "Posted Activities count : {}.".format(len(activity_data)) - ) + consts.LOG_FORMAT.format( + __method_name, "Chunk size is greater than {}.".format(consts.CHUNK_SIZE) ) + ) + self.process_large_chunks_of_activity_data( + activity_uuids + ) self.azuresentinel.post_data( json.dumps([alert], indent=2), consts.ARMIS_ALERTS_TABLE, "armis_alert_time" ) @@ -237,6 +261,9 @@ def process_alerts_data(self, alerts, offset_to_post, checkpoint_table_object: E except ArmisException: raise ArmisException() + except ArmisTimeOutException: + raise ArmisTimeOutException() + except Exception as err: logging.error( consts.LOG_FORMAT.format( @@ -257,13 +284,22 @@ def fetch_alert_data( """ __method_name = inspect.currentframe().f_code.co_name try: + aql_with_severity = "in:alerts" + if consts.SEVERITY in consts.SEVERITIES: + severity_index = consts.SEVERITIES.index(consts.SEVERITY) + included_severities = ",".join(consts.SEVERITIES[severity_index:]) + aql_with_severity = f"in:alerts severity:{included_severities}" + else: + raise ValueError() if is_checkpoint_not_exist: - aql_data = "in:alerts" + aql_data = aql_with_severity else: - aql_data = """{} after:{}""".format("in:alerts", last_time) + aql_data = """{} after:{}""".format(aql_with_severity, last_time) alert_parameter["aql"] = aql_data alert_parameter["length"] = 1000 while self.data_alert_from is not None: + if int(time.time()) >= self.start_time + consts.FUNCTION_APP_TIMEOUT_SECONDS: + raise ArmisTimeOutException() alert_parameter.update({"from": self.data_alert_from}) offset_to_post = self.data_alert_from logging.info(consts.LOG_FORMAT.format(__method_name, "Fetching alerts data with parameters = {}.".format(alert_parameter))) @@ -295,6 +331,17 @@ def fetch_alert_data( except ArmisDataNotFoundException: raise ArmisDataNotFoundException() + except ArmisTimeOutException: + raise ArmisTimeOutException() + + except ValueError: + logging.error( + consts.LOG_FORMAT.format( + __method_name, "Value Error occurred, Severity value is not from the list 'Low', 'Medium', 'High', 'Critical'." + ) + ) + raise ArmisException() + except Exception as err: logging.error(consts.LOG_FORMAT.format(__method_name, "Error occurred : {}.".format(err))) raise ArmisException() @@ -374,6 +421,14 @@ def check_data_exists_or_not_alert(self): except ArmisException: raise ArmisException() + except ArmisTimeOutException: + logging.error( + consts.LOG_FORMAT.format( + __method_name, "9:30 mins executed hence stopping the execution" + ) + ) + return + except ArmisDataNotFoundException: raise ArmisDataNotFoundException() @@ -399,8 +454,8 @@ def main(mytimer: func.TimerRequest) -> None: logging.info( consts.LOG_FORMAT.format(__method_name, "Python timer trigger function ran at {}".format(utc_timestamp)) ) - - armis_obj = ArmisAlertsActivities() + start_time = time.time() + armis_obj = ArmisAlertsActivities(start_time) try: armis_obj.check_data_exists_or_not_alert() except ArmisDataNotFoundException: diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/consts.py b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/consts.py index d1422b6d712..01f417706c4 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/consts.py +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/consts.py @@ -20,6 +20,8 @@ "activityUUIDs", ] RETRY_COUNT_401 = 3 +SEVERITY = os.environ.get("Severity", "Low") +SEVERITIES = ["Low", "Medium", "High", "Critical"] # Sentinel constants CONNECTION_STRING = os.environ.get("AzureWebJobsStorage", "") @@ -27,6 +29,7 @@ ARMIS_ACTIVITIES_TABLE = os.environ.get("ArmisActivitiesTableName", "") WORKSPACE_ID = os.environ.get("WorkspaceID", "") WORKSPACE_KEY = os.environ.get("WorkspaceKey", "") +KEYVAULT_NAME = os.environ.get("KeyVaultName", "") CHUNK_SIZE = 35 FILE_SHARE = "funcstatemarkershare" CHECKPOINT_FILE_TIME = "funcarmisalertsfile" @@ -34,3 +37,4 @@ LOG_FORMAT = "Armis Alerts Activities Connector: (method = {}) : {}" REQUEST_TIMEOUT = 300 CHECKPOINT_TABLE_NAME = "ArmisAlertActivityCheckpoint" +FUNCTION_APP_TIMEOUT_SECONDS = 570 diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/host.json b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/host.json new file mode 100644 index 00000000000..55d16424d66 --- /dev/null +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/host.json @@ -0,0 +1,7 @@ +{ + "version": "2.0", + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[4.*, 5.0.0)" + } +} \ No newline at end of file diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/keyvault_secrets_management.py b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/keyvault_secrets_management.py new file mode 100644 index 00000000000..52562484b13 --- /dev/null +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/keyvault_secrets_management.py @@ -0,0 +1,64 @@ +"""This file is used for accessing keyvault to get or set secrets.""" +import logging +from azure.keyvault.secrets import SecretClient +from azure.identity import DefaultAzureCredential +from azure.core.exceptions import ResourceNotFoundError +from . import consts + + +class KeyVaultSecretManager: + """This class contains methods to authenticate with Azure KeyVault and get or set secrets in keyvault.""" + + def __init__(self) -> None: + """Intialize instance variables for class.""" + self.keyvault_name = consts.KEYVAULT_NAME + self.keyvault_uri = "https://{}.vault.azure.net/".format(self.keyvault_name) + self.client = self.get_client() + + def get_client(self): + """To obtain AzureKeyVault client. + + Returns: + SecretClient: returns client object for accessing AzureKeyVault. + """ + credential = DefaultAzureCredential() + client = SecretClient(vault_url=self.keyvault_uri, credential=credential) + return client + + def get_keyvault_secret(self, secret_name): + """To get value of provided secretname from AzureKeyVault. + + Args: + secret_name (str): secret name to get its value. + """ + try: + logging.info("Retrieving secret {} from {}.".format(secret_name, self.keyvault_name)) + retrieved_secret = self.client.get_secret(secret_name) + logging.info("Retrieved secret value for {}.".format(retrieved_secret.name)) + return retrieved_secret.value + + except ResourceNotFoundError as err: + logging.error("Resource not found : '{}' ".format(err)) + self.set_keyvault_secret(secret_name, "") + return "" + + def set_keyvault_secret(self, secret_name, secret_value): + """To update secret value of given secret name or create new secret. + + Args: + secret_name (str): secret name to update its value or create it. + secret_value (str): secret value to be set as value of given secret name. + """ + logging.info("Creating or updating a secret '{}'.".format(secret_name)) + self.client.set_secret(secret_name, secret_value) + logging.info("Secret created successfully : '{}' .".format(secret_name)) + + def get_properties_list_of_secrets(self): + """To get list of secrets stored in keyvault with its properties. + + Returns: + list: _description_ + """ + secret_properties = self.client.list_properties_of_secrets() + properties_list = [secret_property.name for secret_property in secret_properties] + return properties_list diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/utils.py b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/utils.py index b4f7aedfc3a..3f5c7fce4e7 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/utils.py +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertActivitySentinelConnector/utils.py @@ -6,6 +6,7 @@ import requests from . import consts from .state_manager import StateManager +from .keyvault_secrets_management import KeyVaultSecretManager class Utils: @@ -27,7 +28,14 @@ def __init__(self) -> None: ] ) self._secret_key = consts.API_KEY - self.get_access_token() + self.keyvault_obj = KeyVaultSecretManager() + self.access_token_key = "armis-access-token" + properties_list = self.keyvault_obj.get_properties_list_of_secrets() + if self.access_token_key in properties_list: + self.access_token = self.keyvault_obj.get_keyvault_secret(self.access_token_key) + self.header.update({"Authorization": self.access_token}) + else: + self.get_access_token() self.state_manager_obj = StateManager( connection_string=consts.CONNECTION_STRING, file_path=consts.CHECKPOINT_FILE_TIME ) @@ -61,6 +69,35 @@ def check_environment_var_exist(self, environment_var): ) raise ArmisException() + def compare_access_token(self): + """compare_access_token will compare the current access token with the access token stored in keyvault + and update the header for further use. + """ + __method_name = inspect.currentframe().f_code.co_name + try: + keyvault_access_token = self.keyvault_obj.get_keyvault_secret(self.access_token_key) + header_access_token = self.header.get("Authorization") + if keyvault_access_token == header_access_token: + logging.info(consts.LOG_FORMAT.format( + __method_name, "KeyVault Access Token Invalid. Generating New Token." + )) + self.get_access_token() + else: + logging.info(consts.LOG_FORMAT.format( + __method_name, "KeyVault Access Token Updated. Updating Header Value." + )) + self.header.update({"Authorization": keyvault_access_token}) + except ArmisException: + raise ArmisException() + except Exception as err: + logging.error( + consts.LOG_FORMAT.format( + __method_name, + "Unexpected error : {}.".format(err), + ) + ) + raise ArmisException() + def make_rest_call(self, method, url, params=None, headers=None, data=None, retry_401=0): """Make a rest call. @@ -103,7 +140,7 @@ def make_rest_call(self, method, url, params=None, headers=None, data=None, retr __method_name, "Unauthorized, Status code : {}, Retrying...".format(response.status_code) ) ) - self.get_access_token() + self.compare_access_token() self.retry_count += 1 continue elif response.status_code == 429: @@ -230,6 +267,7 @@ def get_access_token(self): response = self.make_rest_call(method="POST", url=consts.URL + consts.ACCESS_TOKEN_SUFFIX, data=body) access_token = response.get("data", {}).get("access_token") self.header.update({"Authorization": access_token}) + self.keyvault_obj.set_keyvault_secret(self.access_token_key, access_token) logging.info(consts.LOG_FORMAT.format(__method_name, "Generated access token Successfully.")) except KeyError as err: logging.error(consts.LOG_FORMAT.format(__method_name, "Key error : {}.".format(err))) diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivitiesSentinelConn311.zip b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivitiesSentinelConn311.zip new file mode 100644 index 00000000000..4de71bceb2a Binary files /dev/null and b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivitiesSentinelConn311.zip differ diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivities_API_FunctionApp.json b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivities_API_FunctionApp.json index f2209d0d96a..26bda67fe0d 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivities_API_FunctionApp.json +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/ArmisAlertsActivities_API_FunctionApp.json @@ -104,7 +104,27 @@ }, { "title": "", - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "title": "", + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Alerts Activities Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "title": "", + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "title": "", + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "title": "", + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "title": "", + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [{ "parameters": { "fillWith": [ @@ -127,7 +147,7 @@ }, { "title": "Option 1 - Azure Resource Manager (ARM) Template", - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy." + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy." }, { "title": "Option 2 - Manual Deployment of Azure Functions", @@ -135,11 +155,11 @@ }, { "title": "", - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { "title": "", - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ] } \ No newline at end of file diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/Exceptions/ArmisExceptions.py b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/Exceptions/ArmisExceptions.py index 511169b052f..8e999d742e7 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/Exceptions/ArmisExceptions.py +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/Exceptions/ArmisExceptions.py @@ -11,3 +11,9 @@ class ArmisDataNotFoundException(Exception): """ArmisDataNotFoundException class will inherit Exception class.""" pass + + +class ArmisTimeOutException(Exception): + """ArmisTimeOutException class will inherit Exception class.""" + + pass diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/azuredeploy_Connector_ArmisAlertsActivitiesAPI_AzureFunction.json b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/azuredeploy_Connector_ArmisAlertsActivitiesAPI_AzureFunction.json index 7a3f4cf8b4d..dd8c467bcac 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/azuredeploy_Connector_ArmisAlertsActivitiesAPI_AzureFunction.json +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/azuredeploy_Connector_ArmisAlertsActivitiesAPI_AzureFunction.json @@ -48,6 +48,19 @@ "description": "Enter name of the table used to store Armis Activities logs. Default is 'Armis_Activities_CL'" } }, + "Severity": { + "type": "string", + "metadata": { + "description": "Add severity value for Alert. Default is 'Low'" + }, + "allowedValues": [ + "Low", + "Medium", + "High", + "Critical" + ], + "defaultValue": "Low" + }, "ArmisSchedule":{ "type": "string", "defaultValue": "0 */15 * * * *", @@ -55,6 +68,33 @@ "description": "Enter a valid Quartz Cron-Expression (Example: 0 0 0 * * *)" } }, + "KeyVaultName": { + "type": "string", + "metadata": { + "description": "Enter name of keyvault where access token will be stored (Note: Use the previously created key vault name specific to above API key within the Azure workspace)" + } + }, + "AzureClientId": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Enter Azure Client Id that you have created during app registration" + } + }, + "AzureClientSecret": { + "type": "securestring", + "minLength": 1, + "metadata": { + "description": "Enter Azure Client Secret that you have created during creating the client secret" + } + }, + "TenantId":{ + "type": "string", + "minLength": 1, + "metadata": { + "description": "Enter Tenant Id of your Microsoft Entra Id" + } + }, "AppInsightsWorkspaceResourceID": { "type": "string", "metadata": { @@ -195,8 +235,13 @@ "ArmisURL": "[parameters('ArmisBaseURL')]", "ArmisAlertsTableName": "[parameters('ArmisAlertsTableName')]", "ArmisActivitiesTableName": "[parameters('ArmisActivitiesTableName')]", + "Severity": "[parameters('Severity')]", "Schedule": "[parameters('ArmisSchedule')]", - "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-ArmisAlertsActivities-functionapp" + "KeyVaultName": "[parameters('KeyvaultName')]", + "AZURE_CLIENT_ID": "[parameters('AzureClientId')]", + "AZURE_CLIENT_SECRET": "[parameters('AzureClientSecret')]", + "AZURE_TENANT_ID": "[parameters('TenantId')]", + "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-ArmisAlertsActivities311-functionapp" } } ] diff --git a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/requirements.txt b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/requirements.txt index 52584d6099a..306cc61b236 100644 --- a/Solutions/Armis/Data Connectors/ArmisAlertsActivities/requirements.txt +++ b/Solutions/Armis/Data Connectors/ArmisAlertsActivities/requirements.txt @@ -6,3 +6,5 @@ azure-functions azure-storage-file-share==12.3.0 requests azure-data-tables==12.1.0 +azure-keyvault-secrets +azure-identity diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConn311.zip b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConn311.zip new file mode 100644 index 00000000000..f79a504a47e Binary files /dev/null and b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConn311.zip differ diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/__init__.py b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/__init__.py index f701a455af4..8fe348a5301 100644 --- a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/__init__.py +++ b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/__init__.py @@ -12,6 +12,7 @@ import requests from .state_manager import StateManager from .exports_store import ExportsTableStore +from .keyvault_secrets_management import KeyVaultSecretManager from Exceptions.ArmisExceptions import ( ArmisException, ArmisDataNotFoundException, @@ -70,6 +71,7 @@ def _get_access_token_device(self, armis_link_suffix): response = response.json() _access_token = response.get("data", {}).get("access_token") self._header.update({"Authorization": _access_token}) + self.keyvault_obj.set_keyvault_secret(self.access_token_key, _access_token) elif response.status_code == 400: raise ArmisException( "Armis Device Connector: Please check either armis URL or armis secret key is wrong." @@ -126,6 +128,79 @@ def validate_timestamp(self, last_seen_time): logging.error("Armis Device Connector: Error occurred: {}".format(err)) raise ArmisException(err) + def compare_access_token(self): + """compare_access_token will compare the current access token with the access token stored in keyvault + and update the header for further use. + """ + try: + keyvault_access_token = self.keyvault_obj.get_keyvault_secret(self.access_token_key) + header_access_token = self._header.get("Authorization") + if keyvault_access_token == header_access_token: + logging.info("Armis Device Connector: KeyVault Access Token Invalid. Generating New Token.") + self._get_access_token_device("/access_token/") + else: + logging.info("Armis Device Connector: KeyVault Access Token Updated. Updating Header Value.") + self._header.update({"Authorization": keyvault_access_token}) + except ArmisException as err: + logging.error(err) + raise ArmisException( + "Armis Device Connector: Error while comparing access token." + ) + + def process_successful_data(self, results): + """process_successful_data will process the data and return the data to be posted in sentinel. + + Args: + results (json): json data to be processed. + + Returns: + tuple: tuple containing data, last_seen_time, total_data_length, count_per_frame_data + """ + try: + if results["data"]["count"] == 0: + raise ArmisDataNotFoundException( + "Armis Device Connector: Data not found." + ) + + if ( + "data" in results + and "results" in results["data"] + and "total" in results["data"] + and "count" in results["data"] + and "next" in results["data"] + ): + total_data_length = results["data"]["total"] + count_per_frame_data = results["data"]["count"] + data = results["data"]["results"] + + for i in data: + i["armis_device_time"] = i["lastSeen"] + + logging.info( + "Armis Device Connector: From {}, total length {}".format( + self._data_device_from, total_data_length + ) + ) + self._data_device_from = results["data"]["next"] + last_seen_time = data[-1]["lastSeen"][:19] + last_seen_time = self.validate_timestamp(last_seen_time) + + return ( + data, + last_seen_time, + total_data_length, + count_per_frame_data, + ) + else: + raise ArmisException( + "Armis Device Connector: There are no proper keys in data." + ) + except ArmisDataNotFoundException as err: + logging.info(err) + raise ArmisDataNotFoundException() + except ArmisException as err: + raise ArmisException(err) + def _get_device_data(self, armis_link_suffix, parameter): """Get_device_data is used to get data using api. @@ -146,44 +221,7 @@ def _get_device_data(self, armis_link_suffix, parameter): logging.info("Armis Device Connector: Status Code : 200") results = response.json() - if results["data"]["count"] == 0: - raise ArmisDataNotFoundException( - "Armis Device Connector: Data not found." - ) - - if ( - "data" in results - and "results" in results["data"] - and "total" in results["data"] - and "count" in results["data"] - and "next" in results["data"] - ): - total_data_length = results["data"]["total"] - count_per_frame_data = results["data"]["count"] - data = results["data"]["results"] - - for i in data: - i["armis_device_time"] = i["lastSeen"] - - logging.info( - "Armis Device Connector: From {}, total length {}".format( - self._data_device_from, total_data_length - ) - ) - self._data_device_from = results["data"]["next"] - last_seen_time = data[-1]["lastSeen"][:19] - last_seen_time = self.validate_timestamp(last_seen_time) - - return ( - data, - last_seen_time, - total_data_length, - count_per_frame_data, - ) - else: - raise ArmisException( - "Armis Device Connector: There are no proper keys in data." - ) + return self.process_successful_data(results) elif response.status_code == 400: logging.error( @@ -202,7 +240,7 @@ def _get_device_data(self, armis_link_suffix, parameter): HTTP_ERRORS[401] ) ) - self._get_access_token_device("/access_token/") + self.compare_access_token() continue else: raise ArmisException( @@ -231,8 +269,7 @@ def _get_device_data(self, armis_link_suffix, parameter): "Armis Device Connector: Error while getting data from device api." ) - except ArmisDataNotFoundException as err: - logging.info(err) + except ArmisDataNotFoundException: raise ArmisDataNotFoundException() def _fetch_device_data( @@ -256,7 +293,14 @@ def _fetch_device_data( else: aql_data = "in:devices after:{}".format(last_time) logging.info("Armis Device Connector: aql query: " + aql_data) - self._get_access_token_device("/access_token/") + self.keyvault_obj = KeyVaultSecretManager() + self.access_token_key = "armis-access-token" + properties_list = self.keyvault_obj.get_properties_list_of_secrets() + if self.access_token_key in properties_list: + self.access_token = self.keyvault_obj.get_keyvault_secret(self.access_token_key) + self._header.update({"Authorization": self.access_token}) + else: + self._get_access_token_device("/access_token/") azuresentinel = AzureSentinel() parameter_device = { diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/keyvault_secrets_management.py b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/keyvault_secrets_management.py new file mode 100644 index 00000000000..465012fb0f6 --- /dev/null +++ b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDeviceSentinelConnector/keyvault_secrets_management.py @@ -0,0 +1,66 @@ +"""This file is used for accessing keyvault to get or set secrets.""" +import os +import logging +from azure.keyvault.secrets import SecretClient +from azure.identity import DefaultAzureCredential +from azure.core.exceptions import ResourceNotFoundError + +KEYVAULT_NAME = os.environ.get("KeyVaultName", "") + + +class KeyVaultSecretManager: + """This class contains methods to authenticate with Azure KeyVault and get or set secrets in keyvault.""" + + def __init__(self) -> None: + """Intialize instance variables for class.""" + self.keyvault_name = KEYVAULT_NAME + self.keyvault_uri = "https://{}.vault.azure.net/".format(self.keyvault_name) + self.client = self.get_client() + + def get_client(self): + """To obtain AzureKeyVault client. + + Returns: + SecretClient: returns client object for accessing AzureKeyVault. + """ + credential = DefaultAzureCredential() + client = SecretClient(vault_url=self.keyvault_uri, credential=credential) + return client + + def get_keyvault_secret(self, secret_name): + """To get value of provided secretname from AzureKeyVault. + + Args: + secret_name (str): secret name to get its value. + """ + try: + logging.info("Retrieving secret {} from {}.".format(secret_name, self.keyvault_name)) + retrieved_secret = self.client.get_secret(secret_name) + logging.info("Retrieved secret value for {}.".format(retrieved_secret.name)) + return retrieved_secret.value + + except ResourceNotFoundError as err: + logging.error("Resource not found : '{}' ".format(err)) + self.set_keyvault_secret(secret_name, "") + return "" + + def set_keyvault_secret(self, secret_name, secret_value): + """To update secret value of given secret name or create new secret. + + Args: + secret_name (str): secret name to update its value or create it. + secret_value (str): secret value to be set as value of given secret name. + """ + logging.info("Creating or updating a secret '{}'.".format(secret_name)) + self.client.set_secret(secret_name, secret_value) + logging.info("Secret created successfully : '{}' .".format(secret_name)) + + def get_properties_list_of_secrets(self): + """To get list of secrets stored in keyvault with its properties. + + Returns: + list: _description_ + """ + secret_properties = self.client.list_properties_of_secrets() + properties_list = [secret_property.name for secret_property in secret_properties] + return properties_list diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDevice_API_FunctionApp.json b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDevice_API_FunctionApp.json index 5370fbdfbb0..e21279e55de 100644 --- a/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDevice_API_FunctionApp.json +++ b/Solutions/Armis/Data Connectors/ArmisDevice/ArmisDevice_API_FunctionApp.json @@ -85,7 +85,27 @@ }, { "title": "", - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "title": "", + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Device Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "title": "", + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "title": "", + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "title": "", + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "title": "", + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [{ "parameters": { "fillWith": [ @@ -108,7 +128,7 @@ }, { "title": "Option 1 - Azure Resource Manager (ARM) Template", - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy." + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy." }, { "title": "Option 2 - Manual Deployment of Azure Functions", @@ -116,11 +136,11 @@ }, { "title": "", - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { "title": "", - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ] } \ No newline at end of file diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/azuredeploy_Connector_ArmisDeviceAPI_AzureFunction.json b/Solutions/Armis/Data Connectors/ArmisDevice/azuredeploy_Connector_ArmisDeviceAPI_AzureFunction.json index 0c48580a92a..abd4817a337 100644 --- a/Solutions/Armis/Data Connectors/ArmisDevice/azuredeploy_Connector_ArmisDeviceAPI_AzureFunction.json +++ b/Solutions/Armis/Data Connectors/ArmisDevice/azuredeploy_Connector_ArmisDeviceAPI_AzureFunction.json @@ -48,6 +48,33 @@ "description": "Enter a valid Quartz Cron-Expression (Example: 0 0 0 * * *)" } }, + "KeyVaultName": { + "type": "string", + "metadata": { + "description": "Enter name of keyvault where access token will be stored (Note: Use the previously created key vault name specific to above API key within the Azure workspace)" + } + }, + "AzureClientId": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Enter Azure Client Id that you have created during app registration" + } + }, + "AzureClientSecret": { + "type": "securestring", + "minLength": 1, + "metadata": { + "description": "Enter Azure Client Secret that you have created during creating the client secret" + } + }, + "TenantId":{ + "type": "string", + "minLength": 1, + "metadata": { + "description": "Enter Tenant Id of your Microsoft Entra Id" + } + }, "AppInsightsWorkspaceResourceID": { "type": "string", "metadata": { @@ -188,7 +215,11 @@ "ArmisURL": "[parameters('ArmisBaseURL')]", "ArmisDeviceTableName": "[parameters('ArmisDeviceTableName')]", "Schedule": "[parameters('ArmisSchedule')]", - "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-ArmisDevice-functionapp" + "KeyVaultName": "[parameters('KeyvaultName')]", + "AZURE_CLIENT_ID": "[parameters('AzureClientId')]", + "AZURE_CLIENT_SECRET": "[parameters('AzureClientSecret')]", + "AZURE_TENANT_ID": "[parameters('TenantId')]", + "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-ArmisDevice311-functionapp" } } ] diff --git a/Solutions/Armis/Data Connectors/ArmisDevice/requirements.txt b/Solutions/Armis/Data Connectors/ArmisDevice/requirements.txt index 52584d6099a..306cc61b236 100644 --- a/Solutions/Armis/Data Connectors/ArmisDevice/requirements.txt +++ b/Solutions/Armis/Data Connectors/ArmisDevice/requirements.txt @@ -6,3 +6,5 @@ azure-functions azure-storage-file-share==12.3.0 requests azure-data-tables==12.1.0 +azure-keyvault-secrets +azure-identity diff --git a/Solutions/Armis/Data/Solution_Armis.json b/Solutions/Armis/Data/Solution_Armis.json index b0d4aa04ea5..03242b06a59 100644 --- a/Solutions/Armis/Data/Solution_Armis.json +++ b/Solutions/Armis/Data/Solution_Armis.json @@ -16,7 +16,7 @@ "Playbooks/ArmisUpdateAlertStatus/azuredeploy.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Armis", - "Version": "3.1.0", + "Version": "3.1.1", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1PConnector": false diff --git a/Solutions/Armis/Package/3.1.1.zip b/Solutions/Armis/Package/3.1.1.zip new file mode 100644 index 00000000000..2fcc1a51f21 Binary files /dev/null and b/Solutions/Armis/Package/3.1.1.zip differ diff --git a/Solutions/Armis/Package/createUiDefinition.json b/Solutions/Armis/Package/createUiDefinition.json index ed83acd51b6..cd3cf342081 100644 --- a/Solutions/Armis/Package/createUiDefinition.json +++ b/Solutions/Armis/Package/createUiDefinition.json @@ -63,6 +63,13 @@ "text": "This Solution installs the data connector for Armis. You can get Armis custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." } }, + { + "name": "dataconnectors2-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Solution installs the data connector for Armis. You can get Armis custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + } + }, { "name": "dataconnectors-parser-text", "type": "Microsoft.Common.TextBlock", diff --git a/Solutions/Armis/Package/mainTemplate.json b/Solutions/Armis/Package/mainTemplate.json index 250b5582ca0..ef0010eff2e 100644 --- a/Solutions/Armis/Package/mainTemplate.json +++ b/Solutions/Armis/Package/mainTemplate.json @@ -33,7 +33,7 @@ "email": "support@armis.com}", "_email": "[variables('email')]", "_solutionName": "Armis", - "_solutionVersion": "3.1.0", + "_solutionVersion": "3.1.1", "solutionId": "armisinc1668090987837.armis-solution", "_solutionId": "[variables('solutionId')]", "parserObject1": { @@ -97,7 +97,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ArmisActivities Data Parser with template version 3.1.0", + "description": "ArmisActivities Data Parser with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject1').parserVersion1]", @@ -229,7 +229,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ArmisDevice Data Parser with template version 3.1.0", + "description": "ArmisDevice Data Parser with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject2').parserVersion2]", @@ -361,7 +361,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ArmisAlerts Data Parser with template version 3.1.0", + "description": "ArmisAlerts Data Parser with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject3').parserVersion3]", @@ -493,7 +493,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Armis data connector with template version 3.1.0", + "description": "Armis data connector with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -611,7 +611,22 @@ "description": "**STEP 1 - Configuration steps for the Armis API**\n\n Follow these instructions to create an Armis API secret key.\n 1. Log into your Armis instance\n 2. Navigate to Settings -> API Management\n 3. If the secret key has not already been created, press the Create button to create the secret key\n 4. To access the secret key, press the Show button\n 5. The secret key can now be copied and used during the Armis Alerts Activities connector configuration" }, { - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Alerts Activities Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [ { "parameters": { @@ -634,7 +649,7 @@ ] }, { - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", "title": "Option 1 - Azure Resource Manager (ARM) Template" }, { @@ -642,10 +657,10 @@ "title": "Option 2 - Manual Deployment of Azure Functions" }, { - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ] } @@ -831,7 +846,22 @@ "description": "**STEP 1 - Configuration steps for the Armis API**\n\n Follow these instructions to create an Armis API secret key.\n 1. Log into your Armis instance\n 2. Navigate to Settings -> API Management\n 3. If the secret key has not already been created, press the Create button to create the secret key\n 4. To access the secret key, press the Show button\n 5. The secret key can now be copied and used during the Armis Alerts Activities connector configuration" }, { - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Alerts Activities Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Alerts Activities Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Alerts Activities data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [ { "parameters": { @@ -854,7 +884,7 @@ ] }, { - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", "title": "Option 1 - Azure Resource Manager (ARM) Template" }, { @@ -862,10 +892,10 @@ "title": "Option 2 - Manual Deployment of Azure Functions" }, { - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisAlertsActivitiesAPI311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Alert Table Name \n\t\tArmis Activity Table Name \n\t\tSeverity (Default: Low) \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ], "id": "[variables('_uiConfigId1')]", @@ -882,7 +912,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Armis data connector with template version 3.1.0", + "description": "Armis data connector with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion2')]", @@ -981,7 +1011,22 @@ "description": "**STEP 1 - Configuration steps for the Armis API**\n\n Follow these instructions to create an Armis API secret key.\n 1. Log into your Armis instance\n 2. Navigate to Settings -> API Management\n 3. If the secret key has not already been created, press the Create button to create the secret key\n 4. To access the secret key, press the Show button\n 5. The secret key can now be copied and used during the Armis Device connector configuration" }, { - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Device Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [ { "parameters": { @@ -1004,7 +1049,7 @@ ] }, { - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", "title": "Option 1 - Azure Resource Manager (ARM) Template" }, { @@ -1012,10 +1057,10 @@ "title": "Option 2 - Manual Deployment of Azure Functions" }, { - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ] } @@ -1182,7 +1227,22 @@ "description": "**STEP 1 - Configuration steps for the Armis API**\n\n Follow these instructions to create an Armis API secret key.\n 1. Log into your Armis instance\n 2. Navigate to Settings -> API Management\n 3. If the secret key has not already been created, press the Create button to create the secret key\n 4. To access the secret key, press the Show button\n 5. The secret key can now be copied and used during the Armis Device connector configuration" }, { - "description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", + "description": "**STEP 2 - App Registration steps for the Application in Microsoft Entra ID**\n\n This integration requires an App registration in the Azure portal. Follow the steps in this section to create a new application in Microsoft Entra ID:\n 1. Sign in to the [Azure portal](https://portal.azure.com/).\n 2. Search for and select **Microsoft Entra ID**.\n 3. Under **Manage**, select **App registrations > New registration**.\n 4. Enter a display **Name** for your application.\n 5. Select **Register** to complete the initial app registration.\n 6. When registration finishes, the Azure portal displays the app registration's Overview pane. You see the **Application (client) ID** and **Tenant ID**. The client ID and Tenant ID is required as configuration parameters for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)" + }, + { + "description": "**STEP 3 - Add a client secret for application in Microsoft Entra ID**\n\n Sometimes called an application password, a client secret is a string value required for the execution of Armis Device Data Connector. Follow the steps in this section to create a new Client Secret:\n 1. In the Azure portal, in **App registrations**, select your application.\n 2. Select **Certificates & secrets > Client secrets > New client secret**.\n 3. Add a description for your client secret.\n 4. Select an expiration for the secret or specify a custom lifetime. Limit is 24 months.\n 5. Select **Add**. \n 6. *Record the secret's value for use in your client application code. This secret value is never displayed again after you leave this page.* The secret value is required as configuration parameter for the execution of Armis Device Data Connector. \n\n> **Reference link:** [https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret)" + }, + { + "description": "**STEP 4 - Assign role of Contributor to application in Microsoft Entra ID**\n\n Follow the steps in this section to assign the role:\n 1. In the Azure portal, Go to **Resource Group** and select your resource group.\n 2. Go to **Access control (IAM)** from left panel.\n 3. Click on **Add**, and then select **Add role assignment**.\n 4. Select **Contributor** as role and click on next.\n 5. In **Assign access to**, select `User, group, or service principal`.\n 6. Click on **add members** and type **your app name** that you have created and select it.\n 7. Now click on **Review + assign** and then again click on **Review + assign**. \n\n> **Reference link:** [https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal)" + }, + { + "description": "**STEP 5 - Create a Keyvault**\n\n Follow these instructions to create a new Keyvault.\n 1. In the Azure portal, Go to **Key vaults**. Click create.\n 2. Select Subsciption, Resource Group and provide unique name of keyvault.\n\n> **NOTE:** Create a separate key vault for each **API key** within one workspace." + }, + { + "description": "**STEP 6 - Create Access Policy in Keyvault**\n\n Follow these instructions to create access policy in Keyvault.\n 1. Go to keyvaults, select your keyvault, go to Access policies on left side panel. Click create.\n 2. Select all keys & secrets permissions. Click next.\n 3. In the principal section, search by application name which was generated in STEP - 2. Click next.\n\n> **NOTE:** Ensure the Permission model in the Access Configuration of Key Vault is set to **'Vault access policy'**" + }, + { + "description": "**STEP 7 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Armis Device data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following) readily available.., as well as the Armis API Authorization Key(s)", "instructions": [ { "parameters": { @@ -1205,7 +1265,7 @@ ] }, { - "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", + "description": "Use this method for automated deployment of the Armis connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://aka.ms/sentinel-ArmisDevice-azuredeploy-gov)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tFunction Name \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.", "title": "Option 1 - Azure Resource Manager (ARM) Template" }, { @@ -1213,10 +1273,10 @@ "title": "Option 2 - Manual Deployment of Azure Functions" }, { - "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." + "description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-ArmisDevice311-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. ARMISXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.11\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Microsoft Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration." }, { - "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tAvoid Duplicates (Default: true) \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." + "description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective values (case-sensitive): \n\t\tWorkspace ID \n\t\tWorkspace Key \n\t\tArmis Secret Key \n\t\tArmis URL (https://.armis.com/api/v1/) \n\t\tArmis Device Table Name \n\t\tArmis Schedule \n\t\tKeyVault Name \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tTenant Id \n\t\tlogAnalyticsUri (optional) \n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://.ods.opinsights.azure.us`.\n4. Once all application settings have been entered, click **Save**." } ], "id": "[variables('_uiConfigId2')]", @@ -1233,7 +1293,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ArmisUpdateAlertStatus Playbook with template version 3.1.0", + "description": "ArmisUpdateAlertStatus Playbook with template version 3.1.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('playbookVersion1')]", @@ -1797,7 +1857,7 @@ "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.1.0", + "version": "3.1.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "Armis", diff --git a/Solutions/Armis/ReleaseNotes.md b/Solutions/Armis/ReleaseNotes.md index c3420f3ca65..2d12db5a7b6 100644 --- a/Solutions/Armis/ReleaseNotes.md +++ b/Solutions/Armis/ReleaseNotes.md @@ -1,5 +1,6 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|---------------------------------------------| +| 3.1.1 | 19-05-2025 | Updated Armis AlertActivity and Armis Device Data connectors to add keyvault for storing Armis Access Token and Severity parameter in AlertActivity.| | 3.1.0 | 11-09-2024 | Updated Armis Alerts Data connector to ingest Armis Activities associated with only Armis Alerts.| | 3.0.3 | 26-08-2024 | Updated the python runtime version to **3.11**| | 3.0.2 | 03-05-2024 | Repackaged for parser issue fix on reinstall|