{
    "id": "InfobloxDataConnector",
    "title": "Infoblox Data Connector via REST API",
    "publisher": "Infoblox",
    "descriptionMarkdown": "The Infoblox Data Connector allows you to easily connect your Infoblox TIDE data and Dossier data with Microsoft Sentinel. By connecting your data to Microsoft Sentinel, you can take advantage of search & correlation, alerting, and threat intelligence enrichment for each log.",
    "graphQueries": [
        {
            "metricName": "Dossier whois source data received",
            "legend": "dossier_whois",
            "baseQuery": "dossier_whois_CL"
        },
        {
            "metricName": "Dossier whitelist source data received",
            "legend": "dossier_whitelist",
            "baseQuery": "dossier_whitelist_CL"
        },
        {
            "metricName": "Dossier tld risk source data received",
            "legend": "dossier_tld_risk",
            "baseQuery": "dossier_tld_risk_CL"
        },
        {
            "metricName": "Dossier threat actor source data received",
            "legend": "dossier_threat_actor",
            "baseQuery": "dossier_threat_actor_CL"
        },
        {
            "metricName": "Dossier rpz feeds records source data received",
            "legend": "dossier_rpz_feeds_records",
            "baseQuery": "dossier_rpz_feeds_records_CL"
        },
        {
            "metricName": "Dossier rpz feeds source data received",
            "legend": "dossier_rpz_feeds",
            "baseQuery": "dossier_rpz_feeds_CL"
        },
        {
            "metricName": "Dossier nameserver matches source data received",
            "legend": "dossier_nameserver_matches",
            "baseQuery": "dossier_nameserver_matches_CL"
        },
        {
            "metricName": "Dossier nameserver source data received",
            "legend": "dossier_nameserver",
            "baseQuery": "dossier_nameserver_CL"
        },
        {
            "metricName": "Dossier malware analysis v3 source data received",
            "legend": "dossier_malware_analysis_v3",
            "baseQuery": "dossier_malware_analysis_v3_CL"
        },
        {
            "metricName": "Dossier inforank source data received",
            "legend": "dossier_inforank",
            "baseQuery": "dossier_inforank_CL"
        },
        {
            "metricName": "Dossier infoblox web cat source data received",
            "legend": "dossier_infoblox_web_cat",
            "baseQuery": "dossier_infoblox_web_cat_CL"
        },
        {
            "metricName": "Dossier geo source data received",
            "legend": "dossier_geo",
            "baseQuery": "dossier_geo_CL"
        },
        {
            "metricName": "Dossier dns source data received",
            "legend": "dossier_dns",
            "baseQuery": "dossier_dns_CL"
        },
        {
            "metricName": "Dossier atp threat source data received",
            "legend": "dossier_atp_threat",
            "baseQuery": "dossier_atp_threat_CL"
        },
        {
            "metricName": "Dossier atp source data received",
            "legend": "dossier_atp",
            "baseQuery": "dossier_atp_CL"
        },
        {
            "metricName": "Dossier ptr source data received",
            "legend": "dossier_ptr",
            "baseQuery": "dossier_ptr_CL"
        }
    ],
    "sampleQueries": [
        {
            "description": "Dossier whois data source",
            "query": "dossier_whois_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier whitelist data source",
            "query": "dossier_whitelist_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier tld risk data source",
            "query": "dossier_tld_risk_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier threat actor data source",
            "query": "dossier_threat_actor_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier rpz feeds records data source",
            "query": "dossier_rpz_feeds_records_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier rpz feeds data source",
            "query": "dossier_rpz_feeds_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier nameserver matches data source",
            "query": "dossier_nameserver_matches_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier nameserver data source",
            "query": "dossier_nameserver_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier malware analysis v3 data source",
            "query": "dossier_malware_analysis_v3_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier inforank data source",
            "query": "dossier_inforank_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier infoblox web cat data source",
            "query": "dossier_infoblox_web_cat_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier geo data source",
            "query": "dossier_geo_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier dns data source",
            "query": "dossier_dns_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier atp threat data source",
            "query": "dossier_atp_threat_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier atp data source",
            "query": "dossier_atp_CL\n | sort by TimeGenerated desc"
        },
        {
            "description": "Dossier ptr data source",
            "query": "dossier_ptr_CL\n | sort by TimeGenerated desc"
        }
    ],
    "dataTypes": [
        {
            "name": "dossier_whois_CL",
            "lastDataReceivedQuery": "dossier_whois_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_whitelist_CL",
            "lastDataReceivedQuery": "dossier_whitelist_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_tld_risk_CL",
            "lastDataReceivedQuery": "dossier_tld_risk_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_threat_actor_CL",
            "lastDataReceivedQuery": "dossier_threat_actor_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_rpz_feeds_records_CL",
            "lastDataReceivedQuery": "dossier_rpz_feeds_records_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_rpz_feeds_CL",
            "lastDataReceivedQuery": "dossier_rpz_feeds_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_nameserver_matches_CL",
            "lastDataReceivedQuery": "dossier_nameserver_matches_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_nameserver_CL",
            "lastDataReceivedQuery": "dossier_nameserver_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_malware_analysis_v3_CL",
            "lastDataReceivedQuery": "dossier_malware_analysis_v3_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_inforank_CL",
            "lastDataReceivedQuery": "dossier_inforank_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_infoblox_web_cat_CL",
            "lastDataReceivedQuery": "dossier_infoblox_web_cat_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_geo_CL",
            "lastDataReceivedQuery": "dossier_geo_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_dns_CL",
            "lastDataReceivedQuery": "dossier_dns_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_atp_threat_CL",
            "lastDataReceivedQuery": "dossier_atp_threat_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_atp_CL",
            "lastDataReceivedQuery": "dossier_atp_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        },
        {
            "name": "dossier_ptr_CL",
            "lastDataReceivedQuery": "dossier_ptr_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        }
    ],
    "connectivityCriterias": [
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_whois_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_whitelist_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_tld_risk_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_threat_actor_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_rpz_feeds_records_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_rpz_feeds_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_nameserver_matches_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_nameserver_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_malware_analysis_v3_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_inforank_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_infoblox_web_cat_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_geo_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_dns_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_atp_threat_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_atp_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        },
        {
            "type": "IsConnectedQuery",
            "value": [
                "dossier_ptr_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(3d)"
            ]
        }
    ],
    "availability": {
        "status": 1,
        "isPreview": true
    },
    "permissions": {
        "resourceProvider": [
            {
                "provider": "Microsoft.OperationalInsights/workspaces",
                "permissionsDisplayText": "read and write permissions on the workspace are required.",
                "providerDisplayName": "Workspace",
                "scope": "Workspace",
                "requiredPermissions": {
                    "write": true,
                    "read": true,
                    "delete": true
                }
            },
            {
                "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
                "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
                "providerDisplayName": "Keys",
                "scope": "Workspace",
                "requiredPermissions": {
                    "action": true
                }
            }
        ],
        "customs": [
            {
                "name": "Azure Subscription",
                "description": "Azure Subscription with owner role is required to register an application in Microsoft Entra ID and assign role of contributor to app in resource group."
            },
            {
                "name": "Microsoft.Web/sites permissions",
                "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
            },
            {
                "name": "REST API Credentials/permissions",
                "description": "**Infoblox API Key** is required.  See the documentation to learn more about API on the [Rest API reference](https://csp.infoblox.com/apidoc?url=https://csp.infoblox.com/apidoc/docs/Infrastructure#/Services/ServicesRead)"
            }
        ]
    },
    "instructionSteps": [
        {
            "title": "",
            "description": ">**NOTE:** This connector uses Azure Functions to connect to the Infoblox API to create Threat Indicators for TIDE and pull Dossier data into Microsoft Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
        },
        {
            "title": "",
            "description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
        },
        {
            "title": "",
            "description": "**STEP 1 - 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 are required as the **AzureClientId** and **AzureTenantId** configuration parameters, used by the connector's Function Apps to authenticate to the Log Ingestion API (for Dossier data) and to the Microsoft Sentinel Threat Intelligence Indicators API (for TIDE data). \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 2 - 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 by the connector to authenticate to the Log Ingestion API and the Microsoft Sentinel Threat Intelligence Indicators API. 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 the **AzureClientSecret** configuration parameter. \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 3 - Assign role of Contributor to application in Microsoft Entra ID**\n\n This role is required so the connector's Function Apps can create Threat Intelligence Indicators from TIDE data via the Microsoft Sentinel Threat Intelligence Indicators API. 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 4 - Find the Object ID of the app registration**\n\n This connector ingests Dossier and TIDE data into Sentinel via the Log Ingestion API, which requires the app registration (the same one created in Step 1) to have the **Monitoring Metrics Publisher** role on every Data Collection Rule the connector creates. This role assignment is granted **automatically** by the ARM template at deployment time - you do not need to assign it by hand - but the template needs the app's **Object ID** (the Enterprise Application / Service Principal object ID, not the Application/Client ID) as a deployment parameter to do so.\n\n 1. In the Azure portal, search for and select **Microsoft Entra ID**.\n 2. Under **Manage**, select **Enterprise applications**.\n 3. Search for the app registration you created in Step 1 and select it.\n 4. Copy the **Object ID** shown on the Overview pane - this is the value to enter as **AzureEntraObjectID** during deployment.\n\n> **Note:** If this value is missing or incorrect at deployment time, the role assignment silently fails to grant access and Dossier/TIDE data will not appear in the workspace, even though the Function Apps run without error."
        },
        {
            "title": "",
            "description": "**STEP 5 - Steps to generate the Infoblox API Credentials**\n\n Follow these instructions to generate Infoblox API Key.\n In the [Infoblox Cloud Services Portal](https://csp.infoblox.com/atlas/app/welcome), generate an API Key and copy it somewhere safe to use in the next step. You can find instructions on how to create API keys [**here**](https://docs.infoblox.com/space/BloxOneThreatDefense/230394187/How+Do+I+Create+an+API+Key%3F)."
        },
        {
            "title": "Azure Resource Manager (ARM) Template",
            "description": "Use this method for automated deployment of the Infoblox Data connector.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-infoblox-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the below information : \n\t\tWorkspace ID \n\t\tWorkspace (Log Analytics workspace resource name) \n\t\tData Collection Endpoint/Rule Location (Default: Resource Group location, must match the workspace region) \n\t\tAzure Tenant Id \n\t\tAzure Client Id \n\t\tAzure Client Secret \n\t\tAzure Entra Object ID (from Step 4) \n\t\tInfoblox API Token \n\t\tInfoblox Base URL \n\t\tHistorical Data Cutoff Date \n\t\tLog Level (Default: Info) \n\t\tConfidence (Default: 80) \n\t\tThreat Level (Default: 80) \n\t\tApp Insights Workspace Resource ID \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy.\n\n> **Note:** The Data Collection Endpoint/Data Collection Rules and the Monitoring Metrics Publisher role assignment on them are created and wired up automatically by this template - no manual DCR or role-assignment steps are required after deployment."
        }
    ]
}