Skip to content

Commit b541ea9

Browse files
committed
Add Panorays Sentinel Solution
1 parent 59e0373 commit b541ea9

15 files changed

+1840
-0
lines changed

Solutions/Panorays/Data Connectors/Panorays_ccp/DCR.json

Lines changed: 694 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"workspaceName": { "type": "string", "metadata": { "description": "Log Analytics Workspace Name (Not ID)" } },
6+
"location": { "type": "string", "defaultValue": "eastus" },
7+
"panoraysAPIBaseUrl": { "type": "string", "defaultValue": "https://api.panoraysapp.com" },
8+
"apitoken": { "type": "securestring" }
9+
},
10+
"variables": {
11+
"dceName": "Panorays-Manual-DCE",
12+
"dcrName": "Panorays-Manual-DCR",
13+
"tableName": "PanoraysCompanyFindingPOC_CL",
14+
"connectorDefinitionName": "ccpPanoraysCompanyFindingPOC",
15+
"connectorInstanceName": "Panorays-Manual-Instance"
16+
},
17+
"resources": [
18+
{
19+
"type": "Microsoft.Insights/dataCollectionEndpoints",
20+
"apiVersion": "2021-09-01-preview",
21+
"name": "[variables('dceName')]",
22+
"location": "[parameters('location')]",
23+
"properties": {
24+
"networkAcls": { "publicNetworkAccess": "Enabled" }
25+
}
26+
},
27+
{
28+
"type": "Microsoft.OperationalInsights/workspaces/tables",
29+
"apiVersion": "2022-10-01",
30+
"name": "[concat(parameters('workspaceName'), '/', variables('tableName'))]",
31+
"location": "[parameters('location')]",
32+
"properties": {
33+
"schema": {
34+
"name": "[variables('tableName')]",
35+
"columns": [
36+
{ "name": "TimeGenerated", "type": "datetime" },
37+
{ "name": "FindingKey", "type": "string" },
38+
{ "name": "status", "type": "string" },
39+
{ "name": "severity", "type": "string" },
40+
{ "name": "asset_name", "type": "string" },
41+
{ "name": "cves", "type": "dynamic" },
42+
{ "name": "finding_text", "type": "string" },
43+
{ "name": "description", "type": "string" }
44+
]
45+
}
46+
}
47+
},
48+
{
49+
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions",
50+
"apiVersion": "2022-09-01-preview",
51+
"name": "[concat(parameters('workspaceName'), '/Microsoft.SecurityInsights/', variables('connectorDefinitionName'))]",
52+
"location": "[parameters('location')]",
53+
"kind": "Customizable",
54+
"properties": {
55+
"connectorUiConfig": {
56+
"id": "[variables('connectorDefinitionName')]",
57+
"title": "Panorays (Manual)",
58+
"publisher": "Microsoft",
59+
"descriptionMarkdown": "Manually deployed Panorays Connector for testing.",
60+
"graphQueriesTableName": "[variables('tableName')]",
61+
"graphQueries": [
62+
{ "metricName": "Total findings", "legend": "Findings", "baseQuery": "{{graphQueriesTableName}}" }
63+
],
64+
"sampleQueries": [
65+
{ "description": "Get Sample Data", "query": "{{graphQueriesTableName}} | take 10" }
66+
],
67+
"dataTypes": [
68+
{ "name": "{{graphQueriesTableName}}", "lastDataReceivedQuery": "{{graphQueriesTableName}} | summarize Time = max(TimeGenerated) | where isnotempty(Time)" }
69+
],
70+
"connectivityCriteria": [ { "type": "HasDataConnectors" } ],
71+
"permissions": { "resourceProvider": [ { "provider": "Microsoft.OperationalInsights/workspaces", "permissionsDisplayText": "Read and Write", "providerDisplayName": "Workspace", "scope": "Workspace", "requiredPermissions": { "read": true, "write": true, "delete": true } } ] },
72+
"instructionSteps": [
73+
{
74+
"instructions": [
75+
{ "type": "Markdown", "parameters": { "content": "Manual Deployment Test" } }
76+
]
77+
}
78+
]
79+
}
80+
}
81+
},
82+
{
83+
"type": "Microsoft.Insights/dataCollectionRules",
84+
"apiVersion": "2021-09-01-preview",
85+
"name": "[variables('dcrName')]",
86+
"location": "[parameters('location')]",
87+
"dependsOn": [
88+
"[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dceName'))]",
89+
"[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), variables('tableName'))]"
90+
],
91+
"properties": {
92+
"dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dceName'))]",
93+
"streamDeclarations": {
94+
"Custom-PanoraysStream": {
95+
"columns": [
96+
{ "name": "id", "type": "string" },
97+
{ "name": "status", "type": "string" },
98+
{ "name": "severity", "type": "string" },
99+
{ "name": "asset_name", "type": "string" },
100+
{ "name": "cves", "type": "string" },
101+
{ "name": "finding_text", "type": "string" },
102+
{ "name": "description", "type": "string" }
103+
]
104+
}
105+
},
106+
"destinations": {
107+
"logAnalytics": [
108+
{
109+
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName'))]",
110+
"name": "law"
111+
}
112+
]
113+
},
114+
"dataFlows": [
115+
{
116+
"streams": [ "Custom-PanoraysStream" ],
117+
"destinations": [ "law" ],
118+
"transformKql": "source | project TimeGenerated = now(), FindingKey = id, status, severity, asset_name, cves, finding_text, description",
119+
"outputStream": "[concat('Custom-', variables('tableName'))]"
120+
}
121+
]
122+
}
123+
},
124+
{
125+
"type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
126+
"apiVersion": "2022-09-01-preview",
127+
"name": "[concat(parameters('workspaceName'), '/Microsoft.SecurityInsights/', variables('connectorInstanceName'))]",
128+
"location": "[parameters('location')]",
129+
"dependsOn": [
130+
"[resourceId('Microsoft.Insights/dataCollectionRules', variables('dcrName'))]",
131+
"[resourceId('Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions', parameters('workspaceName'), 'Microsoft.SecurityInsights', variables('connectorDefinitionName'))]"
132+
],
133+
"kind": "RestApiPoller",
134+
"properties": {
135+
"connectorDefinitionName": "[variables('connectorDefinitionName')]",
136+
"dataType": "[variables('tableName')]",
137+
"dcrConfig": {
138+
"streamName": "Custom-PanoraysStream",
139+
"dataCollectionEndpoint": "[reference(resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dceName')), '2021-09-01-preview').logsIngestion.endpoint]",
140+
"dataCollectionRuleImmutableId": "[reference(resourceId('Microsoft.Insights/dataCollectionRules', variables('dcrName')), '2021-09-01-preview').immutableId]"
141+
},
142+
"auth": {
143+
"type": "APIKey",
144+
"ApiKey": "[parameters('apitoken')]",
145+
"ApiKeyName": "Authorization",
146+
"ApiKeyIdentifier": "Bearer"
147+
},
148+
"request": {
149+
"apiEndpoint": "[concat(parameters('panoraysAPIBaseUrl'), '/v2/findings')]",
150+
"rateLimitQPS": 10,
151+
"queryWindowInMin": 1,
152+
"httpMethod": "GET",
153+
"headers": {
154+
"Accept": "application/json",
155+
"User-Agent": "PanoraysIntegration/1.0"
156+
}
157+
},
158+
"paging": {
159+
"pagingType": "NextPageToken",
160+
"PageSize": 100,
161+
"PageSizeParameterName": "limit",
162+
"NextPageTokenJsonPath": "$.pagination.nextCursor",
163+
"NextPageParaName": "cursor"
164+
},
165+
"response": { "eventsJsonPaths": [ "$.data" ] }
166+
}
167+
}
168+
]
169+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"name": "ccpPanoraysCompanyFindingPOC",
3+
"apiVersion": "2024-01-01-preview",
4+
"type": "Microsoft.SecurityInsights/dataConnectorDefinitions",
5+
"kind": "Customizable",
6+
"properties": {
7+
"connectorUiConfig": {
8+
"id": "ccpPanoraysCompanyFindingPOC",
9+
"title": "Panorays",
10+
"publisher": "Microsoft",
11+
"descriptionMarkdown": "The [Panorays](https://panorays-papi-v2-documentation.redocly.app/#api-access) data connector allows ingesting company findings from the Panorays API into Microsoft Sentinel. The data connector is built on Microsoft Sentinel Codeless Connector Platform. It uses the Panorays API to fetch data and it supports DCR-based [ingestion time transformations](https://docs.microsoft.com/azure/azure-monitor/logs/custom-logs-overview) that parses the received security data into a custom table so that queries don't need to parse it again, thus resulting in better performance.",
12+
"graphQueriesTableName": "PanoraysCompanyFindingPOC_CL",
13+
"graphQueries": [
14+
{
15+
"metricName": "Total findings found",
16+
"legend": "Comnapny Findings",
17+
"baseQuery": "{{graphQueriesTableName}}"
18+
}
19+
],
20+
"sampleQueries": [
21+
{
22+
"description": "Get Sample of Panorays Company Findings",
23+
"query": "{{graphQueriesTableName}}\n | take 10"
24+
}
25+
],
26+
"dataTypes": [
27+
{
28+
"name": "{{graphQueriesTableName}}",
29+
"lastDataReceivedQuery": "{{graphQueriesTableName}}\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
30+
}
31+
],
32+
"connectivityCriteria": [
33+
{
34+
"type": "HasDataConnectors",
35+
"value": null
36+
}
37+
],
38+
"availability": {
39+
"status": 1,
40+
"isPreview": false
41+
},
42+
"permissions": {
43+
"tenant": null,
44+
"licenses": null,
45+
"resourceProvider": [
46+
{
47+
"provider": "Microsoft.OperationalInsights/workspaces",
48+
"permissionsDisplayText": "Read and Write permissions are required.",
49+
"providerDisplayName": "Workspace",
50+
"scope": "Workspace",
51+
"requiredPermissions": {
52+
"read": true,
53+
"write": true,
54+
"delete": true,
55+
"action": false
56+
}
57+
}
58+
]
59+
},
60+
"instructionSteps": [
61+
{
62+
"instructions": [
63+
{
64+
"type": "Markdown",
65+
"parameters": {
66+
"content": "#### Configuration steps for the Panorays API \n Follow the instructions to obtain the credentials. "
67+
}
68+
},
69+
{
70+
"type": "Markdown",
71+
"parameters": {
72+
"content": "#### 1. Retrieve Panorays API Token from here: https://www.panoraysapp.com/profile/api_tokens"
73+
}
74+
},
75+
{
76+
"type": "Markdown",
77+
"parameters": {
78+
"content": "#### 2. Retrieve API Token\n 2.1. Log in to the Panorays App\n 2.2. In the Panorays App, click [**Company Settings**] -> [**API Tokens**]\n 2.3. Click on [**Generate Token**] button.\n 2.4. Enter a token name and select the permissions.\n 2.5. Click on [**Generate Token**] and [**Copy API Token**]\n 2.6. Paste the Token here"
79+
}
80+
},
81+
{
82+
"parameters": {
83+
"label": "Panorays API Base URL",
84+
"placeholder": "https://api.panoraysapp.com",
85+
"type": "text",
86+
"name": "panoraysAPIBaseUrl"
87+
},
88+
"type": "Textbox"
89+
},
90+
{
91+
"parameters": {
92+
"label": "API Token",
93+
"placeholder": "API Token",
94+
"type": "securestring",
95+
"name": "apitoken"
96+
},
97+
"type": "Textbox"
98+
},
99+
{
100+
"parameters": {
101+
"label": "toggle",
102+
"name": "toggle"
103+
},
104+
"type": "ConnectionToggleButton"
105+
}
106+
]
107+
}
108+
],
109+
"isConnectivityCriteriasMatchSome": false
110+
}
111+
}
112+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
3+
"handler": "Microsoft.Azure.CreateUIDef",
4+
"version": "0.1.2-preview",
5+
"parameters": {
6+
"config": {
7+
"isWizard": false,
8+
"basics": {
9+
"description": "<img src=\"https://panorays.com/wp-content/uploads/2022/07/panorays-logo.svg\" width=\"75px\" height=\"75px\">\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Panorays/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Panorays](https://www.panorays.com/) solution provides ability to bring Panorays company findings to your Microsoft Sentinel Workspace to inform and to examine potential security risks\n\n**Data Connectors:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
10+
"subscription": {
11+
"resourceProviders": [
12+
"Microsoft.OperationsManagement/solutions",
13+
"Microsoft.OperationalInsights/workspaces/providers/alertRules",
14+
"Microsoft.Insights/workbooks",
15+
"Microsoft.Logic/workflows"
16+
]
17+
},
18+
"location": {
19+
"metadata": {
20+
"hidden": "Hiding location, we get it from the log analytics workspace"
21+
},
22+
"visible": false
23+
},
24+
"resourceGroup": {
25+
"allowExisting": true
26+
}
27+
}
28+
},
29+
"basics": [
30+
{
31+
"name": "getLAWorkspace",
32+
"type": "Microsoft.Solutions.ArmApiControl",
33+
"toolTip": "This filters by workspaces that exist in the Resource Group selected",
34+
"condition": "[greater(length(resourceGroup().name),0)]",
35+
"request": {
36+
"method": "GET",
37+
"path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
38+
}
39+
},
40+
{
41+
"name": "workspace",
42+
"type": "Microsoft.Common.DropDown",
43+
"label": "Workspace",
44+
"placeholder": "Select a workspace",
45+
"toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
46+
"constraints": {
47+
"allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
48+
"required": true
49+
},
50+
"visible": true
51+
}
52+
],
53+
"steps": [
54+
{
55+
"name": "configuration",
56+
"label": "Configuration",
57+
"subLabel": {
58+
"preValidation": "API Details",
59+
"postValidation": "Done"
60+
},
61+
"bladeTitle": "Panorays Configuration",
62+
"elements": [
63+
{
64+
"name": "instructions",
65+
"type": "Microsoft.Common.TextBlock",
66+
"options": {
67+
"text": "Please provide your Panorays API details. These will be used to configure the Data Connector automatically."
68+
}
69+
},
70+
{
71+
"name": "panoraysAPIBaseUrl",
72+
"type": "Microsoft.Common.TextBox",
73+
"label": "Panorays API Base URL",
74+
"toolTip": "The base URL for the Panorays API.",
75+
"defaultValue": "https://api.panoraysapp.com",
76+
"constraints": {
77+
"required": true,
78+
"regex": "^https://.+",
79+
"validationMessage": "Please enter a valid URL starting with https://"
80+
}
81+
},
82+
{
83+
"name": "apitoken",
84+
"type": "Microsoft.Common.TextBox",
85+
"label": "API Token",
86+
"toolTip": "Your Panorays API Token.",
87+
"placeholder": "Paste your API Token here",
88+
"constraints": {
89+
"required": true,
90+
"regex": "^\\S+$",
91+
"validationMessage": "The API Token must not contain spaces."
92+
},
93+
"osPlatform": "Linux",
94+
"visible": true,
95+
"password": true
96+
}
97+
]
98+
}
99+
],
100+
"outputs": {
101+
"workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
102+
"location": "[location()]",
103+
"workspace": "[basics('workspace')]",
104+
"resourceGroupName": "[resourceGroup().name]",
105+
"subscription": "[subscription().subscriptionId]",
106+
"panoraysAPIBaseUrl": "[steps('configuration').panoraysAPIBaseUrl]",
107+
"apitoken": "[steps('configuration').apitoken]"
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)