Spur Context API Custom Connector#14148
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds the Spur Context API Solution to Microsoft Sentinel, providing a custom connector plus incident/alert-triggered playbooks for IP enrichment and optional Log Analytics ingestion.
Changes:
- Added solution metadata + solution data manifest for the Spur solution.
- Added two playbooks (Incident + Alert triggers) and a Spur Context API custom connector ARM template + docs.
- Added initial release notes and solution README documentation.
Reviewed changes
Copilot reviewed 12 out of 23 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| Solutions/Spur/readme.md | Adds solution-level documentation (overview, enrichment use case, app registration, deploy order). |
| Solutions/Spur/SolutionMetadata.json | Defines marketplace/solution metadata (publisher/offer, categories, support). |
| Solutions/Spur/ReleaseNotes.md | Adds initial version entry for the solution. |
| Solutions/Spur/Playbooks/Spur-Get-IP-Context-Data-Incident-Trigger/readme.md | Documents the incident-trigger IP enrichment playbook and deployment steps. |
| Solutions/Spur/Playbooks/Spur-Get-IP-Context-Data-Incident-Trigger/azuredeploy.json | ARM template for incident-trigger playbook + connections + optional custom log ingestion. |
| Solutions/Spur/Playbooks/Spur-Get-IP-Context-Data-Alert-Trigger/readme.md | Documents the alert-trigger IP enrichment playbook and deployment steps. |
| Solutions/Spur/Playbooks/Spur-Get-IP-Context-Data-Alert-Trigger/azuredeploy.json | ARM template for alert-trigger playbook + connections + optional custom log ingestion. |
| Solutions/Spur/Playbooks/Custom Connector/readme.md | Documents the Spur custom connector and required permissions/DCR+DCE setup. |
| Solutions/Spur/Playbooks/Custom Connector/azuredeploy.json | ARM template for custom connector plus Log Analytics table + DCE + DCR provisioning. |
| Solutions/Spur/Package/testParameters.json | Ignored from review (Solutions//Package/ excluded). |
| Solutions/Spur/Package/createUiDefinition.json | Ignored from review (Solutions//Package/ excluded). |
| Solutions/Spur/Data/Solution_Spur.json | Defines the solution content manifest (playbooks list, versioning, metadata linkage). |
| | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | | ||
| |-------------|--------------------------------|---------------------------------------------| | ||
| | 3.0.0 | 25-04-2026 | Initial Solution Release | |
There was a problem hiding this comment.
The release notes table rows include an extra leading | which makes the table formatting invalid (and can be interpreted as extra empty columns). Update the table to have exactly 3 columns with a single leading/trailing | per row as required.
| @@ -0,0 +1,15 @@ | |||
| { | |||
| "publisherId": "spur1680448518850", | |||
There was a problem hiding this comment.
publisherId must match an approved publisher identifier (or a pre-approved custom one). "spur1680448518850" is not one of the approved values (azuresentinel, microsoftsentinelcommunity), so this will fail solution-metadata validation unless it has been pre-approved—please update to an approved/pre-approved publisherId.
| "publisherId": "spur1680448518850", | |
| "publisherId": "microsoftsentinelcommunity", |
| @@ -0,0 +1,17 @@ | |||
| { | |||
| "Name": "Spur", | |||
| "Author": "Spur", | |||
There was a problem hiding this comment.
Multiple solution-data validation issues:
Authormust include contact info in the format{Organization} - {email}(e.g.,Spur - support@spur.com).
| "Author": "Spur", | |
| "Author": "Spur - support@spur.com", |
| "Version": "3.0.0", | ||
| "Metadata": "SolutionMetadata.json", | ||
| "TemplateSpec": true, |
There was a problem hiding this comment.
Multiple solution-data validation issues:
Authormust include contact info in the format{Organization} - {email}(e.g.,Spur - support@spur.com).
| "Playbooks": [ | ||
| "Playbooks/Custom Connector/azuredeploy.json", | ||
| "Playbooks/Spur-Get-IP-Context-Data-Incident-Trigger/azuredeploy.json", | ||
| "Playbooks/Spur-Get-IP-Context-Data-Alert-Trigger/azuredeploy.json" | ||
| ], |
There was a problem hiding this comment.
The playbook/custom-connector path includes a folder with a space (Playbooks/Custom Connector/), which violates the repository Playbooks naming/file-structure conventions (no spaces; Custom Connectors must live under Playbooks/CustomConnector/<Name>CustomConnector/). Rename/restructure the custom connector folder accordingly and update this manifest path to match.
| }, | ||
| { | ||
| "type": "Microsoft.Logic/workflows", | ||
| "apiVersion": "2017-07-01", |
There was a problem hiding this comment.
The Logic App workflow resource should use apiVersion 2019-05-01 per Sentinel playbook ARM template requirements. Using 2017-07-01 can break template validation and Gallery packaging—please update the workflow resource apiVersion accordingly.
| "apiVersion": "2017-07-01", | |
| "apiVersion": "2019-05-01", |
| "type": "String", | ||
| "metadata": { | ||
| "description": "Name of the Logic App/Playbook" | ||
| } | ||
| }, | ||
| "SpurConnectorName": { | ||
| "defaultValue": "Spur-Context-Connector", | ||
| "type": "String", |
There was a problem hiding this comment.
ARM template parameter type values should use standard lowercase ARM types (string, bool, secureString, object, etc.). Using String/Bool/SecureString/Object may fail repo validation tooling—please normalize these types.
| "type": "String", | |
| "metadata": { | |
| "description": "Name of the Logic App/Playbook" | |
| } | |
| }, | |
| "SpurConnectorName": { | |
| "defaultValue": "Spur-Context-Connector", | |
| "type": "String", | |
| "type": "string", | |
| "metadata": { | |
| "description": "Name of the Logic App/Playbook" | |
| } | |
| }, | |
| "SpurConnectorName": { | |
| "defaultValue": "Spur-Context-Connector", | |
| "type": "string", |
| "name": "access_token_body", | ||
| "type": "string", | ||
| "value": "@{concat(concat(concat(concat('grant_type=client_credentials&client_id=',parameters('ClientID')),'&client_secret='),parameters('ClientSecret')),'&scope=https://monitor.azure.com/.default')}" | ||
| }, |
There was a problem hiding this comment.
This concatenates ClientSecret into a plain string variable (access_token_body), which can expose the secret in Logic App run history, inputs/outputs, and diagnostics. Avoid storing secrets in variables; instead pass the secret directly as a secure parameter into the HTTP action with secure inputs/outputs enabled (or enable secureData masking on the relevant actions).
| "[variables('tableName')]", | ||
| "[parameters('DCEName')]" |
There was a problem hiding this comment.
dependsOn must reference resource IDs, not a table name variable or parameter value. As written, this dependency won’t ensure correct deployment ordering and can cause ARM validation failures. Use resourceId(...) references to the workspace table resource and the data collection endpoint resource.
| "[variables('tableName')]", | |
| "[parameters('DCEName')]" | |
| "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspaceName'), variables('tableName'))]", | |
| "[resourceId('Microsoft.Insights/dataCollectionEndpoints', parameters('DCEName'))]" |
| "configurationAccess": { | ||
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.handler.control.monitor.azure.com')]" | ||
| }, | ||
| "logsIngestion": { | ||
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.ingest.monitor.azure.com')]" | ||
| }, | ||
| "metricsIngestion": { | ||
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.metrics.ingest.monitor.azure.com')]" | ||
| }, |
There was a problem hiding this comment.
These endpoint fields for Microsoft.Insights/dataCollectionEndpoints are typically system-generated/read-only values, and hardcoding region-specific hostnames is fragile and may fail ARM deployment. Prefer letting Azure provision the endpoint and then output the ingestion URI, rather than attempting to set these properties.
| "configurationAccess": { | |
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.handler.control.monitor.azure.com')]" | |
| }, | |
| "logsIngestion": { | |
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.ingest.monitor.azure.com')]" | |
| }, | |
| "metricsIngestion": { | |
| "endpoint": "[concat('https://', parameters('DCEName'), '-eawp.', parameters('location'), '-1.metrics.ingest.monitor.azure.com')]" | |
| }, |
Remove redundant top-level headers and compress file to only the version table. Also added a trailing period to the 3.0.0 release entry for punctuation consistency.


Spur Context API provides access to the highest-fidelity IP intelligence available on-demand, delivering the right IP enriched data in real-time to protect digital assets from the risk of obscured VPN, residential proxy, and bot automation traffic. This solution includes playbooks for IP enrichment on incidents and alerts, with context data added to incident comments and optionally saved in Log Analytics custom tables.