{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "author": "XBOW - support@xbow.com", "comments": "Solution template for XBOW" }, "parameters": { "location": { "type": "string", "minLength": 1, "defaultValue": "[resourceGroup().location]", "metadata": { "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" } }, "workspace-location": { "type": "string", "defaultValue": "", "metadata": { "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" } }, "workspace": { "defaultValue": "", "type": "string", "metadata": { "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" } } }, "variables": { "email": "support@xbow.com", "_email": "[variables('email')]", "_solutionName": "XBOW", "_solutionVersion": "3.0.1", "solutionId": "xbowinc.xbow-sentinel-connector", "_solutionId": "[variables('solutionId')]", "uiConfigId1": "XbowSecurityConnector", "_uiConfigId1": "[variables('uiConfigId1')]", "dataConnectorContentId1": "XbowSecurityConnector", "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", "_dataConnectorId1": "[variables('dataConnectorId1')]", "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", "dataConnectorVersion1": "1.0.0", "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", "analyticRuleObject1": { "analyticRuleVersion1": "1.0.1", "_analyticRulecontentId1": "f8e7d6c5-4b3a-4912-8f0e-2d1c3b4a5678", "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'f8e7d6c5-4b3a-4912-8f0e-2d1c3b4a5678')]", "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('f8e7d6c5-4b3a-4912-8f0e-2d1c3b4a5678')))]", "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','f8e7d6c5-4b3a-4912-8f0e-2d1c3b4a5678','-', '1.0.1')))]" }, "analyticRuleObject2": { "analyticRuleVersion2": "1.0.1", "_analyticRulecontentId2": "b3c5e2f9-6a8d-4127-9b2e-4f6a8c9d0e12", "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'b3c5e2f9-6a8d-4127-9b2e-4f6a8c9d0e12')]", "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('b3c5e2f9-6a8d-4127-9b2e-4f6a8c9d0e12')))]", "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','b3c5e2f9-6a8d-4127-9b2e-4f6a8c9d0e12','-', '1.0.1')))]" }, "analyticRuleObject3": { "analyticRuleVersion3": "1.0.1", "_analyticRulecontentId3": "d2e4f1a8-7c9b-4356-8e0d-5a2b7c8e9f01", "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'd2e4f1a8-7c9b-4356-8e0d-5a2b7c8e9f01')]", "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('d2e4f1a8-7c9b-4356-8e0d-5a2b7c8e9f01')))]", "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','d2e4f1a8-7c9b-4356-8e0d-5a2b7c8e9f01','-', '1.0.1')))]" }, "analyticRuleObject4": { "analyticRuleVersion4": "1.0.1", "_analyticRulecontentId4": "e4c6a8b2-9d7f-4285-a1e3-6b9c2e4f1a85", "analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'e4c6a8b2-9d7f-4285-a1e3-6b9c2e4f1a85')]", "analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('e4c6a8b2-9d7f-4285-a1e3-6b9c2e4f1a85')))]", "_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','e4c6a8b2-9d7f-4285-a1e3-6b9c2e4f1a85','-', '1.0.1')))]" }, "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" }, "resources": [ { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", "name": "[variables('dataConnectorTemplateSpecName1')]", "location": "[parameters('workspace-location')]", "dependsOn": [ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { "description": "XBOW data connector with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", "parameters": {}, "variables": {}, "resources": [ { "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", "apiVersion": "2021-03-01-preview", "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", "location": "[parameters('workspace-location')]", "kind": "GenericUI", "properties": { "connectorUiConfig": { "id": "[variables('_uiConfigId1')]", "title": "XBOW Security Platform (via Azure Function)", "publisher": "XBOW", "descriptionMarkdown": "The **XBOW** data connector ingests asset snapshots, vulnerability findings, and assessment activity from the [XBOW Security Platform](https://console.xbow.com) into Microsoft Sentinel. An Azure Function polls the XBOW API on a timer and pushes asset JSON snapshots into `XbowAssets_CL`, enriched findings (with evidence, PoC recipes, impact, and mitigations) into `XbowFindings_CL`, and assessment lifecycle events into `XbowAssessments_CL`, using the [Azure Monitor Ingestion API](https://learn.microsoft.com/azure/azure-monitor/logs/logs-ingestion-api-overview) (DCE/DCR).", "graphQueries": [ { "metricName": "XBOW Assets", "legend": "XbowAssets_CL", "baseQuery": "XbowAssets_CL" }, { "metricName": "XBOW Findings", "legend": "XbowFindings_CL", "baseQuery": "XbowFindings_CL" }, { "metricName": "XBOW Assessments", "legend": "XbowAssessments_CL", "baseQuery": "XbowAssessments_CL" } ], "sampleQueries": [ { "description": "Latest XBOW asset snapshots", "query": "XbowAssets_CL\n| summarize arg_max(TimeGenerated, *) by AssetId\n| project TimeGenerated, AssetName, Lifecycle, StartUrl, AssetReachableState\n| sort by TimeGenerated desc" }, { "description": "All XBOW findings, newest first", "query": "XbowFindings_CL\n| sort by TimeGenerated desc" }, { "description": "XBOW critical & high severity open findings", "query": "XbowFindings_CL\n| where State == \"open\" and Severity in (\"critical\", \"high\")\n| sort by TimeGenerated desc" }, { "description": "XBOW findings by severity", "query": "XbowFindings_CL\n| summarize Count = count() by Severity\n| sort by Count desc" }, { "description": "XBOW assessment activity", "query": "XbowAssessments_CL\n| sort by TimeGenerated desc" } ], "dataTypes": [ { "name": "XbowAssets_CL", "lastDataReceivedQuery": "XbowAssets_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { "name": "XbowFindings_CL", "lastDataReceivedQuery": "XbowFindings_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { "name": "XbowAssessments_CL", "lastDataReceivedQuery": "XbowAssessments_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ "XbowFindings_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(1d)" ] } ], "availability": { "status": 1, "isPreview": false }, "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": "XBOW API Token", "description": "A XBOW Personal Access Token is required. Generate one in the [XBOW console](https://console.xbow.com) under **Settings > Personal Access Tokens**. Scope the token to the organization you want to monitor." }, { "name": "XBOW Organization ID", "description": "The Organization ID from your XBOW account. Find it in the XBOW console URL or via the API." }, { "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": "Custom prerequisites if necessary, otherwise delete this customs tag", "description": "Description for any custom pre-requisites" }, { "name": "Azure AD App Registration", "description": "An Azure AD App Registration (service principal) is required. You must manually assign the **Monitoring Metrics Publisher** role on the Data Collection Rule (DCR) to this App Registration after deployment." } ] }, "instructionSteps": [ { "description": ">**NOTE:** This connector uses Azure Functions and the Azure Monitor Ingestion API (DCE/DCR) to ingest XBOW assets, findings, and assessments into Microsoft Sentinel. The ARM template automatically creates the Data Collection Endpoint, custom log tables (`XbowAssets_CL`, `XbowFindings_CL`, and `XbowAssessments_CL`), Data Collection Rule, and Function App. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) and [Azure Monitor pricing page](https://azure.microsoft.com/pricing/details/monitor/) for details." }, { "description": ">**(Optional Step)** Securely store your XBOW API Token and App Registration credentials in Azure Key Vault. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault references with an Azure Function App." }, { "description": "1. Log into the [XBOW console](https://console.xbow.com) with administrator access.\n2. Click your profile icon (top right) and select **Settings**.\n3. In the left sidebar, click **Personal Access Tokens**.\n4. Click **Generate new token**, provide a name, and select the organization scope.\n5. Copy and securely store your token — it will not be shown again.\n6. Note your **Organization ID** from the XBOW console or from the URL when viewing your organization.", "title": "STEP 1 – Generate a XBOW API Token" }, { "description": "1. In the [Azure Portal](https://portal.azure.com), navigate to **Azure Active Directory > App registrations > New registration**.\n2. Provide a name (e.g. `Xbow-Sentinel-Connector`) and register.\n3. Under **Certificates & secrets**, create a new client secret. Note the **Tenant ID**, **Client ID**, and **Client Secret**.\n4. Deploy the connector using Step 3 below, then return here.\n5. Open the deployed **Data Collection Rule** (from the deployment outputs or by searching in the resource group).\n6. Go to **Access control (IAM) > Add role assignment**.\n7. Select role **Monitoring Metrics Publisher**.\n8. Assign access to the App Registration (service principal) created above.\n9. Wait a few minutes for RBAC propagation before verifying ingestion.", "title": "STEP 2 – Create an Azure AD App Registration and Grant DCR Role" }, { "description": "Click **Deploy to Azure** and fill in the parameters. The template will automatically create the Data Collection Endpoint, `XbowAssets_CL`, `XbowFindings_CL`, and `XbowAssessments_CL` tables, Data Collection Rule, and Function App.\n\n[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-Xbow-azuredeploy)\n\n**Parameters to fill in:**\n\n| Parameter | Description |\n|---|---|\n| `WorkspaceName` | Name of your Log Analytics / Microsoft Sentinel workspace |\n| `XbowApiToken` | XBOW Personal Access Token from Step 1 |\n| `XbowOrgId` | XBOW Organization ID from Step 1 |\n| `TenantId` | Azure AD Tenant ID from Step 2 |\n| `ClientId` | App Registration Client ID from Step 2 |\n| `ClientSecret` | App Registration Client Secret from Step 2 |\n| `AppInsightsWorkspaceResourceID` | Full Resource ID of the Log Analytics workspace (from **Log Analytics workspace > Properties**) |\n| `FunctionAppLocation` | Optional Azure region for Function App resources (defaults to the Resource Group location) |", "instructions": [ { "parameters": { "fillWith": [ "WorkspaceId" ], "label": "Workspace ID" }, "type": "CopyableLabel" } ], "title": "STEP 3 – Deploy the Azure Function App" } ] } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2023-04-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", "properties": { "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", "contentId": "[variables('_dataConnectorContentId1')]", "kind": "DataConnector", "version": "[variables('dataConnectorVersion1')]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } } ] }, "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", "contentId": "[variables('_dataConnectorContentId1')]", "contentKind": "DataConnector", "displayName": "XBOW Security Platform (via Azure Function)", "contentProductId": "[variables('_dataConnectorcontentProductId1')]", "id": "[variables('_dataConnectorcontentProductId1')]", "version": "[variables('dataConnectorVersion1')]" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2023-04-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", "dependsOn": [ "[variables('_dataConnectorId1')]" ], "location": "[parameters('workspace-location')]", "properties": { "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", "contentId": "[variables('_dataConnectorContentId1')]", "kind": "DataConnector", "version": "[variables('dataConnectorVersion1')]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } }, { "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", "apiVersion": "2021-03-01-preview", "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", "location": "[parameters('workspace-location')]", "kind": "GenericUI", "properties": { "connectorUiConfig": { "title": "XBOW Security Platform (via Azure Function)", "publisher": "XBOW", "descriptionMarkdown": "The **XBOW** data connector ingests asset snapshots, vulnerability findings, and assessment activity from the [XBOW Security Platform](https://console.xbow.com) into Microsoft Sentinel. An Azure Function polls the XBOW API on a timer and pushes asset JSON snapshots into `XbowAssets_CL`, enriched findings (with evidence, PoC recipes, impact, and mitigations) into `XbowFindings_CL`, and assessment lifecycle events into `XbowAssessments_CL`, using the [Azure Monitor Ingestion API](https://learn.microsoft.com/azure/azure-monitor/logs/logs-ingestion-api-overview) (DCE/DCR).", "graphQueries": [ { "metricName": "XBOW Assets", "legend": "XbowAssets_CL", "baseQuery": "XbowAssets_CL" }, { "metricName": "XBOW Findings", "legend": "XbowFindings_CL", "baseQuery": "XbowFindings_CL" }, { "metricName": "XBOW Assessments", "legend": "XbowAssessments_CL", "baseQuery": "XbowAssessments_CL" } ], "dataTypes": [ { "name": "XbowAssets_CL", "lastDataReceivedQuery": "XbowAssets_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { "name": "XbowFindings_CL", "lastDataReceivedQuery": "XbowFindings_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { "name": "XbowAssessments_CL", "lastDataReceivedQuery": "XbowAssessments_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" } ], "connectivityCriterias": [ { "type": "IsConnectedQuery", "value": [ "XbowFindings_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(1d)" ] } ], "sampleQueries": [ { "description": "Latest XBOW asset snapshots", "query": "XbowAssets_CL\n| summarize arg_max(TimeGenerated, *) by AssetId\n| project TimeGenerated, AssetName, Lifecycle, StartUrl, AssetReachableState\n| sort by TimeGenerated desc" }, { "description": "All XBOW findings, newest first", "query": "XbowFindings_CL\n| sort by TimeGenerated desc" }, { "description": "XBOW critical & high severity open findings", "query": "XbowFindings_CL\n| where State == \"open\" and Severity in (\"critical\", \"high\")\n| sort by TimeGenerated desc" }, { "description": "XBOW findings by severity", "query": "XbowFindings_CL\n| summarize Count = count() by Severity\n| sort by Count desc" }, { "description": "XBOW assessment activity", "query": "XbowAssessments_CL\n| sort by TimeGenerated desc" } ], "availability": { "status": 1, "isPreview": false }, "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": "XBOW API Token", "description": "A XBOW Personal Access Token is required. Generate one in the [XBOW console](https://console.xbow.com) under **Settings > Personal Access Tokens**. Scope the token to the organization you want to monitor." }, { "name": "XBOW Organization ID", "description": "The Organization ID from your XBOW account. Find it in the XBOW console URL or via the API." }, { "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": "Custom prerequisites if necessary, otherwise delete this customs tag", "description": "Description for any custom pre-requisites" }, { "name": "Azure AD App Registration", "description": "An Azure AD App Registration (service principal) is required. You must manually assign the **Monitoring Metrics Publisher** role on the Data Collection Rule (DCR) to this App Registration after deployment." } ] }, "instructionSteps": [ { "description": ">**NOTE:** This connector uses Azure Functions and the Azure Monitor Ingestion API (DCE/DCR) to ingest XBOW assets, findings, and assessments into Microsoft Sentinel. The ARM template automatically creates the Data Collection Endpoint, custom log tables (`XbowAssets_CL`, `XbowFindings_CL`, and `XbowAssessments_CL`), Data Collection Rule, and Function App. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) and [Azure Monitor pricing page](https://azure.microsoft.com/pricing/details/monitor/) for details." }, { "description": ">**(Optional Step)** Securely store your XBOW API Token and App Registration credentials in Azure Key Vault. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault references with an Azure Function App." }, { "description": "1. Log into the [XBOW console](https://console.xbow.com) with administrator access.\n2. Click your profile icon (top right) and select **Settings**.\n3. In the left sidebar, click **Personal Access Tokens**.\n4. Click **Generate new token**, provide a name, and select the organization scope.\n5. Copy and securely store your token — it will not be shown again.\n6. Note your **Organization ID** from the XBOW console or from the URL when viewing your organization.", "title": "STEP 1 – Generate a XBOW API Token" }, { "description": "1. In the [Azure Portal](https://portal.azure.com), navigate to **Azure Active Directory > App registrations > New registration**.\n2. Provide a name (e.g. `Xbow-Sentinel-Connector`) and register.\n3. Under **Certificates & secrets**, create a new client secret. Note the **Tenant ID**, **Client ID**, and **Client Secret**.\n4. Deploy the connector using Step 3 below, then return here.\n5. Open the deployed **Data Collection Rule** (from the deployment outputs or by searching in the resource group).\n6. Go to **Access control (IAM) > Add role assignment**.\n7. Select role **Monitoring Metrics Publisher**.\n8. Assign access to the App Registration (service principal) created above.\n9. Wait a few minutes for RBAC propagation before verifying ingestion.", "title": "STEP 2 – Create an Azure AD App Registration and Grant DCR Role" }, { "description": "Click **Deploy to Azure** and fill in the parameters. The template will automatically create the Data Collection Endpoint, `XbowAssets_CL`, `XbowFindings_CL`, and `XbowAssessments_CL` tables, Data Collection Rule, and Function App.\n\n[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-Xbow-azuredeploy)\n\n**Parameters to fill in:**\n\n| Parameter | Description |\n|---|---|\n| `WorkspaceName` | Name of your Log Analytics / Microsoft Sentinel workspace |\n| `XbowApiToken` | XBOW Personal Access Token from Step 1 |\n| `XbowOrgId` | XBOW Organization ID from Step 1 |\n| `TenantId` | Azure AD Tenant ID from Step 2 |\n| `ClientId` | App Registration Client ID from Step 2 |\n| `ClientSecret` | App Registration Client Secret from Step 2 |\n| `AppInsightsWorkspaceResourceID` | Full Resource ID of the Log Analytics workspace (from **Log Analytics workspace > Properties**) |\n| `FunctionAppLocation` | Optional Azure region for Function App resources (defaults to the Resource Group location) |", "instructions": [ { "parameters": { "fillWith": [ "WorkspaceId" ], "label": "Workspace ID" }, "type": "CopyableLabel" } ], "title": "STEP 3 – Deploy the Azure Function App" } ], "id": "[variables('_uiConfigId1')]" } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]", "location": "[parameters('workspace-location')]", "dependsOn": [ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { "description": "XbowCriticalHighFindings_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", "parameters": {}, "variables": {}, "resources": [ { "type": "Microsoft.SecurityInsights/AlertRuleTemplates", "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "apiVersion": "2023-02-01-preview", "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { "description": "Creates an incident for each Critical or High severity finding reported by XBOW that\nis currently in an open state. These findings represent the most severe security issues\nand require immediate attention. Each alert is deduplicated per finding so re-ingestion\nof the same finding does not produce duplicate incidents.", "displayName": "XbowCriticalHighFindings", "enabled": false, "query": "XbowFindings_CL\n| where TimeGenerated > ago(1h)\n| where tolower(Severity) in ('critical', 'high')\n| where isempty(State) or tolower(State) == 'open'\n| summarize arg_max(TimeGenerated, *) by FindingId\n| join kind=leftouter (\n XbowAssets_CL\n | summarize arg_max(TimeGenerated, *) by AssetId\n | project AssetId, StartUrl\n) on AssetId\n| project\n TimeGenerated,\n FindingId,\n FindingName,\n Severity,\n State,\n Summary,\n Impact,\n Mitigations,\n Recipe,\n AssetId,\n AssetName,\n OrganizationId,\n CreatedAt,\n StartUrl\n", "queryFrequency": "PT30M", "queryPeriod": "PT1H", "severity": "High", "suppressionDuration": "PT1H", "suppressionEnabled": false, "triggerOperator": "GreaterThan", "triggerThreshold": 0, "status": "Available", "requiredDataConnectors": [ { "dataTypes": [ "XbowFindings_CL", "XbowAssets_CL" ], "connectorId": "XbowSecurityConnector" } ], "tactics": [ "InitialAccess", "Execution", "PrivilegeEscalation", "DefenseEvasion", "Impact" ], "techniques": [ "T1190" ], "entityMappings": [ { "fieldMappings": [ { "identifier": "Url", "columnName": "StartUrl" } ], "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { "AssetID": "AssetId", "OrganizationID": "OrganizationId", "Severity": "Severity", "FindingID": "FindingId", "State": "State", "AssetName": "AssetName", "FindingName": "FindingName", "CreatedAt": "CreatedAt", "Mitigations": "Mitigations" }, "alertDetailsOverride": { "alertDisplayNameFormat": "XBOW {{Severity}}: {{FindingName}}", "alertDescriptionFormat": "{{Severity}} severity finding on {{AssetName}}. {{Summary}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { "groupByCustomDetails": [ "FindingID" ], "enabled": true, "matchingMethod": "Selected", "reopenClosedIncident": false, "lookbackDuration": "24h" } } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]", "properties": { "description": "XBOW Analytics Rule 1", "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } } ] }, "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "contentKind": "AnalyticsRule", "displayName": "XbowCriticalHighFindings", "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]", "location": "[parameters('workspace-location')]", "dependsOn": [ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { "description": "XbowMediumFindings_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", "parameters": {}, "variables": {}, "resources": [ { "type": "Microsoft.SecurityInsights/AlertRuleTemplates", "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "apiVersion": "2023-02-01-preview", "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { "description": "Creates an incident for each Medium severity finding reported by XBOW that is currently\nin an open state. These findings represent moderate security risks that should be\naddressed in a timely manner. Each alert is deduplicated per finding so re-ingestion\nof the same finding does not produce duplicate incidents.", "displayName": "XbowMediumFindings", "enabled": false, "query": "XbowFindings_CL\n| where TimeGenerated > ago(1h)\n| where tolower(Severity) == 'medium'\n| where isempty(State) or tolower(State) == 'open'\n| summarize arg_max(TimeGenerated, *) by FindingId\n| join kind=leftouter (\n XbowAssets_CL\n | summarize arg_max(TimeGenerated, *) by AssetId\n | project AssetId, StartUrl\n) on AssetId\n| project\n TimeGenerated,\n FindingId,\n FindingName,\n Severity,\n State,\n Summary,\n Impact,\n Mitigations,\n Recipe,\n AssetId,\n AssetName,\n OrganizationId,\n CreatedAt,\n StartUrl\n", "queryFrequency": "PT30M", "queryPeriod": "PT1H", "severity": "Medium", "suppressionDuration": "PT1H", "suppressionEnabled": false, "triggerOperator": "GreaterThan", "triggerThreshold": 0, "status": "Available", "requiredDataConnectors": [ { "dataTypes": [ "XbowFindings_CL", "XbowAssets_CL" ], "connectorId": "XbowSecurityConnector" } ], "tactics": [ "Discovery", "Reconnaissance", "CredentialAccess" ], "entityMappings": [ { "fieldMappings": [ { "identifier": "Url", "columnName": "StartUrl" } ], "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { "AssetID": "AssetId", "OrganizationID": "OrganizationId", "Severity": "Severity", "FindingID": "FindingId", "State": "State", "AssetName": "AssetName", "FindingName": "FindingName", "CreatedAt": "CreatedAt", "Mitigations": "Mitigations" }, "alertDetailsOverride": { "alertDisplayNameFormat": "XBOW Medium: {{FindingName}}", "alertDescriptionFormat": "Medium severity finding on asset {{AssetName}} ({{AssetId}}). {{Summary}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { "groupByCustomDetails": [ "FindingID" ], "enabled": true, "matchingMethod": "Selected", "reopenClosedIncident": false, "lookbackDuration": "24h" } } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]", "properties": { "description": "XBOW Analytics Rule 2", "parentId": "[variables('analyticRuleObject2').analyticRuleId2]", "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } } ] }, "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "contentKind": "AnalyticsRule", "displayName": "XbowMediumFindings", "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", "name": "[variables('analyticRuleObject3').analyticRuleTemplateSpecName3]", "location": "[parameters('workspace-location')]", "dependsOn": [ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { "description": "XbowLowFindings_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]", "parameters": {}, "variables": {}, "resources": [ { "type": "Microsoft.SecurityInsights/AlertRuleTemplates", "name": "[variables('analyticRuleObject3')._analyticRulecontentId3]", "apiVersion": "2023-02-01-preview", "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { "description": "Creates an incident for each Low severity finding reported by XBOW that is currently\nin an open state. These findings represent minor security issues or best-practice\nviolations that should be addressed as part of regular security maintenance. Each\nalert is deduplicated per finding so re-ingestion of the same finding does not\nproduce duplicate incidents.", "displayName": "XbowLowFindings", "enabled": false, "query": "XbowFindings_CL\n| where TimeGenerated > ago(2h)\n| where tolower(Severity) == 'low'\n| where isempty(State) or tolower(State) == 'open'\n| summarize arg_max(TimeGenerated, *) by FindingId\n| join kind=leftouter (\n XbowAssets_CL\n | summarize arg_max(TimeGenerated, *) by AssetId\n | project AssetId, StartUrl\n) on AssetId\n| project\n TimeGenerated,\n FindingId,\n FindingName,\n Severity,\n State,\n Summary,\n Impact,\n Mitigations,\n Recipe,\n AssetId,\n AssetName,\n OrganizationId,\n CreatedAt,\n StartUrl\n", "queryFrequency": "PT1H", "queryPeriod": "PT2H", "severity": "Low", "suppressionDuration": "PT1H", "suppressionEnabled": false, "triggerOperator": "GreaterThan", "triggerThreshold": 0, "status": "Available", "requiredDataConnectors": [ { "dataTypes": [ "XbowFindings_CL", "XbowAssets_CL" ], "connectorId": "XbowSecurityConnector" } ], "tactics": [ "Discovery" ], "entityMappings": [ { "fieldMappings": [ { "identifier": "Url", "columnName": "StartUrl" } ], "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { "AssetID": "AssetId", "OrganizationID": "OrganizationId", "Severity": "Severity", "FindingID": "FindingId", "State": "State", "AssetName": "AssetName", "FindingName": "FindingName", "CreatedAt": "CreatedAt", "Mitigations": "Mitigations" }, "alertDetailsOverride": { "alertDisplayNameFormat": "XBOW Low: {{FindingName}}", "alertDescriptionFormat": "Low severity finding on asset {{AssetName}} ({{AssetId}}). {{Summary}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { "groupByCustomDetails": [ "FindingID" ], "enabled": true, "matchingMethod": "Selected", "reopenClosedIncident": false, "lookbackDuration": "24h" } } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject3').analyticRuleId3,'/'))))]", "properties": { "description": "XBOW Analytics Rule 3", "parentId": "[variables('analyticRuleObject3').analyticRuleId3]", "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject3').analyticRuleVersion3]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } } ] }, "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]", "contentKind": "AnalyticsRule", "displayName": "XbowLowFindings", "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]", "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]", "version": "[variables('analyticRuleObject3').analyticRuleVersion3]" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", "name": "[variables('analyticRuleObject4').analyticRuleTemplateSpecName4]", "location": "[parameters('workspace-location')]", "dependsOn": [ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { "description": "XbowNewAssetDiscovered_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]", "parameters": {}, "variables": {}, "resources": [ { "type": "Microsoft.SecurityInsights/AlertRuleTemplates", "name": "[variables('analyticRuleObject4')._analyticRulecontentId4]", "apiVersion": "2023-02-01-preview", "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { "description": "Alerts when a new asset is registered in XBOW for the first time. This is detected by\nmatching assets whose CreatedAt timestamp falls within the current query window,\nindicating the asset was newly added rather than updated. This helps track shadow IT,\nnew deployments, and any unexpected expansion of the external attack surface.", "displayName": "XbowNewAssetDiscovered", "enabled": false, "query": "XbowAssets_CL\n| where TimeGenerated > ago(1h)\n// Only match assets created within the query window (new, not updated)\n| where todatetime(CreatedAt) > ago(1h)\n| summarize arg_max(TimeGenerated, *) by AssetId\n| project\n TimeGenerated,\n AssetId,\n AssetName,\n StartUrl,\n Lifecycle,\n Sku,\n OrganizationId,\n CreatedAt,\n UpdatedAt,\n AssetReachableState,\n AssetReachableMessage\n", "queryFrequency": "PT30M", "queryPeriod": "PT1H", "severity": "Medium", "suppressionDuration": "PT1H", "suppressionEnabled": false, "triggerOperator": "GreaterThan", "triggerThreshold": 0, "status": "Available", "requiredDataConnectors": [ { "dataTypes": [ "XbowAssets_CL" ], "connectorId": "XbowSecurityConnector" } ], "tactics": [ "Reconnaissance", "Discovery" ], "techniques": [ "T1595" ], "entityMappings": [ { "fieldMappings": [ { "identifier": "Url", "columnName": "StartUrl" } ], "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { "OrganizationID": "OrganizationId", "Lifecycle": "Lifecycle", "AssetID": "AssetId", "Sku": "Sku", "StartUrl": "StartUrl", "AssetName": "AssetName", "CreatedAt": "CreatedAt", "AssetReachableState": "AssetReachableState" }, "alertDetailsOverride": { "alertDisplayNameFormat": "XBOW New Asset: {{AssetName}}", "alertDescriptionFormat": "New asset registered in XBOW: {{AssetName}} ({{StartUrl}}). Reachability: {{AssetReachableState}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { "groupByCustomDetails": [ "AssetID" ], "enabled": true, "matchingMethod": "Selected", "reopenClosedIncident": false, "lookbackDuration": "6h" } } } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject4').analyticRuleId4,'/'))))]", "properties": { "description": "XBOW Analytics Rule 4", "parentId": "[variables('analyticRuleObject4').analyticRuleId4]", "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]", "kind": "AnalyticsRule", "version": "[variables('analyticRuleObject4').analyticRuleVersion4]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" } } } ] }, "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]", "contentKind": "AnalyticsRule", "displayName": "XbowNewAssetDiscovered", "contentProductId": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]", "id": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]", "version": "[variables('analyticRuleObject4').analyticRuleVersion4]" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { "version": "3.0.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "XBOW", "publisherDisplayName": "XBOW", "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

The XBOW solution ingests assets, assessment activity, and vulnerability findings from the XBOW Security Platform into Microsoft Sentinel. XBOW is an AI-powered autonomous penetration testing platform that continuously discovers and validates vulnerabilities in your web applications. This connector surfaces enriched findings — including proof-of-concept evidence, reproduction recipes, impact assessments, and mitigation guidance — directly in your Microsoft Sentinel workspace.

\n

Data tables:

\n\n

Underlying Microsoft Technologies used:

\n

This solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:

\n
    \n
  1. Azure Monitor Ingestion API (DCE/DCR)

    \n
  2. \n
  3. Azure Functions

    \n
  4. \n
\n

Data Connectors: 1, Analytic Rules: 4

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", "icon": "", "contentId": "[variables('_solutionId')]", "parentId": "[variables('_solutionId')]", "source": { "kind": "Solution", "name": "XBOW", "sourceId": "[variables('_solutionId')]" }, "author": { "name": "XBOW", "email": "[variables('_email')]" }, "support": { "name": "XBOW", "email": "support@xbow.com", "tier": "Partner", "link": "https://docs.xbow.com" }, "dependencies": { "operator": "AND", "criteria": [ { "kind": "DataConnector", "contentId": "[variables('_dataConnectorContentId1')]", "version": "[variables('dataConnectorVersion1')]" }, { "kind": "AnalyticsRule", "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" }, { "kind": "AnalyticsRule", "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" }, { "kind": "AnalyticsRule", "contentId": "[variables('analyticRuleObject3')._analyticRulecontentId3]", "version": "[variables('analyticRuleObject3').analyticRuleVersion3]" }, { "kind": "AnalyticsRule", "contentId": "[variables('analyticRuleObject4')._analyticRulecontentId4]", "version": "[variables('analyticRuleObject4').analyticRuleVersion4]" } ] }, "firstPublishDate": "2026-03-04", "providers": [ "XBOW" ], "categories": { "domains": [ "Security - Vulnerability Management" ] } }, "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" } ], "outputs": {} }