{
  "name": "NordStellarPush",
  "apiVersion": "2022-09-01-preview",
  "type": "Microsoft.SecurityInsights/dataConnectorDefinitions",
  "location": "[parameters('workspace-location')]",
  "kind": "Customizable",
  "properties": {
    "connectorUiConfig": {
      "id": "NordStellarPush",
      "title": "NordStellar (Push)",
      "publisher": "Nord Security Inc.",
      "descriptionMarkdown": "The [NordStellar](https://nordlayer.com/intelligence/) connector pushes real-time threat intelligence and exposure events from the NordStellar platform into Microsoft Sentinel using the Codeless Connector Framework (CCF) Push pattern. All event types are routed to a single unified `NordStellar_CL` table with common columns (`EventTime`, `EventId`, `EventType`, `Module`, `RiskLevel`, `AssetType`, `AssetValue`, `Tags`) extracted by the DCR's KQL transform, while type-specific payload is preserved in a dynamic `Details` column.\n\n**Supported event types:**\n\n- **Leaked Data** (`module: LEAKED_DATA`): `DATA_BREACH`, `COMBO_LIST`, `MALWARE_INFECTION`, `CONSUMER_CREDENTIAL`\n- **Dark Web Monitoring** (`module: DARK_WEB_MONITORING`): `DARK_WEB_FORUM_POST`, `DARK_WEB_TELEGRAM_POST`, `DARK_WEB_RANSOMWARE_POST`, `DARK_WEB_MARKETPLACE_POST`\n- **Domain Squatting** (`module: DOMAIN_SQUATTING`): `DOMAIN_PERMUTATION`\n- **Attack Surface** (`module: ATTACK_SURFACE`): `ATTACK_SURFACE_WEB_APPLICATION_VULNERABILITY`, `ATTACK_SURFACE_NETWORK_SERVICE_VULNERABILITY`, `ATTACK_SURFACE_DNS_VULNERABILITY`",
      "graphQueries": [
        {
          "metricName": "NordStellar events",
          "legend": "NordStellar_CL",
          "baseQuery": "NordStellar_CL"
        }
      ],
      "sampleQueries": [
        {
          "description": "Critical and High severity events (last 24h)",
          "query": "NordStellar_CL\n| where TimeGenerated > ago(24h)\n| where RiskLevel in (\"CRITICAL\", \"HIGH\")\n| project TimeGenerated, EventTime, EventType, RiskLevel, AssetType, AssetValue\n| order by TimeGenerated desc"
        },
        {
          "description": "Event volume by event type (last 7d)",
          "query": "NordStellar_CL\n| where TimeGenerated > ago(7d)\n| summarize count() by EventType\n| order by count_ desc"
        },
        {
          "description": "Attack surface vulnerabilities with CVSS3 >= 7",
          "query": "NordStellar_CL\n| where EventType startswith \"ATTACK_SURFACE_\"\n| extend Cvss3 = todouble(Details.cvss3_score), Cve = tostring(Details.cve_id), Title = tostring(Details['title'])\n| where Cvss3 >= 7\n| project TimeGenerated, EventType, RiskLevel, AssetValue, Title, Cve, Cvss3\n| order by Cvss3 desc"
        },
        {
          "description": "Malware infections by stealer family",
          "query": "NordStellar_CL\n| where EventType == \"MALWARE_INFECTION\"\n| extend Stealer = tostring(Details.stealer_name)\n| summarize count() by Stealer\n| order by count_ desc"
        },
        {
          "description": "Domain permutations (typosquatting)",
          "query": "NordStellar_CL\n| where EventType == \"DOMAIN_PERMUTATION\"\n| project TimeGenerated, EventTime, RiskLevel, OriginalDomain = tostring(Details.original_domain), PermutedDomain = tostring(Details.domain), PermutationType = tostring(Details.permutation_type)\n| order by TimeGenerated desc"
        }
      ],
      "dataTypes": [
        {
          "name": "NordStellar_CL",
          "lastDataReceivedQuery": "NordStellar_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)"
        }
      ],
      "connectivityCriteria": [
        {
          "type": "IsConnectedQuery",
          "value": [
            "NordStellar_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(7d)"
          ]
        }
      ],
      "availability": {
        "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
            }
          }
        ],
        "customs": [
          {
            "name": "Microsoft Entra",
            "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher."
          },
          {
            "name": "Microsoft Azure",
            "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role."
          },
          {
            "name": "NordStellar",
            "description": "Active NordStellar tenant with permission to configure outbound webhooks for the integration."
          }
        ]
      },
      "instructionSteps": [
        {
          "title": "1. Deploy connector resources",
          "description": "This connector enables NordStellar to push real-time threat intelligence and exposure events directly to Microsoft Sentinel via the Azure Monitor Ingestion API.",
          "instructions": [
            {
              "type": "Markdown",
              "parameters": {
                "content": "#### Automated configuration\nClicking **Deploy** will create:\n- A custom Log Analytics table `NordStellar_CL`\n- A Data Collection Rule (DCR) with a single stream `Custom-NordStellar` and a KQL transform that promotes common fields and preserves the type-specific payload in `Details`\n- The Data Collection Endpoint (DCE) used for ingestion\n- A Microsoft Entra application with OAuth 2.0 client credentials\n- The required `Monitoring Metrics Publisher` role assignment on the DCR\n\nThe credentials returned below are then configured in the NordStellar portal so events can be pushed securely."
              }
            },
            {
              "type": "DeployPushConnectorButton",
              "parameters": {
                "label": "Deploy NordStellar Push connector resources",
                "applicationDisplayName": "NordStellar Sentinel Push Connector Application"
              }
            }
          ]
        },
        {
          "title": "2. Configure NordStellar",
          "description": "Use the following parameters to configure the Microsoft Sentinel integration in the NordStellar portal.",
          "instructions": [
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Tenant ID (Directory ID)",
                "fillWith": ["TenantId"]
              }
            },
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Application (Client) ID",
                "fillWith": ["ApplicationId"],
                "placeholder": "Deploy push connector to get the Application ID"
              }
            },
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Client Secret",
                "fillWith": ["ApplicationSecret"],
                "placeholder": "Deploy push connector to get the Client Secret"
              }
            },
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Data Collection Endpoint URI",
                "fillWith": ["DataCollectionEndpoint"],
                "placeholder": "Deploy push connector to get the DCE Endpoint"
              }
            },
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Data Collection Rule Immutable ID",
                "fillWith": ["DataCollectionRuleId"],
                "placeholder": "Deploy push connector to get the DCR Immutable ID"
              }
            },
            {
              "type": "CopyableLabel",
              "parameters": {
                "label": "Stream Name",
                "value": "Custom-NordStellar"
              }
            },
            {
              "type": "Markdown",
              "parameters": {
                "content": "#### On-the-wire envelope\nNordStellar must POST a JSON array to `{DCE URI}/dataCollectionRules/{DCR Immutable ID}/streams/Custom-NordStellar?api-version=2023-01-01` with an OAuth bearer token for the scope `https://monitor.azure.com//.default`.\n\nEach element wraps the original webhook event in a thin envelope:\n\n```json\n[\n  {\n    \"time\": \"2026-04-27T10:30:00Z\",\n    \"event\": {\n      \"id\": \"...\",\n      \"type\": \"DATA_BREACH\",\n      \"module\": \"LEAKED_DATA\",\n      \"risk_level\": \"HIGH\",\n      \"date_added\": \"...\",\n      \"tags\": [\"NAME\"],\n      \"asset\": { \"type\": \"EMAIL\", \"value\": \"user@company.com\" }\n    }\n  }\n]\n```\n\nThe DCR's KQL transform promotes `id`, `type`, `module`, `risk_level`, `asset.type`/`source_type`, `asset.value`/`asset_value`, and `tags` into typed columns. `TimeGenerated` is set to the ingestion time so historical events are never dropped by retention checks, while the original event timestamp (`detected_at` for attack-surface/domain-permutation, `date_added` otherwise) is preserved in `EventTime`. Everything else is preserved in the dynamic `Details` column."
              }
            }
          ]
        },
        {
          "title": "3. Verify data ingestion",
          "description": "Confirm events are flowing from NordStellar to Sentinel.",
          "instructions": [
            {
              "type": "Markdown",
              "parameters": {
                "content": "Wait 5-10 minutes after enabling the integration, then run this KQL query in your Microsoft Sentinel workspace:\n\n```kql\nNordStellar_CL\n| where TimeGenerated > ago(1h)\n| summarize count() by EventType, Module\n| order by count_ desc\n```\n\nIf no data appears after 15 minutes, verify the credentials in the NordStellar portal and check Azure Monitor for ingestion errors on the DCR."
              }
            }
          ]
        }
      ]
    }
  }
}
