From 5daad1af17b013d8063d22614a86fcda4c82d429 Mon Sep 17 00:00:00 2001 From: Dhanunjaya Bedudooru Date: Thu, 30 Jul 2026 22:22:55 -0700 Subject: [PATCH] BitSight: de-duplicate statistics parsers and simplify connector auth (v3.2.1) - Add arg_max(TimeGenerated, *) de-duplication to the BitSight statistics parsers so the CCF snapshot tables return only the latest record per entity, resolving the duplicate-records issue. - Replace the separate username and password inputs with a single BitSight API Token field in both the Security Statistics and Security Events connectors. Authentication uses HTTP Basic with the token as the username and an empty password, matching BitSight's documented API token scheme. - Bump solution to 3.2.1, update release notes, and regenerate the package. --- .../BitSight_CCF/ConnectorDefinition.json | 24 +- .../BitSight_CCF/PollingConfig.json | 58 +- .../ConnectorDefinition.json | 20 +- .../BitSight_Events_CCF/PollingConfig.json | 37 +- .../BitSight/Data/Solution_BitSight.json | 2 +- Solutions/BitSight/Package/3.2.1.zip | Bin 0 -> 52965 bytes Solutions/BitSight/Package/mainTemplate.json | 1409 ++++++++++++----- .../Parsers/BitSightDiligenceStatistics.yaml | 5 +- .../Parsers/BitSightIndustrialStatistics.yaml | 5 +- .../BitSightObservationStatistics.yaml | 5 +- Solutions/BitSight/ReleaseNotes.md | 1 + 11 files changed, 1073 insertions(+), 493 deletions(-) create mode 100644 Solutions/BitSight/Package/3.2.1.zip diff --git a/Solutions/BitSight/Data Connectors/BitSight_CCF/ConnectorDefinition.json b/Solutions/BitSight/Data Connectors/BitSight_CCF/ConnectorDefinition.json index 3ddb6086d71..0fce40b8aa3 100644 --- a/Solutions/BitSight/Data Connectors/BitSight_CCF/ConnectorDefinition.json +++ b/Solutions/BitSight/Data Connectors/BitSight_CCF/ConnectorDefinition.json @@ -148,7 +148,7 @@ { "type": "Markdown", "parameters": { - "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." + "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." } }, { @@ -160,8 +160,8 @@ "columnValue": "properties.addOnAttributes.connectionName" }, { - "columnName": "Active Streams", - "columnValue": "properties.addOnAttributes.streams" + "columnName": "Data Type", + "columnValue": "properties.dataType" }, { "columnName": "API URL", @@ -255,28 +255,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } diff --git a/Solutions/BitSight/Data Connectors/BitSight_CCF/PollingConfig.json b/Solutions/BitSight/Data Connectors/BitSight_CCF/PollingConfig.json index 2e92a5a36ef..6fe346bd2ff 100644 --- a/Solutions/BitSight/Data Connectors/BitSight_CCF/PollingConfig.json +++ b/Solutions/BitSight/Data Connectors/BitSight_CCF/PollingConfig.json @@ -1,4 +1,4 @@ -[ +[ { "type": "Microsoft.SecurityInsights/dataConnectors", "apiVersion": "2025-03-01", @@ -7,9 +7,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -97,9 +98,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -185,9 +187,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -275,9 +278,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -365,9 +369,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -455,9 +460,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -545,9 +551,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -635,9 +642,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "https://service.bitsighttech.com/customer-api/v1/defaults/vulnerabilities", diff --git a/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/ConnectorDefinition.json b/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/ConnectorDefinition.json index c83017708ea..ed290bd17e1 100644 --- a/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/ConnectorDefinition.json +++ b/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/ConnectorDefinition.json @@ -103,7 +103,7 @@ { "type": "Markdown", "parameters": { - "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." + "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." } }, { @@ -196,28 +196,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } diff --git a/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/PollingConfig.json b/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/PollingConfig.json index be4f943b26a..33fe7b77a3f 100644 --- a/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/PollingConfig.json +++ b/Solutions/BitSight/Data Connectors/BitSight_Events_CCF/PollingConfig.json @@ -1,4 +1,4 @@ -[ +[ { "type": "Microsoft.SecurityInsights/dataConnectors", "apiVersion": "2025-03-01", @@ -7,9 +7,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/v2/alerts/')]", @@ -66,9 +67,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -167,9 +169,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -271,9 +274,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -375,9 +379,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", diff --git a/Solutions/BitSight/Data/Solution_BitSight.json b/Solutions/BitSight/Data/Solution_BitSight.json index d14f90c3811..6a2088bb84a 100644 --- a/Solutions/BitSight/Data/Solution_BitSight.json +++ b/Solutions/BitSight/Data/Solution_BitSight.json @@ -37,7 +37,7 @@ "Data Connectors/BitSight_CCF/ConnectorDefinition.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\BitSight", - "Version": "3.2.0", + "Version": "3.2.1", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1PConnector": false diff --git a/Solutions/BitSight/Package/3.2.1.zip b/Solutions/BitSight/Package/3.2.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..6c65eb90ad9d8fffc28b80c5e3b3670e0b9d8fb5 GIT binary patch literal 52965 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 Q@^Td!sYjBc!SJQ~58dj2#sB~S literal 0 HcmV?d00001 diff --git a/Solutions/BitSight/Package/mainTemplate.json b/Solutions/BitSight/Package/mainTemplate.json index 703d67032af..2eb87c3ed5b 100644 --- a/Solutions/BitSight/Package/mainTemplate.json +++ b/Solutions/BitSight/Package/mainTemplate.json @@ -55,7 +55,7 @@ "email": "support@microsoft.com", "_email": "[variables('email')]", "_solutionName": "BitSight", - "_solutionVersion": "3.2.0", + "_solutionVersion": "3.2.1", "solutionId": "bitsight_technologies_inc.bitsight_sentinel", "_solutionId": "[variables('solutionId')]", "workbookVersion1": "1.0.0", @@ -153,7 +153,7 @@ "_parserName7": "[concat(parameters('workspace'),'/','BitSightDiligenceStatistics')]", "_parserId7": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'BitSightDiligenceStatistics')]", "parserTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('BitSightDiligenceStatistics-Parser')))]", - "parserVersion7": "1.1.0", + "parserVersion7": "1.2.0", "parserContentId7": "BitSightDiligenceStatistics-Parser" }, "parserObject8": { @@ -181,14 +181,14 @@ "_parserName11": "[concat(parameters('workspace'),'/','BitSightIndustrialStatistics')]", "_parserId11": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'BitSightIndustrialStatistics')]", "parserTemplateSpecName11": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('BitSightIndustrialStatistics-Parser')))]", - "parserVersion11": "1.1.0", + "parserVersion11": "1.2.0", "parserContentId11": "BitSightIndustrialStatistics-Parser" }, "parserObject12": { "_parserName12": "[concat(parameters('workspace'),'/','BitSightObservationStatistics')]", "_parserId12": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'BitSightObservationStatistics')]", "parserTemplateSpecName12": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('BitSightObservationStatistics-Parser')))]", - "parserVersion12": "1.1.0", + "parserVersion12": "1.2.0", "parserContentId12": "BitSightObservationStatistics-Parser" }, "parserObject13": { @@ -207,7 +207,7 @@ "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'))))]", - "dataConnectorCCPVersion": "3.2.0", + "dataConnectorCCPVersion": "3.2.1", "_dataConnectorContentIdConnectorDefinition2": "BitSightEventsConnector", "dataConnectorTemplateNameConnectorDefinition2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition2')))]", "_dataConnectorContentIdConnections2": "BitSightEventsConnectorConnections", @@ -231,7 +231,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightWorkbook Workbook with template version 3.2.0", + "description": "BitSightWorkbook Workbook with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion1')]", @@ -249,7 +249,7 @@ }, "properties": { "displayName": "[parameters('workbook1-name')]", - "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# My Company\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"df9ebd46-967c-445f-9328-d3538237ba3b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"company\",\"label\":\"Company Name\",\"type\":2,\"isRequired\":true,\"query\":\"BitSightCompanyDetails\\r\\n| distinct Name\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"Kati Communications, Inc.\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"0\",\"name\":\"parameters - 1\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"ae71f2b2-2245-4937-827e-20960f9ae3b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Timer\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":604800000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"0\",\"name\":\"parameters - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let latest_Rating = toscalar(BitSightGraphData\\r\\n| where todatetime(RatingDate) {Timer} and CompanyName == '{company}'\\r\\n| distinct CompanyName, RatingDate, Rating\\r\\n| summarize High = max(Rating), Low = min(Rating), any(RatingDate, Rating)\\r\\n| order by any_RatingDate desc\\r\\n| project strcat_delim(\\\"-\\\",any_Rating, High, Low)\\r\\n| limit 1);\\r\\nBitSightCompanyDetails\\r\\n| where Name == '{company}'\\r\\n| sort by TimeGenerated\\r\\n| extend LatestRating = toint(todecimal(split(latest_Rating, \\\"-\\\")[0])), High = toint(todecimal(split(latest_Rating, \\\"-\\\")[1])), Low = toint(todecimal(split(latest_Rating, \\\"-\\\")[2]))\\r\\n| project-rename Name = Name, Subscription = SubscriptionType , Industry = Industry, [\\\"Customer Monitoring Count\\\"] = CustomerMonitoringCount, [\\\"Latest Rating\\\"] = LatestRating\\r\\n| project Name, [\\\"Latest Rating\\\"], High, Low, Industry, [\\\"Customer Monitoring Count\\\"]\\r\\n| limit 1\",\"size\":4,\"timeContext\":{\"durationMs\":2592000000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightGraphData\\r\\n| where todatetime(RatingDate) {Timer} and CompanyName == '{company}'\\r\\n| distinct CompanyName, RatingDate, Rating\\r\\n| project CompanyName, RatingDate, Rating\\r\\n| order by RatingDate asc\",\"size\":0,\"aggregation\":4,\"title\":\"Security Ratings Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"RatingDate\",\"createOtherGroup\":0,\"showDataPoints\":true,\"ySettings\":{\"min\":300,\"max\":850}}},\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}'\\r\\n| summarize count() by RiskVectorLabel\\r\\n| order by count_ desc\",\"size\":0,\"title\":\"Count of Observations by Risk Vector\",\"exportFieldName\":\"x\",\"exportParameterName\":\"SelectedRiskVectorLabel\",\"exportDefaultValue\":\"none\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"chartSettings\":{\"xAxis\":\"RiskVectorLabel\",\"createOtherGroup\":0,\"showLegend\":true}},\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}'\\r\\n| where RiskVectorLabel == '{SelectedRiskVectorLabel}'\\r\\n| project-away EventVendor, EventProduct\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"sortBy\":[{\"itemKey\":\"RemediationHistoryLastRefreshStatusDate\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"RemediationHistoryLastRefreshStatusDate\",\"sortOrder\":2}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedRiskVectorLabel\",\"comparison\":\"isNotEqualTo\",\"value\":\"none\"},\"name\":\"query - 16\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Compromised Systems\\\"\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"title\":\"Compromised Systems by Risk Vector Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"Date\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\",\"showDataPoints\":true}},\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"User Behavior\\\"\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"title\":\"User Behavior by Risk Vector Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\"}},\"name\":\"query - 15\"},{\"type\":1,\"content\":{\"json\":\"##### Diligence by Risk Vector Over Time\"},\"name\":\"text - 13\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"4d26ba1c-db98-437a-9a0c-63126f341afb\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Risk_Vector\",\"label\":\"Risk Vector\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Diligence\\\"\\r\\n| distinct RiskVectorLabel\\r\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 12\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Diligence\\\" and ('*' in ({Risk_Vector}) or RiskVectorLabel in ({Risk_Vector}))\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"Date\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\",\"createOtherGroup\":0,\"showDataPoints\":true}},\"name\":\"query - 14\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightDiligenceHistoricalStatistics\\r\\n| where todatetime(Date) {Timer} and CompanyName == '{company}'\\r\\n| extend yyyy_mm = format_datetime(todatetime(Date), 'yyyy-MM')\\r\\n| summarize round(avg(Count),2) by yyyy_mm, Category\\r\\n| project Category, avg_Count, yyyy_mm = strcat(yyyy_mm,\\\" (Avg)\\\")\\r\\n| order by yyyy_mm asc, Category asc\\r\\n| limit 15\",\"size\":0,\"aggregation\":4,\"title\":\"Diligence Observations by Severity\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\",\"chartSettings\":{\"xAxis\":\"yyyy_mm\",\"yAxis\":[\"avg_Count\"],\"group\":\"Category\"}},\"name\":\"query - 8\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Compromised Systems\\\" and RiskVectorLabel == \\\"Botnet Infections\\\"\\r\\n| extend d=parse_json(Details) \\r\\n| mv-expand asset = todynamic(Assets)\\r\\n| project Infection = dynamic_to_json(d[0].infection.family), [\\\"Detection Method\\\"] = dynamic_to_json(d[0].detection_method), [\\\"Last Seen\\\"] = column_ifexists(\\\"LastSeen\\\",\\\"\\\"), Asset = dynamic_to_json(asset.asset)\\r\\n| distinct Infection, [\\\"Detection Method\\\"], Asset, [\\\"Last Seen\\\"]\\r\\n| order by [\\\"Last Seen\\\"] desc\",\"size\":0,\"title\":\"Infections\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 7\",\"styleSettings\":{\"showBorder\":true}},{\"type\":1,\"content\":{\"json\":\"##### Vulnerabilities\"},\"name\":\"text - 11\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"c7ff4374-c346-4c43-9354-8936687c2704\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BitSightFindingsSummary\\r\\n| where todatetime(StartDate) {Timer} and Company == '{company}'\\r\\n| extend Filter = case(toreal(Severity) <= 3.9 and toreal(Severity) >= 0.0, \\\"Minor\\\", \\r\\n toreal(Severity) <= 6.9 and toreal(Severity) >= 4.0, \\\"Moderate\\\",\\r\\n toreal(Severity) <= 8.9 and toreal(Severity) >= 7.0, \\\"Material\\\",\\r\\n toreal(Severity) <= 10.0 and toreal(Severity) >= 9.0, \\\"Severe\\\",\\r\\n \\\"\\\")\\r\\n| distinct Filter\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 10\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsSummary\\r\\n| where todatetime(StartDate) {Timer} and Company == '{company}'\\r\\n| distinct Name, Severity, StartDate, EndDate, Description\\r\\n| extend [\\\"Severity Details\\\"] = case(toreal(Severity) <= 3.9 and toreal(Severity) >= 0.0, \\\"Minor\\\", \\r\\n toreal(Severity) <= 6.9 and toreal(Severity) >= 4.0, \\\"Moderate\\\",\\r\\n toreal(Severity) <= 8.9 and toreal(Severity) >= 7.0, \\\"Material\\\",\\r\\n toreal(Severity) <= 10.0 and toreal(Severity) >= 9.0, \\\"Severe\\\",\\r\\n \\\"\\\")\\r\\n| where ('*' in ({Severity}) or [\\\"Severity Details\\\"] in ({Severity}))\\r\\n| project-rename Name = Name, [\\\"Start Date\\\"] = StartDate, [\\\"End Date\\\"] = EndDate\\r\\n| project Name, [\\\"Severity Details\\\"], [\\\"Start Date\\\"], [\\\"End Date\\\"], Description\\r\\n\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 9\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"My Company\"}]},\"name\":\"Main\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-BitSightWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# My Company\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"df9ebd46-967c-445f-9328-d3538237ba3b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"company\",\"label\":\"Company Name\",\"type\":2,\"isRequired\":true,\"query\":\"BitSightCompanyDetails\\r\\n| distinct Name\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":\"Kati Communications, Inc.\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"0\",\"name\":\"parameters - 1\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"ae71f2b2-2245-4937-827e-20960f9ae3b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Timer\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":604800000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"0\",\"name\":\"parameters - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let latest_Rating = toscalar(BitSightGraphData\\r\\n| where todatetime(RatingDate) {Timer} and CompanyName == '{company}'\\r\\n| distinct CompanyName, RatingDate, Rating\\r\\n| summarize High = max(Rating), Low = min(Rating), any(RatingDate, Rating)\\r\\n| order by any_RatingDate desc\\r\\n| project strcat_delim(\\\"-\\\",any_Rating, High, Low)\\r\\n| limit 1);\\r\\nBitSightCompanyDetails\\r\\n| where Name == '{company}'\\r\\n| sort by TimeGenerated\\r\\n| extend LatestRating = toint(todecimal(split(latest_Rating, \\\"-\\\")[0])), High = toint(todecimal(split(latest_Rating, \\\"-\\\")[1])), Low = toint(todecimal(split(latest_Rating, \\\"-\\\")[2]))\\r\\n| project-rename Name = Name, Subscription = SubscriptionType , Industry = Industry, [\\\"Customer Monitoring Count\\\"] = CustomerMonitoringCount, [\\\"Latest Rating\\\"] = LatestRating\\r\\n| project Name, [\\\"Latest Rating\\\"], High, Low, Industry, [\\\"Customer Monitoring Count\\\"]\\r\\n| limit 1\",\"size\":4,\"timeContext\":{\"durationMs\":2592000000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightGraphData\\r\\n| where todatetime(RatingDate) {Timer} and CompanyName == '{company}'\\r\\n| distinct CompanyName, RatingDate, Rating\\r\\n| project CompanyName, RatingDate, Rating\\r\\n| order by RatingDate asc\",\"size\":0,\"aggregation\":4,\"title\":\"Security Ratings Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"RatingDate\",\"createOtherGroup\":0,\"showDataPoints\":true,\"ySettings\":{\"min\":300,\"max\":850}}},\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}'\\r\\n| summarize count() by RiskVectorLabel\\r\\n| order by count_ desc\",\"size\":0,\"title\":\"Count of Observations by Risk Vector\",\"exportFieldName\":\"x\",\"exportParameterName\":\"SelectedRiskVectorLabel\",\"exportDefaultValue\":\"none\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"chartSettings\":{\"xAxis\":\"RiskVectorLabel\",\"createOtherGroup\":0,\"showLegend\":true}},\"name\":\"query - 5\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}'\\r\\n| where RiskVectorLabel == '{SelectedRiskVectorLabel}'\\r\\n| project-away EventVendor, EventProduct\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"sortBy\":[{\"itemKey\":\"RemediationHistoryLastRefreshStatusDate\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"RemediationHistoryLastRefreshStatusDate\",\"sortOrder\":2}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedRiskVectorLabel\",\"comparison\":\"isNotEqualTo\",\"value\":\"none\"},\"name\":\"query - 16\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Compromised Systems\\\"\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"title\":\"Compromised Systems by Risk Vector Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"Date\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\",\"showDataPoints\":true}},\"name\":\"query - 6\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"User Behavior\\\"\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"title\":\"User Behavior by Risk Vector Over Time\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\"}},\"name\":\"query - 15\"},{\"type\":1,\"content\":{\"json\":\"##### Diligence by Risk Vector Over Time\"},\"name\":\"text - 13\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"4d26ba1c-db98-437a-9a0c-63126f341afb\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Risk_Vector\",\"label\":\"Risk Vector\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Diligence\\\"\\r\\n| distinct RiskVectorLabel\\r\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 12\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Diligence\\\" and ('*' in ({Risk_Vector}) or RiskVectorLabel in ({Risk_Vector}))\\r\\n| extend Date = format_datetime(todatetime(LastSeen), 'yyyy-MM')\\r\\n| summarize count() by RiskVectorLabel,Date\\r\\n| project Date, count_, RiskVectorLabel\\r\\n| order by Date asc\\r\\n\",\"size\":0,\"aggregation\":4,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"Date\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"xAxis\":\"Date\",\"yAxis\":[\"count_\"],\"group\":\"RiskVectorLabel\",\"createOtherGroup\":0,\"showDataPoints\":true}},\"name\":\"query - 14\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightDiligenceHistoricalStatistics\\r\\n| where todatetime(Date) {Timer} and CompanyName == '{company}'\\r\\n| extend yyyy_mm = format_datetime(todatetime(Date), 'yyyy-MM')\\r\\n| summarize round(avg(Count),2) by yyyy_mm, Category\\r\\n| project Category, avg_Count, yyyy_mm = strcat(yyyy_mm,\\\" (Avg)\\\")\\r\\n| order by yyyy_mm asc, Category asc\\r\\n| limit 15\",\"size\":0,\"aggregation\":4,\"title\":\"Diligence Observations by Severity\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\",\"chartSettings\":{\"xAxis\":\"yyyy_mm\",\"yAxis\":[\"avg_Count\"],\"group\":\"Category\"}},\"name\":\"query - 8\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsData\\r\\n| where todatetime(LastSeen) {Timer} and CompanyName == '{company}' and RiskCategory == \\\"Compromised Systems\\\" and RiskVectorLabel == \\\"Botnet Infections\\\"\\r\\n| extend d=parse_json(Details) \\r\\n| mv-expand asset = todynamic(Assets)\\r\\n| project Infection = dynamic_to_json(d[0].infection.family), [\\\"Detection Method\\\"] = dynamic_to_json(d[0].detection_method), [\\\"Last Seen\\\"] = column_ifexists(\\\"LastSeen\\\",\\\"\\\"), Asset = dynamic_to_json(asset.asset)\\r\\n| distinct Infection, [\\\"Detection Method\\\"], Asset, [\\\"Last Seen\\\"]\\r\\n| order by [\\\"Last Seen\\\"] desc\",\"size\":0,\"title\":\"Infections\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 7\",\"styleSettings\":{\"showBorder\":true}},{\"type\":1,\"content\":{\"json\":\"##### Vulnerabilities\"},\"name\":\"text - 11\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"c7ff4374-c346-4c43-9354-8936687c2704\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"BitSightFindingsSummary\\r\\n| where todatetime(StartDate) {Timer} and Company == '{company}'\\r\\n| extend Filter = case(toreal(Severity) <= 3.9 and toreal(Severity) >= 0.0, \\\"Minor\\\", \\r\\n toreal(Severity) <= 6.9 and toreal(Severity) >= 4.0, \\\"Moderate\\\",\\r\\n toreal(Severity) <= 8.9 and toreal(Severity) >= 7.0, \\\"Material\\\",\\r\\n toreal(Severity) <= 10.0 and toreal(Severity) >= 9.0, \\\"Severe\\\",\\r\\n \\\"\\\")\\r\\n| distinct Filter\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"*\",\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 10\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"BitSightFindingsSummary\\r\\n| where todatetime(StartDate) {Timer} and Company == '{company}'\\r\\n| distinct Name, Severity, StartDate, EndDate, Description\\r\\n| extend [\\\"Severity Details\\\"] = case(toreal(Severity) <= 3.9 and toreal(Severity) >= 0.0, \\\"Minor\\\", \\r\\n toreal(Severity) <= 6.9 and toreal(Severity) >= 4.0, \\\"Moderate\\\",\\r\\n toreal(Severity) <= 8.9 and toreal(Severity) >= 7.0, \\\"Material\\\",\\r\\n toreal(Severity) <= 10.0 and toreal(Severity) >= 9.0, \\\"Severe\\\",\\r\\n \\\"\\\")\\r\\n| where ('*' in ({Severity}) or [\\\"Severity Details\\\"] in ({Severity}))\\r\\n| project-rename Name = Name, [\\\"Start Date\\\"] = StartDate, [\\\"End Date\\\"] = EndDate\\r\\n| project Name, [\\\"Severity Details\\\"], [\\\"Start Date\\\"], [\\\"End Date\\\"], Description\\r\\n\",\"size\":0,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 9\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"My Company\"}]},\"name\":\"Main\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-BitSightWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", "version": "1.0", "sourceId": "[variables('workspaceResourceId')]", "category": "sentinel" @@ -359,7 +359,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightDropInCompanyRatings_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightDropInCompanyRatings_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", @@ -387,10 +387,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightGraphData" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -409,8 +409,8 @@ "CompanyName": "CompanyName" }, "alertDetailsOverride": { - "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRating Date: {{RatingDate}}\\nPercentage Drop: {{percentage}}%", - "alertDisplayNameFormat": "BitSight : Alert for >10% drop in ratings of {{CompanyName}}." + "alertDisplayNameFormat": "BitSight : Alert for >10% drop in ratings of {{CompanyName}}.", + "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRating Date: {{RatingDate}}\\nPercentage Drop: {{percentage}}%" }, "incidentConfiguration": { "createIncident": false @@ -468,7 +468,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightNewAlertFound_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightNewAlertFound_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", @@ -496,10 +496,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightAlerts" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -512,22 +512,22 @@ ], "entityMappings": [ { - "entityType": "URL", "fieldMappings": [ { - "columnName": "CompanyURL", - "identifier": "Url" + "identifier": "Url", + "columnName": "CompanyURL" } - ] + ], + "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "alertDetailsOverride": { - "alertSeverityColumnName": "Severity", "alertDescriptionFormat": "Alert generated on {{AlertDate}} in BitSight.\\n\\nCompany URL: {{CompanyURL}}\\nAlert GUID: {{GUID}}", - "alertDisplayNameFormat": "BitSight: Alert for {{Trigger}} in {{CompanyName}} from bitsight." + "alertDisplayNameFormat": "BitSight: Alert for {{Trigger}} in {{CompanyName}} from bitsight.", + "alertSeverityColumnName": "Severity" }, "incidentConfiguration": { "createIncident": false @@ -585,7 +585,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightCompromisedSystemsDetected_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightCompromisedSystemsDetected_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]", @@ -613,10 +613,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightFindingsData" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -627,26 +627,26 @@ ], "entityMappings": [ { - "entityType": "Malware", "fieldMappings": [ { - "columnName": "RiskVector", - "identifier": "Name" + "identifier": "Name", + "columnName": "RiskVector" }, { - "columnName": "RiskCategory", - "identifier": "Category" + "identifier": "Category", + "columnName": "RiskCategory" } - ] + ], + "entityType": "Malware" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "alertDetailsOverride": { - "alertSeverityColumnName": "Severity", "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRisk Vector: {{RiskVector}}\\nTemporaryId: {{TemporaryId}}\\nRisk Category: Compromised Systems", - "alertDisplayNameFormat": "BitSight: Alert for {{RiskVector}} in {{CompanyName}} from BitSight" + "alertDisplayNameFormat": "BitSight: Alert for {{RiskVector}} in {{CompanyName}} from BitSight", + "alertSeverityColumnName": "Severity" }, "incidentConfiguration": { "createIncident": true @@ -704,7 +704,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightDiligenceRiskCategoryDetected_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightDiligenceRiskCategoryDetected_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]", @@ -732,10 +732,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightFindingsData" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -751,26 +751,26 @@ ], "entityMappings": [ { - "entityType": "Malware", "fieldMappings": [ { - "columnName": "RiskVector", - "identifier": "Name" + "identifier": "Name", + "columnName": "RiskVector" }, { - "columnName": "RiskCategory", - "identifier": "Category" + "identifier": "Category", + "columnName": "RiskCategory" } - ] + ], + "entityType": "Malware" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "alertDetailsOverride": { - "alertSeverityColumnName": "Severity", "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRisk Vector: {{RiskVector}}\\nTemporaryId: {{TemporaryId}}\\nRisk Category: Diligence", - "alertDisplayNameFormat": "BitSight: Alert for {{RiskVector}} in {{CompanyName}} from BitSight" + "alertDisplayNameFormat": "BitSight: Alert for {{RiskVector}} in {{CompanyName}} from BitSight", + "alertSeverityColumnName": "Severity" }, "incidentConfiguration": { "createIncident": false @@ -828,7 +828,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightDropInHeadlineRating_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightDropInHeadlineRating_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]", @@ -856,10 +856,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightGraphData" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -878,8 +878,8 @@ "CompanyName": "CompanyName" }, "alertDetailsOverride": { - "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRating Date: {{RatingDate}}\\nRating Drop: {{RatingDifferance}}", - "alertDisplayNameFormat": "BitSight : Alert for drop in the headline rating of {{CompanyName}}." + "alertDisplayNameFormat": "BitSight : Alert for drop in the headline rating of {{CompanyName}}.", + "alertDescriptionFormat": "Alert is generated for {{CompanyName}}.\\n\\nRating Date: {{RatingDate}}\\nRating Drop: {{RatingDifferance}}" }, "incidentConfiguration": { "createIncident": false @@ -937,7 +937,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightNewBreachFound_AnalyticalRules Analytics Rule with template version 3.2.0", + "description": "BitSightNewBreachFound_AnalyticalRules Analytics Rule with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]", @@ -965,10 +965,10 @@ "status": "Available", "requiredDataConnectors": [ { + "connectorId": "BitSight", "dataTypes": [ "BitSightBreaches" - ], - "connectorId": "BitSight" + ] } ], "tactics": [ @@ -981,22 +981,22 @@ ], "entityMappings": [ { - "entityType": "URL", "fieldMappings": [ { - "columnName": "PreviwURL", - "identifier": "Url" + "identifier": "Url", + "columnName": "PreviwURL" } - ] + ], + "entityType": "URL" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "alertDetailsOverride": { - "alertSeverityColumnName": "Severity", "alertDescriptionFormat": "Alert is generated on {{DateCreated}} at BitSight.\\n\\nGUID: {{GUID}}\\nPreview URL: {{PreviwURL}}", - "alertDisplayNameFormat": "BitSight: Alert for new breach in {{Companyname}}." + "alertDisplayNameFormat": "BitSight: Alert for new breach in {{Companyname}}.", + "alertSeverityColumnName": "Severity" }, "incidentConfiguration": { "createIncident": false @@ -1054,7 +1054,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightAlerts Data Parser with template version 3.2.0", + "description": "BitSightAlerts Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject1').parserVersion1]", @@ -1186,7 +1186,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightBreaches Data Parser with template version 3.2.0", + "description": "BitSightBreaches Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject2').parserVersion2]", @@ -1318,7 +1318,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightCompanyDetails Data Parser with template version 3.2.0", + "description": "BitSightCompanyDetails Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject3').parserVersion3]", @@ -1450,7 +1450,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightCompanyRatingDetails Data Parser with template version 3.2.0", + "description": "BitSightCompanyRatingDetails Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject4').parserVersion4]", @@ -1582,7 +1582,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightCompanyRatings Data Parser with template version 3.2.0", + "description": "BitSightCompanyRatings Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject5').parserVersion5]", @@ -1714,7 +1714,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightDiligenceHistoricalStatistics Data Parser with template version 3.2.0", + "description": "BitSightDiligenceHistoricalStatistics Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject6').parserVersion6]", @@ -1846,7 +1846,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightDiligenceStatistics Data Parser with template version 3.2.0", + "description": "BitSightDiligenceStatistics Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject7').parserVersion7]", @@ -1863,7 +1863,7 @@ "displayName": "Parser for BitSightDiligenceStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightDiligenceStatistics", - "query": "union isfuzzy=true\n (\n BitsightDiligence_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\",\n Unknown = column_ifexists('unknown', ''),\n Bad = column_ifexists('bad', ''),\n Warn = column_ifexists('warn', ''),\n Neutral = column_ifexists('neutral', ''),\n Fair = column_ifexists('fair', ''),\n Good = column_ifexists('good', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', ''),\n SpearPhishing = column_ifexists('spear_phishing', ''),\n BitFlip = column_ifexists('bit_flip', ''),\n TypographicalErrors = column_ifexists('typographical_errors', ''),\n TLDVariant = column_ifexists('tld_variant', ''),\n TotalCount = column_ifexists('total_count', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n RiskVector,\n CompanyName,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TLDVariant,\n TotalCount\n ),\n (\n BitSightDiligenceStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TldVariant,\n TotalCount,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightDiligence_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\",\n Unknown = column_ifexists('unknown', ''),\n Bad = column_ifexists('bad', ''),\n Warn = column_ifexists('warn', ''),\n Neutral = column_ifexists('neutral', ''),\n Fair = column_ifexists('fair', ''),\n Good = column_ifexists('good', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', ''),\n SpearPhishing = column_ifexists('spear_phishing', ''),\n BitFlip = column_ifexists('bit_flip', ''),\n TypographicalErrors = column_ifexists('typographical_errors', ''),\n TLDVariant = column_ifexists('tld_variant', ''),\n TotalCount = column_ifexists('total_count', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n RiskVector,\n CompanyName,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TLDVariant,\n TotalCount\n ),\n (\n BitSightDiligenceStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TldVariant,\n TotalCount,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -1913,8 +1913,8 @@ "contentId": "[variables('parserObject7').parserContentId7]", "contentKind": "Parser", "displayName": "Parser for BitSightDiligenceStatistics", - "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject7').parserContentId7,'-', '1.1.0')))]", - "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject7').parserContentId7,'-', '1.1.0')))]", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject7').parserContentId7,'-', '1.2.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject7').parserContentId7,'-', '1.2.0')))]", "version": "[variables('parserObject7').parserVersion7]" } }, @@ -1928,7 +1928,7 @@ "displayName": "Parser for BitSightDiligenceStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightDiligenceStatistics", - "query": "union isfuzzy=true\n (\n BitsightDiligence_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\",\n Unknown = column_ifexists('unknown', ''),\n Bad = column_ifexists('bad', ''),\n Warn = column_ifexists('warn', ''),\n Neutral = column_ifexists('neutral', ''),\n Fair = column_ifexists('fair', ''),\n Good = column_ifexists('good', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', ''),\n SpearPhishing = column_ifexists('spear_phishing', ''),\n BitFlip = column_ifexists('bit_flip', ''),\n TypographicalErrors = column_ifexists('typographical_errors', ''),\n TLDVariant = column_ifexists('tld_variant', ''),\n TotalCount = column_ifexists('total_count', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n RiskVector,\n CompanyName,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TLDVariant,\n TotalCount\n ),\n (\n BitSightDiligenceStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TldVariant,\n TotalCount,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightDiligence_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\",\n Unknown = column_ifexists('unknown', ''),\n Bad = column_ifexists('bad', ''),\n Warn = column_ifexists('warn', ''),\n Neutral = column_ifexists('neutral', ''),\n Fair = column_ifexists('fair', ''),\n Good = column_ifexists('good', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', ''),\n SpearPhishing = column_ifexists('spear_phishing', ''),\n BitFlip = column_ifexists('bit_flip', ''),\n TypographicalErrors = column_ifexists('typographical_errors', ''),\n TLDVariant = column_ifexists('tld_variant', ''),\n TotalCount = column_ifexists('total_count', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n RiskVector,\n CompanyName,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TLDVariant,\n TotalCount\n ),\n (\n BitSightDiligenceStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"DiligenceStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n Unknown,\n Bad,\n Warn,\n Neutral,\n Fair,\n Good,\n SpearPhishing,\n BitFlip,\n TypographicalErrors,\n TldVariant,\n TotalCount,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -1978,7 +1978,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightFindingsData Data Parser with template version 3.2.0", + "description": "BitSightFindingsData Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject8').parserVersion8]", @@ -2110,7 +2110,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightFindingsSummary Data Parser with template version 3.2.0", + "description": "BitSightFindingsSummary Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject9').parserVersion9]", @@ -2242,7 +2242,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightGraphData Data Parser with template version 3.2.0", + "description": "BitSightGraphData Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject10').parserVersion10]", @@ -2374,7 +2374,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightIndustrialStatistics Data Parser with template version 3.2.0", + "description": "BitSightIndustrialStatistics Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject11').parserVersion11]", @@ -2391,7 +2391,7 @@ "displayName": "Parser for BitSightIndustrialStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightIndustrialStatistics", - "query": "union isfuzzy=true\n (\n BitsightIndustrial_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitsightIndustrialStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n IncidentCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightIndustrial_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitsightIndustrialStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n IncidentCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -2441,8 +2441,8 @@ "contentId": "[variables('parserObject11').parserContentId11]", "contentKind": "Parser", "displayName": "Parser for BitSightIndustrialStatistics", - "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject11').parserContentId11,'-', '1.1.0')))]", - "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject11').parserContentId11,'-', '1.1.0')))]", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject11').parserContentId11,'-', '1.2.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject11').parserContentId11,'-', '1.2.0')))]", "version": "[variables('parserObject11').parserVersion11]" } }, @@ -2456,7 +2456,7 @@ "displayName": "Parser for BitSightIndustrialStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightIndustrialStatistics", - "query": "union isfuzzy=true\n (\n BitsightIndustrial_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitsightIndustrialStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n IncidentCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightIndustrial_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitsightIndustrialStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"IndustrialStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n IncidentCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -2506,7 +2506,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightObservationStatistics Data Parser with template version 3.2.0", + "description": "BitSightObservationStatistics Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject12').parserVersion12]", @@ -2523,7 +2523,7 @@ "displayName": "Parser for BitSightObservationStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightObservationStatistics", - "query": "union isfuzzy=true\n (\n BitsightObservation_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitSightObservationStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n ObservationCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightObservation_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitSightObservationStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n ObservationCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -2573,8 +2573,8 @@ "contentId": "[variables('parserObject12').parserContentId12]", "contentKind": "Parser", "displayName": "Parser for BitSightObservationStatistics", - "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject12').parserContentId12,'-', '1.1.0')))]", - "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject12').parserContentId12,'-', '1.1.0')))]", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject12').parserContentId12,'-', '1.2.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject12').parserContentId12,'-', '1.2.0')))]", "version": "[variables('parserObject12').parserVersion12]" } }, @@ -2588,7 +2588,7 @@ "displayName": "Parser for BitSightObservationStatistics", "category": "Microsoft Sentinel Parser", "functionAlias": "BitSightObservationStatistics", - "query": "union isfuzzy=true\n (\n BitsightObservation_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitSightObservationStatistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n ObservationCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", + "query": "union isfuzzy=true\n (\n BitsightObservation_statistics_CL\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\",\n Count = column_ifexists('count', ''),\n CountPeriod = column_ifexists('count_period', ''),\n AverageDurationDays = column_ifexists('average_duration_days', ''),\n RiskVector = column_ifexists('risk_vector', ''),\n CompanyName = column_ifexists('Company_name', '')\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n Count,\n CountPeriod,\n AverageDurationDays,\n RiskVector,\n CompanyName\n ),\n (\n BitSightObservationStatistics_CL\n | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector\n | extend\n EventVendor = \"BitSight\",\n EventProduct = \"ObservationStatistics\"\n | project\n TimeGenerated,\n EventVendor,\n EventProduct,\n CompanyName,\n CompanyGuid,\n RiskVector,\n ObservationCount,\n CountPeriod,\n AverageDurationDays,\n ConnectorName\n )\n", "functionParameters": "", "version": 2, "tags": [ @@ -2638,7 +2638,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSightVulnerabilitiesFindingsSummary Data Parser with template version 3.2.0", + "description": "BitSightVulnerabilitiesFindingsSummary Data Parser with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject13').parserVersion13]", @@ -2770,7 +2770,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "BitSight data connector with template version 3.2.0", + "description": "BitSight data connector with template version 3.2.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -3591,7 +3591,7 @@ { "type": "Markdown", "parameters": { - "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." + "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." } }, { @@ -3684,28 +3684,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } @@ -5233,7 +5221,7 @@ { "type": "Markdown", "parameters": { - "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." + "content": "## BitSight Connections\n\nManage multiple BitSight data stream connections. Each connection selects a specific data type - **Alerts**, **Breaches**, or **Findings** - and assigns a **Connection Name** that is stored in the `ConnectorName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." } }, { @@ -5326,28 +5314,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } @@ -5490,13 +5466,8 @@ "type": "securestring", "minLength": 1 }, - "username": { - "defaultValue": "username", - "type": "securestring", - "minLength": 1 - }, - "password": { - "defaultValue": "password", + "apiToken": { + "defaultValue": "apiToken", "type": "securestring", "minLength": 1 }, @@ -5544,9 +5515,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/v2/alerts/')]", @@ -5603,9 +5575,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -5704,9 +5677,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -5808,9 +5782,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -5912,9 +5887,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -6187,7 +6163,7 @@ { "type": "Markdown", "parameters": { - "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." + "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." } }, { @@ -6199,8 +6175,8 @@ "columnValue": "properties.addOnAttributes.connectionName" }, { - "columnName": "Active Streams", - "columnValue": "properties.addOnAttributes.streams" + "columnName": "Data Type", + "columnValue": "properties.dataType" }, { "columnName": "API URL", @@ -6294,28 +6270,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } @@ -6988,217 +6952,849 @@ ] } } - } - ] - }, - "packageKind": "Solution", - "packageVersion": "[variables('_solutionVersion')]", - "packageName": "[variables('_solutionName')]", - "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition3'),'-', variables('dataConnectorCCPVersion'))))]", - "packageId": "[variables('_solutionId')]", - "contentSchemaVersion": "3.0.0", - "version": "[variables('dataConnectorCCPVersion')]" - } - }, - { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition3'))]", - "apiVersion": "2022-09-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", - "location": "[parameters('workspace-location')]", - "kind": "Customizable", - "properties": { - "connectorUiConfig": { - "id": "BitSightStatisticsConnector", - "title": "BitSight Security Statistics (via Codeless Connector Framework)", - "publisher": "Microsoft", - "descriptionMarkdown": "The [BitSight](https://www.bitsight.com/) data connector provides the capability to ingest security statistics, company profiles, rating details, diligence history, risk vector statistics, and vulnerability data from your BitSight portfolio into Microsoft Sentinel through the BitSight REST API. Refer to the [BitSight API documentation](https://help.bitsighttech.com/hc/en-us/articles/115014888388-API-Token-Management) for more information.", - "graphQueriesTableName": "BitSightCompanyDetails", - "graphQueries": [ - { - "metricName": "Total Company Detail records received", - "legend": "BitSight Company Details", - "baseQuery": "{{graphQueriesTableName}}" - }, - { - "metricName": "Total Company Rating Details received", - "legend": "BitSight Company Rating Details", - "baseQuery": "BitSightCompanyRatingDetails" - }, - { - "metricName": "Total Diligence Historical Statistics received", - "legend": "BitSight Diligence Historical Statistics", - "baseQuery": "BitSightDiligenceHistoricalStatistics" - }, - { - "metricName": "Total Diligence Statistics received", - "legend": "BitSight Diligence Statistics", - "baseQuery": "BitSightDiligenceStatistics" - }, - { - "metricName": "Total Observations Statistics received", - "legend": "BitSight Observations Statistics", - "baseQuery": "BitSightObservationStatistics" - }, - { - "metricName": "Total Industries Statistics received", - "legend": "BitSight Industries Statistics", - "baseQuery": "BitsightIndustrialStatistics" - }, - { - "metricName": "Total Findings Summary records received", - "legend": "BitSight Findings Summary", - "baseQuery": "BitSightFindingsSummary" - }, - { - "metricName": "Total Vulnerabilities received", - "legend": "BitSight Vulnerabilities", - "baseQuery": "BitsightVulnerabilitiesFindingsSummary" - } - ], - "sampleQueries": [ - { - "description": "Get sample of BitSight Company Details", - "query": "{{graphQueriesTableName}}\n | take 10" - }, - { - "description": "Get company security ratings over time", - "query": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(90d)\n | summarize LatestRating = arg_max(TimeGenerated, CurrentRating) by Name\n | order by LatestRating asc" - }, - { - "description": "Get sample of BitSight Company Rating Details", - "query": "BitSightCompanyRatingDetails\n | take 10" - }, - { - "description": "Get findings summary with latest data per company/stat", - "query": "BitSightFindingsSummary\n | where TimeGenerated > ago(1d)\n | take 10" - }, - { - "description": "Get sample of BitSight Vulnerabilities", - "query": "BitsightVulnerabilitiesFindingsSummary\n | take 10" - } - ], - "dataTypes": [ - { - "name": "{{graphQueriesTableName}}", - "lastDataReceivedQuery": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - }, - { - "name": "BitSightCompanyRatingDetails", - "lastDataReceivedQuery": "BitSightCompanyRatingDetails\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - }, - { - "name": "BitSightFindingsSummary", - "lastDataReceivedQuery": "BitSightFindingsSummary\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - }, - { - "name": "BitSightDiligenceHistoricalStatistics", - "lastDataReceivedQuery": "BitSightDiligenceHistoricalStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" - }, - { - "name": "BitSightDiligenceStatistics", - "lastDataReceivedQuery": "BitSightDiligenceStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" - }, - { - "name": "BitSightObservationStatistics", - "lastDataReceivedQuery": "BitSightObservationStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" - }, - { - "name": "BitsightIndustrialStatistics", - "lastDataReceivedQuery": "BitsightIndustrialStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" }, { - "name": "BitsightVulnerabilitiesFindingsSummary", - "lastDataReceivedQuery": "BitsightVulnerabilitiesFindingsSummary\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" - } - ], - "connectivityCriteria": [ - { - "type": "HasDataConnectors" - } - ], - "availability": { - "isPreview": true, - "status": 1 - }, - "permissions": { - "resourceProvider": [ - { - "provider": "Microsoft.OperationalInsights/workspaces", - "permissionsDisplayText": "Read and Write permissions are required.", - "providerDisplayName": "Workspace", - "scope": "Workspace", - "requiredPermissions": { - "write": true, - "read": true, - "delete": true, - "action": false - } - } - ], - "customs": [ - { - "name": "BitSight API Token", - "description": "A BitSight API Token is required to authenticate requests to the BitSight REST API. [See the documentation](https://help.bitsighttech.com/hc/en-us/articles/115014888388-API-Token-Management) to learn more about API Token management." - } - ] - }, - "instructionSteps": [ - { - "title": "1. Connection Management", - "description": "Manage your BitSight statistics data stream connections", - "instructions": [ - { - "type": "Markdown", - "parameters": { - "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication where the API token is used as **both** the username and password." - } - }, - { - "type": "DataConnectorsGrid", - "parameters": { - "mapping": [ - { - "columnName": "Connection Name", - "columnValue": "properties.addOnAttributes.connectionName" - }, - { - "columnName": "Active Streams", - "columnValue": "properties.addOnAttributes.streams" - }, - { - "columnName": "API URL", - "columnValue": "properties.request.apiEndpoint" - } - ], - "menuItems": [ - "DeleteConnector" - ] - } - }, - { - "type": "ContextPane", - "parameters": { - "isPrimary": true, - "label": "Add Connection", - "title": "Add BitSight Statistics Connection", - "subtitle": "Configure a new BitSight statistics connection", - "contextPaneType": "DataConnectorsContextPane", - "instructionSteps": [ - { - "instructions": [ - { - "type": "Markdown", - "parameters": { - "content": "## 1. Select Data Streams\n\nChoose which BitSight statistics data types to collect for this connection. You can select multiple streams." - } - }, - { - "type": "Dropdown", - "parameters": { - "label": "Data Streams", - "name": "streams", - "options": [ - { + "name": "BitSightCompanyDetails_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightCompanyDetails_CL", + "description": "The BitSightCompanyDetails table contains full company snapshots from the BitSight API per company GUID ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "Guid", + "type": "string", + "description": "Unique identifier (GUID) for the company in BitSight." + }, + { + "name": "Name", + "type": "string", + "description": "Name of the company." + }, + { + "name": "Shortname", + "type": "string", + "description": "Short name of the company." + }, + { + "name": "CompanyType", + "type": "string", + "description": "The type of entity (e.g., CURATED,PRIVATE)." + }, + { + "name": "Description", + "type": "string", + "description": "Description of the company." + }, + { + "name": "PrimaryDomain", + "type": "string", + "description": "Primary internet domain of the company." + }, + { + "name": "Homepage", + "type": "string", + "description": "URL of the company homepage." + }, + { + "name": "DisplayUrl", + "type": "string", + "description": "URL to the company overview page in BitSight portal." + }, + { + "name": "Sparkline", + "type": "string", + "description": "URL to the company rating sparkline image." + }, + { + "name": "Industry", + "type": "string", + "description": "Industry sector name." + }, + { + "name": "IndustrySlug", + "type": "string", + "description": "URL-friendly identifier for the industry." + }, + { + "name": "SubIndustry", + "type": "string", + "description": "Sub-industry name." + }, + { + "name": "SubIndustrySlug", + "type": "string", + "description": "URL-friendly identifier for the sub-industry." + }, + { + "name": "Ipv4Count", + "type": "int", + "description": "Number of IPv4 addresses attributed to the company." + }, + { + "name": "PeopleCount", + "type": "int", + "description": "Number of people associated with the company." + }, + { + "name": "SearchCount", + "type": "int", + "description": "Number of searches for the company." + }, + { + "name": "CustomerMonitoringCount", + "type": "int", + "description": "Number of customers monitoring this company." + }, + { + "name": "CurrentRating", + "type": "int", + "description": "Current overall BitSight security rating." + }, + { + "name": "RatingIndustryMedian", + "type": "string", + "description": "Comparison of company rating to industry median (e.g., above, below)." + }, + { + "name": "Ratings", + "type": "dynamic", + "description": "Array of historical rating snapshots, each with rating_date, rating, range, and rating_color." + }, + { + "name": "SubscriptionType", + "type": "string", + "description": "Type of BitSight subscription (e.g., Continuous Monitoring)." + }, + { + "name": "SubscriptionTypeKey", + "type": "string", + "description": "Machine-readable subscription type key." + }, + { + "name": "SubscriptionEndDate", + "type": "string", + "description": "Date the subscription ends (YYYY-MM-DD), or null." + }, + { + "name": "BulkEmailSenderStatus", + "type": "string", + "description": "Bulk email sender classification (e.g., NONE)." + }, + { + "name": "SecurityGrade", + "type": "string", + "description": "Security grade, if available." + }, + { + "name": "ServiceProvider", + "type": "boolean", + "description": "Indicates whether this company is a service provider." + }, + { + "name": "HasCompanyTree", + "type": "boolean", + "description": "Indicates whether the company has a company tree." + }, + { + "name": "HasPreferredContact", + "type": "boolean", + "description": "Indicates whether the company has a preferred contact." + }, + { + "name": "IsBundle", + "type": "boolean", + "description": "Indicates whether this is a bundle entry." + }, + { + "name": "IsPrimary", + "type": "boolean", + "description": "Indicates whether this is the primary company record." + }, + { + "name": "InSpmPortfolio", + "type": "boolean", + "description": "Indicates whether the company is in the SPM portfolio." + }, + { + "name": "IsMycompMysubsBundle", + "type": "boolean", + "description": "Indicates whether this is a my-company/my-subsidiaries bundle." + }, + { + "name": "IsCsp", + "type": "boolean", + "description": "Indicates whether the company is a cloud service provider." + }, + { + "name": "HasDelegatedSecurityControls", + "type": "boolean", + "description": "Indicates whether security controls have been delegated." + }, + { + "name": "CustomId", + "type": "dynamic", + "description": "Customer-assigned identifier for the company." + }, + { + "name": "AvailableUpgradeTypes", + "type": "dynamic", + "description": "Array of available upgrade types for this company." + }, + { + "name": "CompanyFeatures", + "type": "dynamic", + "description": "Array of feature flags enabled for the company." + }, + { + "name": "RelatedCompanies", + "type": "dynamic", + "description": "Array of related company references." + }, + { + "name": "PrimaryCompany", + "type": "dynamic", + "description": "Primary company object (guid, name), or null." + }, + { + "name": "ComplianceClaim", + "type": "dynamic", + "description": "Compliance claim object, or null." + }, + { + "name": "Permissions", + "type": "dynamic", + "description": "Object of permission flags for this company (can_annotate, can_view_forensics, etc.)." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitSightCompanyRatingDetails_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightCompanyRatingDetails_CL", + "description": "The BitSightCompanyRatingDetails table contains per-risk-vector rating breakdowns for each portfolio company from the BitSight API ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company." + }, + { + "name": "RiskVectorSlug", + "type": "string", + "description": "URL-friendly identifier for the risk vector (dict key — always null due to CCF JSONPath limitation; use RiskVectorLabel)." + }, + { + "name": "RiskVectorLabel", + "type": "string", + "description": "Human-readable name of the risk vector (API field: name)." + }, + { + "name": "RiskCategory", + "type": "string", + "description": "Parent risk category for the risk vector (API field: category)." + }, + { + "name": "CategoryOrder", + "type": "int", + "description": "Display order of the category." + }, + { + "name": "Rating", + "type": "int", + "description": "Numeric score for this risk vector." + }, + { + "name": "Grade", + "type": "string", + "description": "Letter grade for this risk vector." + }, + { + "name": "Percentile", + "type": "int", + "description": "Percentile rank compared to peers for this risk vector (0-100)." + }, + { + "name": "GradeColor", + "type": "string", + "description": "Hex color code associated with the grade for UI display (e.g., '#239563')." + }, + { + "name": "RiskVectorOrder", + "type": "int", + "description": "Display order of the risk vector within its category." + }, + { + "name": "DisplayUrl", + "type": "string", + "description": "URL to the risk vector detail page in BitSight portal." + }, + { + "name": "Beta", + "type": "boolean", + "description": "Indicates if this risk vector is in beta status." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitSightDiligenceHistoricalStatistics_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightDiligenceHistoricalStatistics_CL", + "description": "The BitSightDiligenceHistoricalStatistics table contains historical diligence statistics per company over time from the BitSight API ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company." + }, + { + "name": "RecordDate", + "type": "string", + "description": "The date of the historical record (YYYY-MM-DD)." + }, + { + "name": "Grade", + "type": "string", + "description": "Letter grade for this record period." + }, + { + "name": "Counts", + "type": "dynamic", + "description": "Array of per-category count objects ({ count, category }). Expanded row-per-category at query time by the KQL parser via mv-expand." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitSightDiligenceStatistics_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightDiligenceStatistics_CL", + "description": "The BitSightDiligenceStatistics table contains diligence statistics per risk vector for each portfolio company from the BitSight API ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company." + }, + { + "name": "RiskVector", + "type": "string", + "description": "Risk vector slug (dict key — always null due to CCF JSONPath limitation)." + }, + { + "name": "Unknown", + "type": "int", + "description": "Count of findings with unknown severity." + }, + { + "name": "Bad", + "type": "int", + "description": "Count of bad findings." + }, + { + "name": "Warn", + "type": "int", + "description": "Count of warn findings." + }, + { + "name": "Neutral", + "type": "int", + "description": "Count of neutral findings." + }, + { + "name": "Fair", + "type": "int", + "description": "Count of fair findings." + }, + { + "name": "Good", + "type": "int", + "description": "Count of good findings." + }, + { + "name": "SpearPhishing", + "type": "int", + "description": "[domain_squatting] Count of spear-phishing lookalike domains." + }, + { + "name": "BitFlip", + "type": "int", + "description": "[domain_squatting] Count of bit-flip lookalike domains." + }, + { + "name": "TypographicalErrors", + "type": "int", + "description": "[domain_squatting] Count of typographical-error lookalike domains." + }, + { + "name": "TldVariant", + "type": "int", + "description": "[domain_squatting] Count of TLD-variant lookalike domains." + }, + { + "name": "TotalCount", + "type": "int", + "description": "[domain_squatting] Total count of all lookalike domain types." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitSightFindingsSummary_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightFindingsSummary_CL", + "description": "The BitSightFindingsSummary table contains findings summary statistics per risk vector for each monitored company. Severity and description enrichment is resolved at query time by joining with BitsightVulnerabilitiesFindingsSummary on Name == DisplayName.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company associated with the findings summary." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company associated with the findings summary." + }, + { + "name": "StartDate", + "type": "string", + "description": "Start date of the reporting period (YYYY-MM-DD)." + }, + { + "name": "EndDate", + "type": "string", + "description": "End date of the reporting period (YYYY-MM-DD)." + }, + { + "name": "Stats", + "type": "dynamic", + "description": "Array of per-stat objects. Expanded row-per-stat at query time by the KQL parser via mv-expand into Name, StatId, Confidence, EventCount, HostCount, FirstSeen columns." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitsightIndustrialStatistics_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitsightIndustrialStatistics_CL", + "description": "The BitsightIndustrialStatistics table contains industry peer comparison statistics per risk vector for each portfolio company from the BitSight API ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company." + }, + { + "name": "RiskVector", + "type": "string", + "description": "Risk vector slug (dict key — always null due to CCF JSONPath limitation)." + }, + { + "name": "IncidentCount", + "type": "int", + "description": "Number of incidents for this risk vector in the industry over the measured period." + }, + { + "name": "CountPeriod", + "type": "string", + "description": "Measurement period (e.g., 'year')." + }, + { + "name": "AverageDurationDays", + "type": "real", + "description": "Average duration in days for incidents of this risk vector in the industry." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + }, + { + "name": "BitSightObservationStatistics_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "retentionInDays": 180, + "schema": { + "name": "BitSightObservationStatistics_CL", + "description": "The BitSightObservationStatistics table contains observations statistics per risk vector for each portfolio company from the BitSight API ingested into Microsoft Sentinel.", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "isDefaultDisplay": true + }, + { + "name": "CompanyName", + "type": "string", + "description": "Name of the company." + }, + { + "name": "CompanyGuid", + "type": "string", + "description": "GUID of the company." + }, + { + "name": "RiskVector", + "type": "string", + "description": "Risk vector slug (dict key — always null due to CCF JSONPath limitation)." + }, + { + "name": "ObservationCount", + "type": "int", + "description": "Total number of observations for this risk vector in the measurement period." + }, + { + "name": "CountPeriod", + "type": "string", + "description": "Measurement period (e.g., 'year')." + }, + { + "name": "AverageDurationDays", + "type": "real", + "description": "Average duration in days for observations." + }, + { + "name": "ConnectorName", + "type": "string", + "description": "Connection name identifier for multi-instance tracking." + } + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition3'),'-', variables('dataConnectorCCPVersion'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('dataConnectorCCPVersion')]" + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition3'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "BitSightStatisticsConnector", + "title": "BitSight Security Statistics (via Codeless Connector Framework)", + "publisher": "Microsoft", + "descriptionMarkdown": "The [BitSight](https://www.bitsight.com/) data connector provides the capability to ingest security statistics, company profiles, rating details, diligence history, risk vector statistics, and vulnerability data from your BitSight portfolio into Microsoft Sentinel through the BitSight REST API. Refer to the [BitSight API documentation](https://help.bitsighttech.com/hc/en-us/articles/115014888388-API-Token-Management) for more information.", + "graphQueriesTableName": "BitSightCompanyDetails", + "graphQueries": [ + { + "metricName": "Total Company Detail records received", + "legend": "BitSight Company Details", + "baseQuery": "{{graphQueriesTableName}}" + }, + { + "metricName": "Total Company Rating Details received", + "legend": "BitSight Company Rating Details", + "baseQuery": "BitSightCompanyRatingDetails" + }, + { + "metricName": "Total Diligence Historical Statistics received", + "legend": "BitSight Diligence Historical Statistics", + "baseQuery": "BitSightDiligenceHistoricalStatistics" + }, + { + "metricName": "Total Diligence Statistics received", + "legend": "BitSight Diligence Statistics", + "baseQuery": "BitSightDiligenceStatistics" + }, + { + "metricName": "Total Observations Statistics received", + "legend": "BitSight Observations Statistics", + "baseQuery": "BitSightObservationStatistics" + }, + { + "metricName": "Total Industries Statistics received", + "legend": "BitSight Industries Statistics", + "baseQuery": "BitsightIndustrialStatistics" + }, + { + "metricName": "Total Findings Summary records received", + "legend": "BitSight Findings Summary", + "baseQuery": "BitSightFindingsSummary" + }, + { + "metricName": "Total Vulnerabilities received", + "legend": "BitSight Vulnerabilities", + "baseQuery": "BitsightVulnerabilitiesFindingsSummary" + } + ], + "sampleQueries": [ + { + "description": "Get sample of BitSight Company Details", + "query": "{{graphQueriesTableName}}\n | take 10" + }, + { + "description": "Get company security ratings over time", + "query": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(90d)\n | summarize LatestRating = arg_max(TimeGenerated, CurrentRating) by Name\n | order by LatestRating asc" + }, + { + "description": "Get sample of BitSight Company Rating Details", + "query": "BitSightCompanyRatingDetails\n | take 10" + }, + { + "description": "Get findings summary with latest data per company/stat", + "query": "BitSightFindingsSummary\n | where TimeGenerated > ago(1d)\n | take 10" + }, + { + "description": "Get sample of BitSight Vulnerabilities", + "query": "BitsightVulnerabilitiesFindingsSummary\n | take 10" + } + ], + "dataTypes": [ + { + "name": "{{graphQueriesTableName}}", + "lastDataReceivedQuery": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "BitSightCompanyRatingDetails", + "lastDataReceivedQuery": "BitSightCompanyRatingDetails\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "BitSightFindingsSummary", + "lastDataReceivedQuery": "BitSightFindingsSummary\n | where TimeGenerated > ago(12h)\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "BitSightDiligenceHistoricalStatistics", + "lastDataReceivedQuery": "BitSightDiligenceHistoricalStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + }, + { + "name": "BitSightDiligenceStatistics", + "lastDataReceivedQuery": "BitSightDiligenceStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + }, + { + "name": "BitSightObservationStatistics", + "lastDataReceivedQuery": "BitSightObservationStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + }, + { + "name": "BitsightIndustrialStatistics", + "lastDataReceivedQuery": "BitsightIndustrialStatistics\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + }, + { + "name": "BitsightVulnerabilitiesFindingsSummary", + "lastDataReceivedQuery": "BitsightVulnerabilitiesFindingsSummary\n| where TimeGenerated > ago(12h)\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "isPreview": true, + "status": 1 + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "Read and Write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true, + "action": false + } + } + ], + "customs": [ + { + "name": "BitSight API Token", + "description": "A BitSight API Token is required to authenticate requests to the BitSight REST API. [See the documentation](https://help.bitsighttech.com/hc/en-us/articles/115014888388-API-Token-Management) to learn more about API Token management." + } + ] + }, + "instructionSteps": [ + { + "title": "1. Connection Management", + "description": "Manage your BitSight statistics data stream connections", + "instructions": [ + { + "type": "Markdown", + "parameters": { + "content": "## BitSight Statistics Connections\n\nManage multiple BitSight statistics connections. Each connection selects one or more **data streams** to ingest and assigns a **Connection Name** stored in the `connectionName` column of every ingested record.\n\n> **Authentication**: BitSight uses HTTP Basic Authentication with your API Token." + } + }, + { + "type": "DataConnectorsGrid", + "parameters": { + "mapping": [ + { + "columnName": "Connection Name", + "columnValue": "properties.addOnAttributes.connectionName" + }, + { + "columnName": "Data Type", + "columnValue": "properties.dataType" + }, + { + "columnName": "API URL", + "columnValue": "properties.request.apiEndpoint" + } + ], + "menuItems": [ + "DeleteConnector" + ] + } + }, + { + "type": "ContextPane", + "parameters": { + "isPrimary": true, + "label": "Add Connection", + "title": "Add BitSight Statistics Connection", + "subtitle": "Configure a new BitSight statistics connection", + "contextPaneType": "DataConnectorsContextPane", + "instructionSteps": [ + { + "instructions": [ + { + "type": "Markdown", + "parameters": { + "content": "## 1. Select Data Streams\n\nChoose which BitSight statistics data types to collect for this connection. You can select multiple streams." + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Data Streams", + "name": "streams", + "options": [ + { "key": "FindingsSummary", "text": "FindingsSummary" }, @@ -7257,28 +7853,16 @@ { "type": "Markdown", "parameters": { - "content": "## 3. Authentication\n\nBitSight uses your API token as **both** the username and password for HTTP Basic Authentication." + "content": "## 3. Authentication\n\nProvide your BitSight API Token. It authenticates requests to the BitSight REST API using HTTP Basic Authentication." } }, { "type": "Textbox", "parameters": { - "label": "BitSight API Token (Username)", + "label": "BitSight API Token", "placeholder": "Paste your BitSight API Token", - "type": "text", - "name": "username", - "validations": { - "required": true - } - } - }, - { - "type": "Textbox", - "parameters": { - "label": "BitSight API Token (Password)", - "placeholder": "Paste your BitSight API Token again", "type": "password", - "name": "password", + "name": "apiToken", "validations": { "required": true } @@ -7413,13 +7997,8 @@ "type": "securestring", "minLength": 1 }, - "username": { - "defaultValue": "username", - "type": "securestring", - "minLength": 1 - }, - "password": { - "defaultValue": "password", + "apiToken": { + "defaultValue": "apiToken", "type": "securestring", "minLength": 1 }, @@ -7467,9 +8046,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -7557,9 +8137,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -7645,9 +8226,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -7735,9 +8317,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -7825,9 +8408,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -7915,9 +8499,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -8005,9 +8590,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "[[concat(parameters('bitSightApiUrl'), '/ratings/v2/portfolio')]", @@ -8095,9 +8681,10 @@ "kind": "RestApiPoller", "properties": { "auth": { - "type": "Basic", - "UserName": "[[parameters('username')]", - "Password": "[[parameters('password')]" + "type": "APIKey", + "ApiKey": "[[base64(concat(parameters('apiToken'), ':'))]", + "ApiKeyName": "Authorization", + "ApiKeyIdentifier": "Basic" }, "request": { "apiEndpoint": "https://service.bitsighttech.com/customer-api/v1/defaults/vulnerabilities", @@ -8157,7 +8744,7 @@ "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.2.0", + "version": "3.2.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "BitSight", diff --git a/Solutions/BitSight/Parsers/BitSightDiligenceStatistics.yaml b/Solutions/BitSight/Parsers/BitSightDiligenceStatistics.yaml index 25d8396bbf6..d96683efdd3 100644 --- a/Solutions/BitSight/Parsers/BitSightDiligenceStatistics.yaml +++ b/Solutions/BitSight/Parsers/BitSightDiligenceStatistics.yaml @@ -1,8 +1,8 @@ id: 3900f610-56b5-4f8f-84f4-291d9b41dfe2 Function: Title: Parser for BitSightDiligenceStatistics - Version: '1.1.0' - LastUpdated: '2026-05-25' + Version: '1.2.0' + LastUpdated: '2026-07-30' Category: Microsoft Sentinel Parser FunctionName: BitSightDiligenceStatistics FunctionAlias: BitSightDiligenceStatistics @@ -46,6 +46,7 @@ FunctionQuery: | ), ( BitSightDiligenceStatistics_CL + | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector | extend EventVendor = "BitSight", EventProduct = "DiligenceStatistics" diff --git a/Solutions/BitSight/Parsers/BitSightIndustrialStatistics.yaml b/Solutions/BitSight/Parsers/BitSightIndustrialStatistics.yaml index 170b0f5e058..4d3b120858f 100644 --- a/Solutions/BitSight/Parsers/BitSightIndustrialStatistics.yaml +++ b/Solutions/BitSight/Parsers/BitSightIndustrialStatistics.yaml @@ -1,8 +1,8 @@ id: 44c51bc8-1c06-46ca-ba25-0422d0af4015 Function: Title: Parser for BitSightIndustrialStatistics - Version: '1.1.0' - LastUpdated: '2026-05-25' + Version: '1.2.0' + LastUpdated: '2026-07-30' Category: Microsoft Sentinel Parser FunctionName: BitSightIndustrialStatistics FunctionAlias: BitSightIndustrialStatistics @@ -30,6 +30,7 @@ FunctionQuery: | ), ( BitsightIndustrialStatistics_CL + | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector | extend EventVendor = "BitSight", EventProduct = "IndustrialStatistics" diff --git a/Solutions/BitSight/Parsers/BitSightObservationStatistics.yaml b/Solutions/BitSight/Parsers/BitSightObservationStatistics.yaml index 91b7edb8ded..584d25b73fa 100644 --- a/Solutions/BitSight/Parsers/BitSightObservationStatistics.yaml +++ b/Solutions/BitSight/Parsers/BitSightObservationStatistics.yaml @@ -1,8 +1,8 @@ id: 144a9fa0-98a3-40f7-b39e-9c7ff0229290 Function: Title: Parser for BitSightObservationStatistics - Version: '1.1.0' - LastUpdated: '2026-05-25' + Version: '1.2.0' + LastUpdated: '2026-07-30' Category: Microsoft Sentinel Parser FunctionName: BitSightObservationStatistics FunctionAlias: BitSightObservationStatistics @@ -30,6 +30,7 @@ FunctionQuery: | ), ( BitSightObservationStatistics_CL + | summarize arg_max(TimeGenerated, *) by CompanyGuid, RiskVector | extend EventVendor = "BitSight", EventProduct = "ObservationStatistics" diff --git a/Solutions/BitSight/ReleaseNotes.md b/Solutions/BitSight/ReleaseNotes.md index f85801603ea..abe8a957c9a 100644 --- a/Solutions/BitSight/ReleaseNotes.md +++ b/Solutions/BitSight/ReleaseNotes.md @@ -1,5 +1,6 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|--------------------------------------------------------------------| +| 3.2.1 | 30-07-2026 | Added arg_max(TimeGenerated, *) de-duplication across the BitSight statistics parsers so snapshot tables return only the latest record per entity, and simplified connector authentication to a single API Token field (HTTP Basic authentication with the token as the username) for both the BitSight Security Statistics and BitSight Security Events connectors. | | 3.2.0 | 15-06-2026 | Replaced legacy Function App connector with two **Codeless Connector Framework (CCF)** connectors: **BitSight Security Events** (Alerts, Breaches, Findings) and **BitSight Security Statistics** (CompanyDetails, CompanyRatingDetails, DiligenceHistoricalStatistics, DiligenceStatistics, ObservationStatistics, IndustrialStatistics, VulnerabilitiesFindingsSummary, FindingsSummary). Added parsers for **BitSightCompanyRatingDetails** and **BitSightVulnerabilitiesFindingsSummary**. Updated Function App UI page for Log Ingestion API. | | 3.1.1 | 22-04-2026 | Updated **Solution Package** with the fix of solutionId | | 3.1.0 | 31-03-2026 | Updated the python runtime version to 3.12. Added support for Log Ingestion API and updated parsers accordingly.
Reverted the solution id to fix the BitSight Solution publishing issue. |