diff --git a/.script/tests/KqlvalidationsTests/CustomFunctions/githubscanaudit.json b/.script/tests/KqlvalidationsTests/CustomFunctions/githubscanaudit.json new file mode 100644 index 00000000000..ec4f6fc43c3 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomFunctions/githubscanaudit.json @@ -0,0 +1,102 @@ +{ + "FunctionName": "githubscanaudit", + "FunctionParameters": [], + "FunctionResultColumns": [ + { + "Name": "TimeGenerated", + "Type": "datetime" + }, + { + "Name": "action_s", + "Type": "string" + }, + { + "Name": "alert_s", + "Type": "string" + }, + { + "Name": "repository_s", + "Type": "string" + }, + { + "Name": "organization_s", + "Type": "string" + }, + { + "Name": "sender_s", + "Type": "string" + }, + { + "Name": "commits_s", + "Type": "string" + }, + { + "Name": "commit_oid_s", + "Type": "string" + }, + { + "Name": "ref_s", + "Type": "string" + }, + { + "Name": "ref_type_s", + "Type": "string" + }, + { + "Name": "rule_s", + "Type": "string" + }, + { + "Name": "comment_s", + "Type": "string" + }, + { + "Name": "deployment_s", + "Type": "string" + }, + { + "Name": "deployment_status_s", + "Type": "string" + }, + { + "Name": "discussion_s", + "Type": "string" + }, + { + "Name": "check_run_s", + "Type": "string" + }, + { + "Name": "key_s", + "Type": "string" + }, + { + "Name": "changes_s", + "Type": "string" + }, + { + "Name": "master_branch_s", + "Type": "string" + }, + { + "Name": "pusher_type_s", + "Type": "string" + }, + { + "Name": "description_s", + "Type": "string" + }, + { + "Name": "event_s", + "Type": "string" + }, + { + "Name": "number_d", + "Type": "real" + }, + { + "Name": "forced_b", + "Type": "bool" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/GitHubAdvancedSecurityAlerts_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/GitHubAdvancedSecurityAlerts_CL.json new file mode 100644 index 00000000000..5c838608070 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/GitHubAdvancedSecurityAlerts_CL.json @@ -0,0 +1,117 @@ +{ + "Name": "GitHubAdvancedSecurityAlerts_CL", + "Properties": [ + { + "Name": "TenantId", + "Type": "string" + }, + { + "Name": "SourceSystem", + "Type": "string" + }, + { + "Name": "TimeGenerated", + "Type": "datetime" + }, + { + "Name": "Type", + "Type": "string" + }, + { + "Name": "_ResourceId", + "Type": "string" + }, + { + "Name": "action_s", + "Type": "string" + }, + { + "Name": "alert_s", + "Type": "string" + }, + { + "Name": "repository_s", + "Type": "string" + }, + { + "Name": "organization_s", + "Type": "string" + }, + { + "Name": "sender_s", + "Type": "string" + }, + { + "Name": "commits_s", + "Type": "string" + }, + { + "Name": "commit_oid_s", + "Type": "string" + }, + { + "Name": "ref_s", + "Type": "string" + }, + { + "Name": "ref_type_s", + "Type": "string" + }, + { + "Name": "rule_s", + "Type": "string" + }, + { + "Name": "comment_s", + "Type": "string" + }, + { + "Name": "deployment_s", + "Type": "string" + }, + { + "Name": "deployment_status_s", + "Type": "string" + }, + { + "Name": "discussion_s", + "Type": "string" + }, + { + "Name": "check_run_s", + "Type": "string" + }, + { + "Name": "key_s", + "Type": "string" + }, + { + "Name": "changes_s", + "Type": "string" + }, + { + "Name": "master_branch_s", + "Type": "string" + }, + { + "Name": "pusher_type_s", + "Type": "string" + }, + { + "Name": "description_s", + "Type": "string" + }, + { + "Name": "event_s", + "Type": "string" + }, + { + "Name": "number_d", + "Type": "real" + }, + { + "Name": "forced_b", + "Type": "bool" + } + ] +} diff --git a/Sample Data/GitHubAdvancedSecurityAlerts_CL.json b/Sample Data/GitHubAdvancedSecurityAlerts_CL.json new file mode 100644 index 00000000000..d7e46447c4a --- /dev/null +++ b/Sample Data/GitHubAdvancedSecurityAlerts_CL.json @@ -0,0 +1,133 @@ +[ + { + "TimeGenerated": "2024-06-01T10:15:00Z", + "action_s": "reopened", + "alert_s": "{\"number\":10,\"created_at\":\"2024-06-01T10:00:00Z\",\"updated_at\":\"2024-06-01T10:15:00Z\",\"url\":\"https://api.github.com/repos/Codertocat/Hello-World/code-scanning/alerts/10\",\"html_url\":\"https://github.com/Codertocat/Hello-World/security/code-scanning/10\",\"state\":\"open\",\"rule\":{\"id\":\"Style/FrozenStringLiteralComment\",\"severity\":\"note\",\"description\":\"Add the frozen_string_literal comment to the top of files to help transition to frozen string literals by default.\"},\"tool\":{\"name\":\"Rubocop\",\"version\":null}}", + "commit_oid_s": "d6e4c75c141dbacecc279b721b8b9393d5405795", + "ref_s": "refs/heads/main", + "repository_s": "{\"id\":186853002,\"name\":\"Hello-World\",\"full_name\":\"Codertocat/Hello-World\",\"private\":false,\"owner\":{\"login\":\"Codertocat\",\"type\":\"User\"},\"url\":\"https://api.github.com/repos/Codertocat/Hello-World\",\"html_url\":\"https://github.com/Codertocat/Hello-World\",\"default_branch\":\"main\"}", + "organization_s": "{\"login\":\"Octocoders\",\"id\":6,\"url\":\"https://api.github.com/orgs/Octocoders\"}", + "sender_s": "{\"login\":\"github\",\"id\":9919,\"type\":\"Organization\",\"site_admin\":false}", + "event_s": "code_scanning_alert", + "rule_s": "", + "alert_s_event": "code_scanning_alert", + "commits_s": "", + "ref_type_s": "", + "comment_s": "", + "deployment_s": "", + "deployment_status_s": "", + "discussion_s": "", + "check_run_s": "", + "key_s": "", + "changes_s": "", + "master_branch_s": "", + "pusher_type_s": "", + "description_s": "", + "number_d": 10, + "forced_b": false + }, + { + "TimeGenerated": "2024-06-01T11:30:00Z", + "action_s": "create", + "alert_s": "{\"number\":5,\"created_at\":\"2024-06-01T11:25:00Z\",\"affected_range\":\">= 1.0.0, < 1.8.0\",\"external_identifier\":\"CVE-2024-12345\",\"ghsa_id\":\"GHSA-xxxx-yyyy-zzzz\",\"severity\":\"high\",\"url\":\"https://api.github.com/repos/Codertocat/Hello-World/vulnerability-alerts/5\"}", + "commit_oid_s": "", + "ref_s": "", + "repository_s": "{\"id\":186853002,\"name\":\"Hello-World\",\"full_name\":\"Codertocat/Hello-World\",\"private\":false,\"owner\":{\"login\":\"Codertocat\",\"type\":\"User\"},\"url\":\"https://api.github.com/repos/Codertocat/Hello-World\",\"html_url\":\"https://github.com/Codertocat/Hello-World\",\"default_branch\":\"main\"}", + "organization_s": "{\"login\":\"Octocoders\",\"id\":6,\"url\":\"https://api.github.com/orgs/Octocoders\"}", + "sender_s": "{\"login\":\"dependabot[bot]\",\"id\":49699333,\"type\":\"Bot\",\"site_admin\":false}", + "event_s": "repository_vulnerability_alert", + "rule_s": "", + "commits_s": "", + "ref_type_s": "", + "comment_s": "", + "deployment_s": "", + "deployment_status_s": "", + "discussion_s": "", + "check_run_s": "", + "key_s": "", + "changes_s": "", + "master_branch_s": "", + "pusher_type_s": "", + "description_s": "", + "number_d": 5, + "forced_b": false + }, + { + "TimeGenerated": "2024-06-01T12:45:00Z", + "action_s": "created", + "alert_s": "{\"number\":3,\"created_at\":\"2024-06-01T12:40:00Z\",\"url\":\"https://api.github.com/repos/Codertocat/Hello-World/secret-scanning/alerts/3\",\"html_url\":\"https://github.com/Codertocat/Hello-World/security/secret-scanning/3\",\"state\":\"open\",\"secret_type\":\"github_personal_access_token\",\"resolution\":null,\"resolved_by\":null,\"resolved_at\":null}", + "commit_oid_s": "", + "ref_s": "", + "repository_s": "{\"id\":186853002,\"name\":\"Hello-World\",\"full_name\":\"Codertocat/Hello-World\",\"private\":false,\"owner\":{\"login\":\"Codertocat\",\"type\":\"User\"},\"url\":\"https://api.github.com/repos/Codertocat/Hello-World\",\"html_url\":\"https://github.com/Codertocat/Hello-World\",\"default_branch\":\"main\"}", + "organization_s": "{\"login\":\"Octocoders\",\"id\":6,\"url\":\"https://api.github.com/orgs/Octocoders\"}", + "sender_s": "{\"login\":\"Codertocat\",\"id\":21031067,\"type\":\"User\",\"site_admin\":false}", + "event_s": "secret_scanning_alert", + "rule_s": "", + "commits_s": "", + "ref_type_s": "", + "comment_s": "", + "deployment_s": "", + "deployment_status_s": "", + "discussion_s": "", + "check_run_s": "", + "key_s": "", + "changes_s": "", + "master_branch_s": "", + "pusher_type_s": "", + "description_s": "", + "number_d": 3, + "forced_b": false + }, + { + "TimeGenerated": "2024-06-01T13:00:00Z", + "action_s": "completed", + "alert_s": "", + "commit_oid_s": "", + "ref_s": "refs/heads/main", + "ref_type_s": "", + "repository_s": "{\"id\":186853002,\"name\":\"Hello-World\",\"full_name\":\"Codertocat/Hello-World\",\"private\":false,\"owner\":{\"login\":\"Codertocat\",\"type\":\"User\"},\"url\":\"https://api.github.com/repos/Codertocat/Hello-World\",\"html_url\":\"https://github.com/Codertocat/Hello-World\",\"default_branch\":\"main\"}", + "organization_s": "{\"login\":\"Octocoders\",\"id\":6,\"url\":\"https://api.github.com/orgs/Octocoders\"}", + "sender_s": "{\"login\":\"Codertocat\",\"id\":21031067,\"type\":\"User\",\"site_admin\":false}", + "check_run_s": "{\"id\":128620228,\"name\":\"Octocoders-linter\",\"status\":\"completed\",\"conclusion\":\"success\",\"started_at\":\"2024-06-01T12:55:00Z\",\"completed_at\":\"2024-06-01T13:00:00Z\",\"url\":\"https://api.github.com/repos/Codertocat/Hello-World/check-runs/128620228\"}", + "event_s": "check_run", + "rule_s": "", + "commits_s": "", + "comment_s": "", + "deployment_s": "", + "deployment_status_s": "", + "discussion_s": "", + "key_s": "", + "changes_s": "", + "master_branch_s": "", + "pusher_type_s": "", + "description_s": "", + "number_d": 0, + "forced_b": false + }, + { + "TimeGenerated": "2024-06-01T14:00:00Z", + "action_s": "push", + "alert_s": "", + "commit_oid_s": "", + "ref_s": "refs/heads/main", + "ref_type_s": "", + "repository_s": "{\"id\":186853002,\"name\":\"Hello-World\",\"full_name\":\"Codertocat/Hello-World\",\"private\":false,\"owner\":{\"login\":\"Codertocat\",\"type\":\"User\"},\"url\":\"https://api.github.com/repos/Codertocat/Hello-World\",\"html_url\":\"https://github.com/Codertocat/Hello-World\",\"default_branch\":\"main\"}", + "organization_s": "{\"login\":\"Octocoders\",\"id\":6,\"url\":\"https://api.github.com/orgs/Octocoders\"}", + "sender_s": "{\"login\":\"Codertocat\",\"id\":21031067,\"type\":\"User\",\"site_admin\":false}", + "commits_s": "[{\"id\":\"abc1234\",\"message\":\"Fix: update dependency versions\",\"timestamp\":\"2024-06-01T14:00:00Z\",\"author\":{\"name\":\"Codertocat\",\"email\":\"sanitized@sanitized.com\"}}]", + "event_s": "push", + "rule_s": "", + "comment_s": "", + "check_run_s": "", + "deployment_s": "", + "deployment_status_s": "", + "discussion_s": "", + "key_s": "", + "changes_s": "", + "master_branch_s": "main", + "pusher_type_s": "user", + "description_s": "", + "number_d": 0, + "forced_b": false + } +] diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/__init__.py b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/__init__.py new file mode 100644 index 00000000000..752b5ea58e1 --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/__init__.py @@ -0,0 +1,91 @@ +import datetime +import logging +import os +import json +import hashlib +import hmac +import azure.functions as func +from azure.identity import DefaultAzureCredential +from azure.monitor.ingestion import LogsIngestionClient +from azure.core.exceptions import HttpResponseError + +github_webhook_secret = os.environ.get('GithubWebhookSecret') +dce_endpoint = os.environ.get('DCE_ENDPOINT') +dcr_rule_id = os.environ.get('DCR_RULE_ID') +dcr_stream_name = os.environ.get('DCR_STREAM_NAME', 'Custom-GitHubAdvancedSecurityAlerts_CL') + +credential = DefaultAzureCredential() +client = LogsIngestionClient(endpoint=dce_endpoint, credential=credential) + +logging.info("GithubWebhookV2: DCE_ENDPOINT=%s, DCR_STREAM_NAME=%s", dce_endpoint, dcr_stream_name) + + +def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse: + logging.info('Info:Current retry count:{}'.format(context.retry_context.retry_count)) + logging.info('Info:Github webhook v2 data connector started') + + # check webhook signature if GitHubWebhookSecret exists + if github_webhook_secret not in (None, '') and not str(github_webhook_secret).isspace(): + hash_object = hmac.new(github_webhook_secret.encode('utf-8'), msg=req.get_body(), digestmod=hashlib.sha256) + expected_signature = "sha256=" + hash_object.hexdigest() + if 'x-hub-signature-256' not in req.headers: + return func.HttpResponse( + "Github webhook signature header is missing.", + status_code=403 + ) + signature_header = req.headers['x-hub-signature-256'] + if not hmac.compare_digest(expected_signature, signature_header): + return func.HttpResponse( + "Github webhook signature verification failed.", + status_code=403 + ) + + req_body = req.get_json() + if "x-github-event" in req.headers: + req_body["event"] = req.headers["x-github-event"] + body = json.dumps(customize_json(json.dumps(req_body))) + logging.info("Info:Converted input json to dict and further to json") + + try: + post_data(body) + logging.info("Info: Github webhook v2 data connector execution completed successfully.") + return func.HttpResponse( + "Github webhook v2 data connector execution completed successfully.", + status_code=200 + ) + except Exception as err: + logging.error("Something wrong. Exception error text: {}".format(err)) + logging.error("Error: Github webhook v2 data connector execution failed with an internal server error.") + raise + + +##################### +######Functions###### +##################### + +def customize_json(input_json): + """Flatten nested objects to JSON strings to match CLv1 column format.""" + required_fields_data = {} + new_json_dict = json.loads(input_json) + for key, value in new_json_dict.items(): + if isinstance(value, dict): + required_fields_data[key] = json.dumps(value, indent=4) + else: + required_fields_data[key] = value + return required_fields_data + + +def post_data(body): + """Send data to Log Analytics via the Logs Ingestion API (CLv2).""" + log_entry = json.loads(body) + log_entry['TimeGenerated'] = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ') + + try: + client.upload(rule_id=dcr_rule_id, stream_name=dcr_stream_name, logs=[log_entry]) + logging.info('Info:Event was ingested via Logs Ingestion API') + except HttpResponseError as e: + logging.error("Upload failed. Response code: {}. Message: {}".format(e.status_code, e.message)) + raise + except Exception as e: + logging.error("Unexpected error during upload: %s (%s)", e, type(e).__name__) + raise diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/function.json b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/function.json new file mode 100644 index 00000000000..e3944226922 --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookConnectorV2/function.json @@ -0,0 +1,19 @@ +{ + "scriptFile": "__init__.py", + "bindings": [ + { + "authLevel": "function", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "$return" + } + ] +} diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2.zip b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2.zip new file mode 100644 index 00000000000..af002d1ea7e Binary files /dev/null and b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2.zip differ diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2_API_FunctionApp.json b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2_API_FunctionApp.json new file mode 100644 index 00000000000..ff587d924ab --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/GithubWebhookV2_API_FunctionApp.json @@ -0,0 +1,183 @@ +{ + "id": "GitHubWebhookV2", + "title": "GitHub (using Webhooks) V2", + "publisher": "Microsoft", + "descriptionMarkdown": "The [GitHub](https://www.github.com) webhook data connector (V2) provides the capability to ingest GitHub subscribed events into Microsoft Sentinel using [GitHub webhook events](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads). This connector uses the Azure Monitor **Logs Ingestion API (CLv2)** with **Managed Identity** authentication and is the designated successor to the original GitHub (using Webhooks) connector, which uses the CLv1 HTTP Data Collector API (ODS endpoint) that Microsoft is replacing with CLv2.\n\nEvents are written to the `GitHubAdvancedSecurityAlerts_CL` table. The `githubscanaudit` parser function provides a unified view across both the legacy `githubscanaudit_CL` table and the new `GitHubAdvancedSecurityAlerts_CL` table, so all existing workbooks, analytic rules, and hunting queries continue to work without modification.\n\n> **Note:** If you are currently using the original GitHub (using Webhooks) connector, both connectors can run side-by-side. To avoid duplicate data ingestion, stop the original V1 Function App once you have confirmed V2 is working correctly. See the migration instructions at the bottom of this connector page.\n\n> **Note:** If you intend to ingest GitHub Audit logs, refer to the GitHub Enterprise Audit Log Connector from the \"**Data Connectors**\" gallery.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "GitHubAdvancedSecurityAlerts_CL", + "baseQuery": "GitHubAdvancedSecurityAlerts_CL" + } + ], + "sampleQueries": [ + { + "description": "GitHub Advanced Security Alerts - All Activities (V2 table).", + "query": "GitHubAdvancedSecurityAlerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "GitHub Events - All Activities (unified view, includes legacy data).", + "query": "githubscanaudit()\n | sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "GitHubAdvancedSecurityAlerts_CL", + "lastDataReceivedQuery": "GitHubAdvancedSecurityAlerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "GitHubAdvancedSecurityAlerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(3d)" + ] + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Microsoft.Authorization/roleAssignments permissions", + "description": "Permissions to create role assignments are required at the resource group scope. This is needed to grant the Function App's Managed Identity the **Monitoring Metrics Publisher** role on the Data Collection Rule." + } + ] + }, + "instructionSteps": [ + { + "title": "", + "description": ">**NOTE:** This connector is built on an HTTP trigger based Azure Function using the **Logs Ingestion API (CLv2)** with **Managed Identity** authentication. There is no need to configure a Workspace Key — authentication is handled automatically by the Function App's system-assigned managed identity. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details." + }, + { + "title": "", + "description": ">**(Optional Step)** Securely store the GitHub Webhook Secret in Azure Key Vault. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App." + }, + { + "title": "", + "description": "**Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Github Webhook V2 connector, have the **Log Analytics Workspace Name** ready. The connector resources (Function App, DCE, DCR, table) must be deployed to the **same resource group** as the Log Analytics workspace.", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceName" + ], + "label": "Workspace Name" + }, + "type": "CopyableLabel" + } + ] + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Option 1 - Azure Resource Manager (ARM) Template", + "description": "Use this method for automated deployment of the GitHub V2 data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below.\n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FGitHub%2FData%2520Connectors%2FGithubWebhookV2%2Fazuredeploy_GithubWebhookV2_API_FunctionApp.json)\n2. Select the **Subscription** and **Resource Group** — deploy to the **same resource group** as your Log Analytics workspace.\n> **NOTE:** You can't mix Windows and Linux apps in the same region and resource group.\n3. Enter the **WorkspaceName** — the name of your Log Analytics workspace (not the full resource ID).\n4. Optionally enter a **GithubWebhookSecret** to enable payload signature validation.\n5. Mark the checkbox labeled **I agree to the terms and conditions stated above**.\n6. Click **Purchase** to deploy." + }, + { + "title": "Option 2 - Manual Deployment of Azure Functions", + "description": "Use the following step-by-step instructions to deploy the GitHub V2 webhook data connector manually with Azure Functions.", + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Step 1 - Deploy a Function App", + "description": "1. Download the [Azure Function App](https://aka.ms/sentinel-GitHubWebhookAPIV2-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it." + }, + { + "title": "Step 2 - Configure the Function App", + "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tDCE_ENDPOINT - The logs ingestion endpoint of your Data Collection Endpoint\n\t\tDCR_RULE_ID - The immutableId of your Data Collection Rule\n\t\tDCR_STREAM_NAME - Custom-GitHubAdvancedSecurityAlerts_CL\n\t\tGithubWebhookSecret (optional) - Your GitHub webhook secret for payload validation\n5. Once all application settings have been entered, click **Save**.\n6. Ensure the Function App has a **System Assigned Managed Identity** enabled.\n7. Grant the Managed Identity the **Monitoring Metrics Publisher** role on your Data Collection Rule." + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "title": "", + "description": "**Post Deployment steps**\n\n" + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "STEP 1 - To get the Azure Function url", + "description": " 1. Go to Azure function Overview page and Click on \"Functions\" in the left blade.\n 2. Click on the function called \"GithubWebhookConnectorV2\".\n 3. Go to \"GetFunctionurl\" and copy the function url." + }, + { + "title": "STEP 2 - Configure Webhook to Github Organization", + "description": "1. Go to [GitHub](https://www.github.com) and open your account and click on \"Your Organizations.\"\n 2. Click on Settings.\n 3. Click on \"Webhooks\" and enter the function app url which was copied from above STEP 1 under payload URL textbox.\n 4. Choose content type as \"application/json\".\n 5. Subscribe for events and Click on \"Add Webhook\"" + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "title": "", + "description": "*Now we are done with the GitHub Webhook V2 configuration. Once GitHub events are triggered, after the delay of 5 to 10 mins, you should be able to see all the transactional events from GitHub in the LogAnalytics workspace table called `GitHubAdvancedSecurityAlerts_CL`. Use the `githubscanaudit()` parser function for a unified view that includes data from both the legacy `githubscanaudit_CL` and new `GitHubAdvancedSecurityAlerts_CL` tables.*" + }, + { + "title": "⚠️ IMPORTANT: Migrating from GitHub Webhook V1 to V2", + "description": "If you are currently using the original **GitHub (using Webhooks)** connector (`githubscanaudit_CL` table), follow these steps to migrate to V2 without disrupting existing data or breaking workbooks and analytic rules.\n\n**Before you begin:** Both connectors can run side-by-side. V1 data lands in `githubscanaudit_CL` and V2 data lands in `GitHubAdvancedSecurityAlerts_CL`. The `githubscanaudit()` parser function unions both tables so all workbooks, analytic rules, and hunting queries continue to work unchanged during and after migration.\n\n**Migration Steps:**\n\n1. **Deploy V2 alongside V1.** Complete all steps above to deploy the GitHub Webhook V2 Function App. Do not remove V1 yet.\n\n2. **Verify V2 is receiving events.** Update the GitHub webhook payload URL in your GitHub Organization settings (**Settings → Webhooks**) to point to the new V2 Function App URL. Trigger some GitHub events and confirm data appears in `GitHubAdvancedSecurityAlerts_CL` within 5–10 minutes.\n\n3. **Validate the unified parser.** Run `githubscanaudit() | sort by TimeGenerated desc | take 50` in Log Analytics to confirm both V1 and V2 data appears under the same schema.\n\n4. **Disable the V1 Function App.** Once V2 is confirmed working, stop the original V1 Function App to prevent duplicate event ingestion:\n - In the Azure Portal, navigate to your original GitHub Webhook V1 Function App.\n - Under **Overview**, click **Stop** to halt execution.\n - Optionally, update the GitHub webhook payload URL to point exclusively to the V2 endpoint.\n\n5. **Retain V1 data.** The `githubscanaudit_CL` table data is subject to your Log Analytics workspace retention policy. No action is required — historical V1 data continues to be queryable via `githubscanaudit()` until it ages out per your retention settings.\n\n> **⚠️ Warning:** Do **not** delete the V1 Function App resources until you have verified V2 is fully operational and you no longer need to roll back. Running both simultaneously does **not** cause duplicate ingestion as long as only one webhook URL is active in GitHub at a time." + } + ], + "metadata": { + "id": "a3f2c1d4-5e6b-7890-abcd-ef1234567890", + "version": "1.0.0", + "kind": "dataConnector", + "source": { + "kind": "community" + }, + "author": { + "name": "Microsoft" + }, + "support": { + "tier": "community", + "name": "Microsoft", + "link": "https://github.com/Azure/Azure-Sentinel/issues" + } + } +} diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/README.md b/Solutions/GitHub/Data Connectors/GithubWebhookV2/README.md new file mode 100644 index 00000000000..c5bdc918b7c --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/README.md @@ -0,0 +1,206 @@ +# GitHub Webhook V2 Data Connector + +> ⚠️ **IMPORTANT: Migrate to V2** +> +> The original GitHub Webhook connector (`GithubWebhook`) uses the **Azure Monitor HTTP Data Collector API (CLv1 / ODS endpoint)**. Microsoft is replacing this API with the **Logs Ingestion API (CLv2)**. V2 of this connector is the strategic replacement and should be used for all new deployments. Existing V1 deployments should be migrated to V2. +> +> See the [Migrating from V1](#migrating-from-v1) section below for step-by-step instructions. + +## Overview + +This connector is the designated successor to the original [GitHub Webhook connector](../GithubWebhook/) and ingests [GitHub webhook events](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads) into Microsoft Sentinel using the **Logs Ingestion API (CLv2)** with **Managed Identity** authentication. It replaces the CLv1 HTTP Data Collector API (ODS endpoint) used by the original connector. + +As of now the solution supports the following GitHub Advanced Security events: +- [Code Scanning Alert](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#code_scanning_alert) +- [Repository Vulnerability Alert (Dependabot)](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#repository_vulnerability_alert) +- [Secret Scanning Alert](https://docs.github.com/en/enterprise-cloud@latest/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#secret_scanning_alert) + +| | V1 (original) | V2 (this connector) | +|---|---|---| +| **API** | HTTP Data Collector API (ODS) — being replaced by CLv2 | Logs Ingestion API (CLv2/GIG) | +| **Auth** | SharedKey (`WorkspaceID` + `WorkspaceKey`) | Managed Identity (`DefaultAzureCredential`) | +| **Table** | `githubscanaudit_CL` | `GitHubAdvancedSecurityAlerts_CL` | +| **Column names** | Auto-generated `_s` / `_d` / `_b` suffixes | Explicit schema, identical `_s` / `_d` / `_b` names | +| **Unified view** | `githubscanaudit_CL` only | `githubscanaudit()` parser (unions both tables) | +| **Recommendation** | Migrate to V2 | ✅ Recommended for all deployments | + +## Architecture + +``` +GitHub Org Webhook + │ POST (HMAC-SHA256 signed) + ▼ +Azure Function App (HTTP trigger) + ├── GithubWebhookConnectorV2/__init__.py + │ ├── Verify x-hub-signature-256 (HMAC-SHA256) + │ ├── customizeJson() — flatten nested JSON to _s strings + │ └── LogsIngestionClient.upload() → DCE → DCR + │ + ├── System-assigned Managed Identity + │ └── Monitoring Metrics Publisher role on DCR + │ + └── App Settings + ├── DCE_ENDPOINT + ├── DCR_RULE_ID + ├── DCR_STREAM_NAME (Custom-GitHubAdvancedSecurityAlerts_CL) + └── GithubWebhookSecret (optional, for HMAC validation) + +DCR → Log Analytics Workspace → GitHubAdvancedSecurityAlerts_CL table +``` + +## Prerequisites + +- Microsoft Sentinel workspace +- Permissions to create Azure Function Apps, role assignments, and DCE/DCR resources +- A GitHub Organization with Webhook configuration access + +> **Best practice:** Create a new Resource Group for this connector — all provisioned resources (Function App, Storage Account, DCE, DCR, App Insights) will reside there. + +## Deployment + +### Option 1 — ARM Template (Recommended) + +[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FGitHub%2FData%2520Connectors%2FGithubWebhookV2%2Fazuredeploy_GithubWebhookV2_API_FunctionApp.json) + +**Required parameters:** + +| Parameter | Description | +|---|---| +| `FunctionName` | Name for the new Function App (default: `fngithubwebhookv2`) | +| `WorkspaceName` | The **name** of your Log Analytics workspace (e.g. `my-sentinel-workspace`). Deploy to the **same resource group** as the workspace. | +| `GithubWebhookSecret` | *(Optional)* Secret string used to validate the `x-hub-signature-256` header sent by GitHub | + +The template automatically provisions: +- Storage Account, App Service Plan, Function App (with SystemAssigned identity) +- Application Insights +- Custom Log table `GitHubAdvancedSecurityAlerts_CL` +- Data Collection Endpoint (DCE) +- Data Collection Rule (DCR) with `transformKql: "source"` passthrough +- Role assignment granting the Function App's Managed Identity the **Monitoring Metrics Publisher** role on the DCR + +### Option 2 — Manual Deployment + +1. Deploy the Function App manually following the [Azure Functions manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md). +2. Create the `GitHubAdvancedSecurityAlerts_CL` table with the schema defined in the ARM template. +3. Create a DCE and DCR pointing to `GitHubAdvancedSecurityAlerts_CL`. +4. Enable **System Assigned Managed Identity** on the Function App. +5. Grant the Managed Identity the **Monitoring Metrics Publisher** role on the DCR. +6. Set the following Application Settings: + +| Setting | Value | +|---|---| +| `DCE_ENDPOINT` | Logs ingestion endpoint URL from your DCE | +| `DCR_RULE_ID` | `immutableId` of your DCR | +| `DCR_STREAM_NAME` | `Custom-GitHubAdvancedSecurityAlerts_CL` | +| `GithubWebhookSecret` | *(Optional)* Your GitHub webhook secret | + +## Post-Deployment Steps + +### Get the Function App Endpoint + +1. In the Azure Portal, go to your Function App → **Overview** → **Functions** → click **GithubWebhookConnectorV2**. + + ![Go to Function](../GithubWebhook/Images/GotoFunction.jpg) + +2. Click **Get Function URL** (highlighted below) and copy the URL. + + ![Function App Complete URL](../GithubWebhook/Images/functionappcompleteurl.jpg) + +3. *(Optional)* Generate a new function key and substitute it into the URL as the `code` query parameter. + Example: `https://fngithubwebhookv2.azurewebsites.net/api/GithubWebhookConnectorV2?code={apikey}` + + ![Function App Key](../GithubWebhook/Images/FunctionAppfunctionKey.jpg) + +### Configure Webhook on GitHub Organization + +1. Go to GitHub → click your avatar → **Your Organizations**. + + ![GitHub Step 1](../GithubWebhook/Images/Githubstep1.JPG) + +2. Open the Organization → click **Settings**. + + ![GitHub Step 2](../GithubWebhook/Images/GithubStep2.jpg) + +3. Click **Webhooks** → **Add webhook** and fill in the form: + - **Payload URL**: paste the Function App URL from above + - **Content type**: `application/json` + - **Secret**: enter your `GithubWebhookSecret` value (if set) + - **Events**: select **Let me select individual events** and enable: + - ✅ Code scanning alerts + - ✅ Repository vulnerability alerts (Dependabot) + - ✅ Secret scanning alerts + + ![GitHub Step 3](../GithubWebhook/Images/GithubStep3.jpg) + +4. Click **Add webhook**. GitHub will send a ping event — the Function App should return HTTP 200. + +### Verify Data in Log Analytics + +After 5–10 minutes (Log Analytics needs time to spin up resources on first ingest), events will appear in the `GitHubAdvancedSecurityAlerts_CL` table: + +![Log Analytics Data](../GithubWebhook/Images/LogAnalyticsdata.jpg) + +> **Tip for testing secret scanning:** GitHub's built-in secret patterns require real credential formats. To reliably trigger a `secret_scanning_alert` webhook during testing, create a **custom secret scanning pattern** in your Organization settings using the pattern `TEST_SECRET_[A-Z0-9]{32}` and commit a matching string such as `TEST_SECRET_ABCD1234EFGH5678IJKL9012MNOP3456` to a repository. + +## Querying Data + +| Query | Description | +|---|---| +| `GitHubAdvancedSecurityAlerts_CL \| sort by TimeGenerated desc` | All V2 events | +| `githubscanaudit() \| sort by TimeGenerated desc` | Unified view (V1 + V2, all historical data) | +| `GitHubCodeScanningData()` | Code scanning alerts (uses `githubscanaudit()` — works with both tables) | +| `GitHubDependabotData()` | Dependabot vulnerability alerts | +| `GitHubSecretScanningData()` | Secret scanning alerts | + +## Migrating from V1 + +> ⚠️ **Microsoft is replacing the CLv1 HTTP Data Collector API (used by the original GitHub Webhook connector) with the Logs Ingestion API (CLv2). V2 is the recommended replacement. Migrate existing V1 deployments to V2 to remain on a supported ingestion path.** + +Because both tables share identical column names (`_s` / `_d` / `_b` suffixes), all existing workbooks, analytic rules, hunting queries, and parsers (`GitHubCodeScanningData`, `GitHubDependabotData`, `GitHubSecretScanningData`) continue to work without modification via the `githubscanaudit()` union parser. + +**Migration Steps:** + +1. **Deploy V2.** Complete all deployment steps above. + +2. **Update the GitHub webhook URL.** In your GitHub Organization (**Settings → Webhooks**), update the payload URL to point to the new V2 Function App URL. This immediately redirects new events to V2. + +3. **Verify V2 is receiving events.** Trigger some GitHub events and confirm data appears in `GitHubAdvancedSecurityAlerts_CL` within 5–10 minutes. + +4. **Validate the unified parser.** Run the following in Log Analytics to confirm events appear: + ```kql + githubscanaudit() + | sort by TimeGenerated desc + | take 50 + ``` + +5. **Stop the V1 Function App.** Once V2 is confirmed working: + - In the Azure Portal, navigate to your original V1 Function App. + - Under **Overview**, click **Stop**. + - This prevents any residual processing while freeing up Function App compute costs. + +6. **Retain V1 historical data.** The `githubscanaudit_CL` table data is subject to your workspace retention policy. No action is required — historical V1 data remains queryable via `githubscanaudit()` until it ages out. + +> **Note:** Do not delete V1 Function App resources until you are satisfied V2 is fully operational and you do not need to roll back. + +## File Structure + +``` +GithubWebhookV2/ +├── GithubWebhookConnectorV2/ +│ ├── __init__.py # Azure Function — CLv2 ingestion logic +│ └── function.json # HTTP trigger binding +├── azuredeploy_GithubWebhookV2_API_FunctionApp.json # ARM template +├── GithubWebhookV2_API_FunctionApp.json # Connector definition +├── GithubWebhookV2.zip # Pre-built Linux deployment package +├── host.json # Function host settings (retry, timeout) +├── requirements.txt # Python dependencies +└── README.md # This file +``` + +## Related Resources + +- [Original V1 connector](../GithubWebhook/) +- [`githubscanaudit` union parser](../../Parsers/GitHubScanAudit.yaml) +- [Azure Monitor HTTP Data Collector API deprecation](https://aka.ms/Sentinel-Logs_migration) +- [Logs Ingestion API overview](https://docs.microsoft.com/azure/azure-monitor/logs/logs-ingestion-api-overview) +- [Azure Monitor Ingestion client library for Python](https://docs.microsoft.com/python/api/overview/azure/monitor-ingestion-readme) diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/azuredeploy_GithubWebhookV2_API_FunctionApp.json b/Solutions/GitHub/Data Connectors/GithubWebhookV2/azuredeploy_GithubWebhookV2_API_FunctionApp.json new file mode 100644 index 00000000000..009f725f3bb --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/azuredeploy_GithubWebhookV2_API_FunctionApp.json @@ -0,0 +1,328 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "FunctionName": { + "defaultValue": "", + "minLength": 1, + "type": "string" + }, + "WorkspaceName": { + "type": "string", + "metadata": { + "description": "The name of the Log Analytics workspace to send GitHub webhook events to. The workspace must be in the same resource group as this deployment." + } + }, + "GithubWebhookSecret": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "(Optional) The secret used to validate GitHub webhook payloads via HMAC-SHA256 signature. Leave empty to skip signature validation." + } + } + }, + "variables": { + "FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]", + "StorageAccountName": "[substring(tolower(variables('FunctionName')), 0, 22)]", + "StorageSuffix": "[environment().suffixes.storage]", + "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]", + "DCEName": "[concat(variables('FunctionName'), '-dce')]", + "DCRName": "[concat(variables('FunctionName'), '-dcr')]", + "TableName": "GitHubAdvancedSecurityAlerts_CL", + "StreamName": "Custom-GitHubAdvancedSecurityAlerts_CL", + "MonitoringMetricsPublisherRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb')]" + }, + "resources": [ + { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[variables('FunctionName')]", + "location": "[resourceGroup().location]", + "kind": "web", + "properties": { + "Application_Type": "web", + "ApplicationId": "[variables('FunctionName')]", + "WorkspaceResourceId": "[variables('WorkspaceResourceId')]" + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2019-06-01", + "name": "[variables('StorageAccountName')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "StorageV2", + "properties": { + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + }, + "supportsHttpsTrafficOnly": true, + "encryption": { + "services": { + "file": { + "keyType": "Account", + "enabled": true + }, + "blob": { + "keyType": "Account", + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + } + } + }, + { + "type": "Microsoft.Storage/storageAccounts/blobServices", + "apiVersion": "2019-06-01", + "name": "[concat(variables('StorageAccountName'), '/default')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]" + ], + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "properties": { + "cors": { + "corsRules": [] + }, + "deleteRetentionPolicy": { + "enabled": false + } + } + }, + { + "type": "Microsoft.Storage/storageAccounts/fileServices", + "apiVersion": "2019-06-01", + "name": "[concat(variables('StorageAccountName'), '/default')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]" + ], + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "properties": { + "cors": { + "corsRules": [] + } + } + }, + { + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2019-06-01", + "name": "[concat(variables('StorageAccountName'), '/default/azure-webjobs-hosts')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('StorageAccountName'), 'default')]", + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]" + ], + "properties": { + "publicAccess": "None" + } + }, + { + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2019-06-01", + "name": "[concat(variables('StorageAccountName'), '/default/azure-webjobs-secrets')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('StorageAccountName'), 'default')]", + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]" + ], + "properties": { + "publicAccess": "None" + } + }, + { + "type": "Microsoft.Storage/storageAccounts/fileServices/shares", + "apiVersion": "2019-06-01", + "name": "[concat(variables('StorageAccountName'), '/default/', variables('StorageAccountName'))]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('StorageAccountName'), 'default')]", + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]" + ], + "properties": { + "shareQuota": 5120 + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2022-10-01", + "name": "[concat(parameters('WorkspaceName'), '/', variables('TableName'))]", + "location": "[resourceGroup().location]", + "properties": { + "schema": { + "name": "[variables('TableName')]", + "columns": [ + { "name": "TimeGenerated", "type": "datetime" }, + { "name": "event_s", "type": "string" }, + { "name": "action_s", "type": "string" }, + { "name": "alert_s", "type": "string" }, + { "name": "repository_s", "type": "string" }, + { "name": "organization_s", "type": "string" }, + { "name": "sender_s", "type": "string" }, + { "name": "commits_s", "type": "string" }, + { "name": "commit_oid_s", "type": "string" }, + { "name": "ref_s", "type": "string" }, + { "name": "ref_type_s", "type": "string" }, + { "name": "rule_s", "type": "string" }, + { "name": "comment_s", "type": "string" }, + { "name": "deployment_s", "type": "string" }, + { "name": "deployment_status_s", "type": "string" }, + { "name": "discussion_s", "type": "string" }, + { "name": "check_run_s", "type": "string" }, + { "name": "key_s", "type": "string" }, + { "name": "changes_s", "type": "string" }, + { "name": "master_branch_s", "type": "string" }, + { "name": "pusher_type_s", "type": "string" }, + { "name": "description_s", "type": "string" }, + { "name": "number_d", "type": "real" }, + { "name": "forced_b", "type": "boolean" } + ] + } + } + }, + { + "type": "Microsoft.Insights/dataCollectionEndpoints", + "apiVersion": "2022-06-01", + "name": "[variables('DCEName')]", + "location": "[resourceGroup().location]", + "properties": { + "networkAcls": { + "publicNetworkAccess": "Enabled" + } + } + }, + { + "type": "Microsoft.Insights/dataCollectionRules", + "apiVersion": "2022-06-01", + "name": "[variables('DCRName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DCEName'))]", + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('WorkspaceName'), variables('TableName'))]" + ], + "properties": { + "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DCEName'))]", + "streamDeclarations": { + "[variables('StreamName')]": { + "columns": [ + { "name": "TimeGenerated", "type": "datetime" }, + { "name": "event", "type": "string" }, + { "name": "action", "type": "string" }, + { "name": "alert", "type": "string" }, + { "name": "repository", "type": "string" }, + { "name": "organization", "type": "string" }, + { "name": "sender", "type": "string" }, + { "name": "commits", "type": "string" }, + { "name": "after", "type": "string" }, + { "name": "ref", "type": "string" }, + { "name": "ref_type", "type": "string" }, + { "name": "rule", "type": "string" }, + { "name": "comment", "type": "string" }, + { "name": "deployment", "type": "string" }, + { "name": "deployment_status", "type": "string" }, + { "name": "discussion", "type": "string" }, + { "name": "check_run", "type": "string" }, + { "name": "key", "type": "string" }, + { "name": "changes", "type": "string" }, + { "name": "master_branch", "type": "string" }, + { "name": "pusher_type", "type": "string" }, + { "name": "description", "type": "string" }, + { "name": "number", "type": "real" }, + { "name": "forced", "type": "boolean" } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('WorkspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "[variables('StreamName')]" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source | extend _alert = parse_json(alert) | extend _updated = todatetime(_alert.updated_at) | extend _created = todatetime(_alert.created_at) | extend TimeGenerated = iff(isnotnull(_updated), _updated, iff(isnotnull(_created), _created, now())) | project TimeGenerated, event_s = ['event'], action_s = action, alert_s = alert, repository_s = repository, organization_s = organization, sender_s = sender, commits_s = commits, commit_oid_s = after, ref_s = ref, ref_type_s = ref_type, rule_s = rule, comment_s = comment, deployment_s = deployment, deployment_status_s = deployment_status, discussion_s = discussion, check_run_s = check_run, key_s = ['key'], changes_s = changes, master_branch_s = master_branch, pusher_type_s = pusher_type, description_s = description, number_d = number, forced_b = forced", + "outputStream": "[variables('StreamName')]" + } + ] + } + }, + { + "type": "Microsoft.Web/sites", + "apiVersion": "2018-11-01", + "name": "[variables('FunctionName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]", + "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]", + "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DCRName'))]" + ], + "kind": "functionapp,linux", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "name": "[variables('FunctionName')]", + "httpsOnly": true, + "clientAffinityEnabled": true, + "alwaysOn": true, + "reserved": true, + "siteConfig": { + "linuxFxVersion": "python|3.11" + } + }, + "resources": [ + { + "apiVersion": "2018-11-01", + "type": "config", + "name": "appsettings", + "dependsOn": [ + "[concat('Microsoft.Web/sites/', variables('FunctionName'))]" + ], + "properties": { + "FUNCTIONS_EXTENSION_VERSION": "~4", + "FUNCTIONS_WORKER_RUNTIME": "python", + "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2015-05-01').InstrumentationKey]", + "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2015-05-01').ConnectionString]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('StorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]", + "DCE_ENDPOINT": "[reference(resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('DCEName')), '2022-06-01').logsIngestion.endpoint]", + "DCR_RULE_ID": "[reference(resourceId('Microsoft.Insights/dataCollectionRules', variables('DCRName')), '2022-06-01').immutableId]", + "DCR_STREAM_NAME": "[variables('StreamName')]", + "GithubWebhookSecret": "[parameters('GithubWebhookSecret')]", + "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-GitHubWebhookAPIV2-functionapp" + } + } + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(resourceId('Microsoft.Insights/dataCollectionRules', variables('DCRName')), variables('FunctionName'), 'MonitoringMetricsPublisher')]", + "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DCRName'))]", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', variables('FunctionName'))]", + "[resourceId('Microsoft.Insights/dataCollectionRules', variables('DCRName'))]" + ], + "properties": { + "roleDefinitionId": "[variables('MonitoringMetricsPublisherRoleId')]", + "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('FunctionName')), '2018-11-01', 'Full').identity.principalId]", + "principalType": "ServicePrincipal" + } + } + ] +} diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/host.json b/Solutions/GitHub/Data Connectors/GithubWebhookV2/host.json new file mode 100644 index 00000000000..b319cde7d59 --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/host.json @@ -0,0 +1,26 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + }, + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[4.*, 5.0.0)" + }, + "functionTimeout": "00:10:00", + "extensions": { + "http": { + "routePrefix": "github" + } + }, + "retry": { + "strategy": "fixedDelay", + "maxRetryCount": 3, + "delayInterval": "00:00:10" + } +} diff --git a/Solutions/GitHub/Data Connectors/GithubWebhookV2/requirements.txt b/Solutions/GitHub/Data Connectors/GithubWebhookV2/requirements.txt new file mode 100644 index 00000000000..b217290158f --- /dev/null +++ b/Solutions/GitHub/Data Connectors/GithubWebhookV2/requirements.txt @@ -0,0 +1,8 @@ +# DO NOT include azure-functions-worker in this file +# The Python Worker is managed by Azure Functions platform +# Manually managing azure-functions-worker may cause unexpected issues + +azure-functions==1.21.3 +azure-identity==1.17.1 +azure-monitor-ingestion==1.0.4 +cryptography==41.0.7 diff --git a/Solutions/GitHub/Package/3.2.0.zip b/Solutions/GitHub/Package/3.2.0.zip new file mode 100644 index 00000000000..371a5049988 Binary files /dev/null and b/Solutions/GitHub/Package/3.2.0.zip differ diff --git a/Solutions/GitHub/Package/createUiDefinition.json b/Solutions/GitHub/Package/createUiDefinition.json index d1a5dcfc494..5c4f2f942cb 100644 --- a/Solutions/GitHub/Package/createUiDefinition.json +++ b/Solutions/GitHub/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "description": "\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/GitHub/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 [GitHub](https://github.com/) Solution for Microsoft Sentinel enables you to easily ingest events and logs from GitHub to Microsoft Sentinel using GitHub audit log API and webhooks. This enables you to view and analyze this data in your workbooks, query it to create custom alerts, and incorporate it to improve your investigation process, giving you more insight into your platform security.\n \n **Underlying Microsoft Technologies used:** \n \n This solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n \n 1. [Codeless Connector Framework (CCF) (used in GitHub Enterprise Audit Log data connector)](https://docs.microsoft.com/azure/sentinel/create-codeless-connector?tabs=deploy-via-arm-template%2Cconnect-via-the-azure-portal) \n \n 2. [Azure Functions ](https://azure.microsoft.com/services/functions/#overview)\n\n

NOTE: Microsoft recommends installation of \"GitHubAuditDefinitionV2\" (via Codeless Connector Framework). This connector is build on the Codeless Connector Framework (CCF), which uses the Log Ingestion API, which replaces ingestion via the deprecated HTTP Data Collector API. CCF-based data connectors also support Data Collection Rules (DCRs) offering transformations and enrichment.

\n\n

Important: While the updated connector(s) can coexist with their legacy versions, running them together will result in duplicated data ingestion. You can disable the older versions of these connectors to avoid duplication of data..

\n\n**Data Connectors:** 3, **Parsers:** 4, **Workbooks:** 2, **Analytic Rules:** 14, **Hunting Queries:** 8\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\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/GitHub/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 [GitHub](https://github.com/) Solution for Microsoft Sentinel enables you to easily ingest events and logs from GitHub to Microsoft Sentinel using GitHub audit log API and webhooks. This enables you to view and analyze this data in your workbooks, query it to create custom alerts, and incorporate it to improve your investigation process, giving you more insight into your platform security.\n \n **Underlying Microsoft Technologies used:** \n \n This solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n \n 1. [Codeless Connector Framework (CCF) (used in GitHub Enterprise Audit Log data connector)](https://docs.microsoft.com/azure/sentinel/create-codeless-connector?tabs=deploy-via-arm-template%2Cconnect-via-the-azure-portal) \n \n 2. [Azure Functions ](https://azure.microsoft.com/services/functions/#overview)\n\n

NOTE: Microsoft recommends installation of \"GitHubAuditDefinitionV2\" (via Codeless Connector Framework). This connector is build on the Codeless Connector Framework (CCF), which uses the Log Ingestion API, which replaces ingestion via the deprecated HTTP Data Collector API. CCF-based data connectors also support Data Collection Rules (DCRs) offering transformations and enrichment.

\n\n

Important: While the updated connector(s) can coexist with their legacy versions, running them together will result in duplicated data ingestion. You can disable the older versions of these connectors to avoid duplication of data..

\n\n**Data Connectors:** 4, **Parsers:** 5, **Workbooks:** 2, **Analytic Rules:** 14, **Hunting Queries:** 8\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -87,6 +87,13 @@ "text": "This Solution installs the data connector for GitHub. You can get GitHub custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." } }, + { + "name": "dataconnectors4-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Solution installs the data connector for GitHub. You can get GitHub custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + } + }, { "name": "dataconnectors-parser-text", "type": "Microsoft.Common.TextBlock", @@ -95,7 +102,7 @@ } }, { - "name": "dataconnectors-link3", + "name": "dataconnectors-link4", "type": "Microsoft.Common.TextBlock", "options": { "link": { diff --git a/Solutions/GitHub/Package/mainTemplate.json b/Solutions/GitHub/Package/mainTemplate.json index a704908d85b..e986bd4f0de 100644 --- a/Solutions/GitHub/Package/mainTemplate.json +++ b/Solutions/GitHub/Package/mainTemplate.json @@ -63,7 +63,7 @@ "email": "support@microsoft.com", "_email": "[variables('email')]", "_solutionName": "GitHub", - "_solutionVersion": "3.1.4", + "_solutionVersion": "3.2.0", "solutionId": "microsoftcorporation1622712991604.sentinel4github", "_solutionId": "[variables('solutionId')]", "workbookVersion1": "1.0.0", @@ -245,7 +245,14 @@ "parserVersion4": "1.0.0", "parserContentId4": "GitHubSecretScanningData-Parser" }, - "dataConnectorCCPVersion": "3.1.4", + "parserObject5": { + "_parserName5": "[concat(parameters('workspace'),'/','githubscanaudit')]", + "_parserId5": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'githubscanaudit')]", + "parserTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('githubscanaudit-Parser')))]", + "parserVersion5": "1.0.0", + "parserContentId5": "githubscanaudit-Parser" + }, + "dataConnectorCCPVersion": "3.2.0", "_dataConnectorContentIdConnectorDefinition1": "GitHubAuditDefinitionV2", "dataConnectorTemplateNameConnectorDefinition1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition1')))]", "_dataConnectorContentIdConnections1": "GitHubAuditDefinitionV2Connections", @@ -270,6 +277,15 @@ "dataConnectorTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId3'))))]", "dataConnectorVersion3": "1.0.1", "_dataConnectorcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId3'),'-', variables('dataConnectorVersion3'))))]", + "uiConfigId4": "GitHubWebhookV2", + "_uiConfigId4": "[variables('uiConfigId4')]", + "dataConnectorContentId4": "GitHubWebhookV2", + "_dataConnectorContentId4": "[variables('dataConnectorContentId4')]", + "dataConnectorId4": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]", + "_dataConnectorId4": "[variables('dataConnectorId4')]", + "dataConnectorTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId4'))))]", + "dataConnectorVersion4": "1.0.0", + "_dataConnectorcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId4'),'-', variables('dataConnectorVersion4'))))]", "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" }, "resources": [ @@ -282,7 +298,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHubAdvancedSecurity Workbook with template version 3.1.4", + "description": "GitHubAdvancedSecurity Workbook with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion1')]", @@ -300,7 +316,7 @@ }, "properties": { "displayName": "[parameters('workbook1-name')]", - "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f80bd5e4-0e9d-4dc7-b999-110328e5b08e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"isGlobal\":true,\"value\":{\"durationMs\":7776000000},\"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}},{\"id\":\"1673856e-da45-4e3b-8c00-9790024bea39\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Repositories\",\"type\":5,\"description\":\"Repository selector\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s).full_name\\n| distinct tostring(repository)\\n| where isnotempty(repository)\\n\\n\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"f6c038fa-f6b7-4d31-9568-b1b4813e1104\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Actors\",\"type\":5,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend actor = todynamic(sender_s).login\\n| distinct tostring(actor)\\n| where isnotempty(actor)\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"4f71b2a0-62dc-4d47-9488-e2df545d99be\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"jsonData\":\"[\\n \\\"critical\\\",\\n \\\"high\\\",\\n \\\"medium\\\",\\n \\\"moderate\\\",\\n \\\"low\\\",\\n \\\"error\\\",\\n \\\"warning\\\",\\n \\\"note\\\"\\n]\",\"defaultValue\":\"value::all\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"b7b61394-d7c7-4a2a-9e90-5d17ce94f8d8\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Advanced Security Overview\",\"subTarget\":\"Advanced Security Overview\",\"style\":\"link\"},{\"id\":\"7b984311-578d-4162-8e03-1c82cfa37519\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Code Scanning Alerts\",\"subTarget\":\"Code Scanning Alerts\",\"style\":\"link\"},{\"id\":\"03316284-9c39-4d15-853b-568d16d264f5\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Secret Scanning Alerts\",\"subTarget\":\"Secret Scanning Alerts\",\"style\":\"link\"},{\"id\":\"8853be7b-58d0-45cc-89c3-1a9897f01b19\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Dependabot Alerts\",\"subTarget\":\"Dependabot Alerts\",\"style\":\"link\"}]},\"customWidth\":\"100\",\"name\":\"links - 5\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Advanced Security Overview

\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity})\\n| where isnotempty(alertexternalidentifier)\\n| project EventType, Severity;\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| where Severity in ({Severity})\\n| where isnotempty(Severity) \\n| project EventType, Severity;\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity})\\n| where isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(Severity)\",\"size\":0,\"title\":\"Open Alerts By Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"Severity\",\"seriesLabelSettings\":[{\"seriesName\":\"high\",\"label\":\"High\",\"color\":\"redBright\"},{\"seriesName\":\"moderate\",\"label\":\"Moderate\",\"color\":\"orange\"},{\"seriesName\":\"medium\",\"label\":\"Medium\",\"color\":\"brown\"},{\"seriesName\":\"critical\",\"label\":\"Critical\",\"color\":\"redDark\"},{\"seriesName\":\"low\",\"label\":\"Low\",\"color\":\"yellow\"}]}},\"customWidth\":\"25\",\"name\":\"query - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity});\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| where Severity in ({Severity});\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity});\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(Repository)\",\"size\":0,\"title\":\"Open Alerts by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| where Severity in ({Severity})\\n| where isnotempty(alertexternalidentifier)\\n| project EventType, Severity;\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity})\\n| project EventType, Severity;\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"High\\\"\\n| where Severity in ({Severity})\\n| where isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(EventType)\",\"size\":0,\"title\":\"Open Alerts by Type\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('dismiss', 'resolve')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity});\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity});\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity});\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| count\",\"size\":4,\"title\":\"Resolved Alert Count\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy - Copy\",\"styleSettings\":{\"padding\":\"50px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = \\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create', 'dismiss', 'resolve')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| where Severity in ({Severity})\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend id = alert.ghsa_id \\n| extend Status = action_s\\n| extend Reason = alert.affected_package_name\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at) \\n| where isnotempty(alertexternalidentifier)\\n|project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nlet CodeScanningAlerts =\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened_by_user', 'closed_by_user', 'fixed', 'appeared_in_branch', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Reason = alert.rule.name\\n| extend id = alert.rule.id\\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity})\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| where isnotempty(Severity) \\n| extend Age = now() - todatetime(Created_at)\\n|project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nlet SecretScanningAlerts = \\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'resolved', 'reopened')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity})\\n| extend Reason = alert.secret_type \\n| extend id = alert.number\\n| extend alertSecretType = alert.secret_type\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| where isnotempty(alertSecretType)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\",\"size\":0,\"title\":\"Alert Details\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AllEvents\",\"formatter\":5},{\"columnMatch\":\"Severity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"contains\",\"thresholdValue\":\"high\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"contains\",\"thresholdValue\":\"critical\",\"representation\":\"redDark\"},{\"operator\":\"contains\",\"thresholdValue\":\"moderate\",\"representation\":\"red\"},{\"operator\":\"contains\",\"thresholdValue\":\"medium\",\"representation\":\"orange\"},{\"operator\":\"contains\",\"thresholdValue\":\"low\",\"representation\":\"yellow\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"{0}{1}\"}]}}],\"rowLimit\":5000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"Age\",\"label\":\"Age(dd:hh:mm:ss)\"}]}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Advanced Security Overview\"},\"name\":\"Advanced Security Overview\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Code Scanning Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend url = alert.url\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('fixed') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Fixed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('reopened') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Reopened\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', \\\"fixed\\\") and isnotempty(commit_oid_s)\\n| summarize event_count=count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"created\",\"label\":\"Created\"},{\"seriesName\":\"fixed\",\"label\":\"Fixed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let GithubPushes = githubscanaudit_CL\\n| extend EventType='Push'\\n| extend status = todynamic(action_s)\\n| extend commit = todynamic(commits_s)[0]\\n| extend added = commit.added\\n| extend modified = commit.modified\\n| extend removed = commit.removed\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories})\\n| where isnotempty(modified[0]) or isnotempty(added[0]);\\nlet CodeScanningAlerts = \\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert';\\nunion withsource=\\\"AllEvents\\\" CodeScanningAlerts, GithubPushes\\n| summarize event_count=count() by EventType, bin(TimeGenerated,1d)\\n\",\"size\":0,\"title\":\"Commit/Alert Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Push\",\"label\":\"Commits\"},{\"seriesName\":\"Code Scanning Alert\",\"label\":\"Alerts\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', \\\"appeared_in_branch\\\") and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend Tool = alert.tool.name\\n| project TimeGenerated, Tool\\n| summarize Count = count() by tostring(Tool), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Tool\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend URL = alert.html_url\\n| extend tool = alert.tool.name\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_To_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| project repository, URL, tool, created_at, resolved_at, Time_To_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"labelSettings\":[{\"columnId\":\"repository\",\"label\":\"Repository\"},{\"columnId\":\"tool\",\"label\":\"Tool\"},{\"columnId\":\"created_at\",\"label\":\"Created at\"},{\"columnId\":\"resolved_at\",\"label\":\"Resolved at\"},{\"columnId\":\"Time_To_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]}},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened_by_user', 'reopened') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n|extend repository = repo.full_name\\n| extend severity = alert.rule.security_severity_level\\n| where isnotempty(severity)\\n| summarize Total=count(severity), Critical=countif(severity=='critical'), High=countif(severity=='high'), Medium=countif(severity=='medium'), Low=countif(severity=='low') by tostring(repository)\\n\",\"size\":0,\"title\":\"Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"representation\":\"redDark\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"red\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"labelSettings\":[{\"columnId\":\"repository\",\"label\":\"Repository\"}]},\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Tool = tostring(alert.tool.name)\\n| extend Repository = repo.full_name\\n| project Repository, Tool\\n| evaluate pivot(tostring(Tool))\\n| order by tostring(Repository) asc\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":1}]},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Code Scanning Alerts\"},\"name\":\"Code Scanning Alerts\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Secret Scanning Alerts

\"},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.resolved_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend actor = todynamic(sender_s)\\n| extend actorname = actor.login\\n| where actorname in ({Actors})\\n| count \",\"size\":4,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| count \\n\",\"size\":4,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by tostring(alertSecretType)\",\"size\":0,\"title\":\"Secrets by Type\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Secrets by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by bin(TimeGenerated, 1d), action_s\",\"size\":0,\"title\":\"Secrets Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend Resolved_at = alert.resolved_at\\n| extend Time_to_Resolution= format_timespan(todatetime(Resolved_at) - todatetime(Created_at), 'dd:hh:mm:ss' )\\n| extend Resolution = case(isnotnull(alert.resolution), alert.resolution, \\\"Null\\\") \\n| extend URL = todynamic(repository_s).url \\n| where isnotempty(Secret_Type)\\n|project Secret_Type, Organization, Repository, Resolution, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend URL = alert.html_url \\n| where isnotempty(Secret_Type)\\n| project tostring(Secret_Type), tostring(Organization), tostring(Repository), tostring(URL), tostring(Created_at)\",\"size\":0,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Created_at\",\"label\":\"Created at\"}]},\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"Secret Scanning Alerts\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Dependabot Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve')\\n| extend alert = todynamic(alert_s)\\n| extend created_at = alert.created_at \\n| extend resolved_at = alert.fixed_at\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\\n\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Resolved\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('dismiss')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Dismissed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create', 'dismiss', 'resolve')\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| where isnotempty(alertexternalidentifier)\\n| summarize Count = count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"create\",\"label\":\"Found\"},{\"seriesName\":\"resolve\",\"label\":\"Fixed\"},{\"seriesName\":\"dismiss\",\"label\":\"Dismissed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='RepositoryVulnerabilityAlert'\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| where isnotempty(alertexternalidentifier)\\n| summarize Count=count() by tostring(Repository)\",\"size\":0,\"title\":\"Vulnerabilities by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='RepositoryVulnerabilityAlert'\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| where isnotempty(alertexternalidentifier)\\n| summarize Count=count() by tostring(Severity), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve', 'dismiss')\\n| extend alert = todynamic(alert_s)\\n|extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = case(isnotnull(alert.fixed_at), alert.fixed_at, alert.dismissed_at)\\n| extend Time_to_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| where isnotempty(alertexternalidentifier)\\n| project Action, Repository, Severity, Alert_URL, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Alert_URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_to_Resolution = todatetime(resolved_at) - todatetime(created_at)\\n| where isnotempty(alertexternalidentifier)\\n| summarize Total=count(Severity), Critical=countif(Severity=='critical'), High=countif(Severity=='high'), Medium=countif(Severity=='moderate'), Low=countif(Severity=='low') by tostring(Repository)\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redDark\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true}},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Dependabot Alerts\"},\"name\":\"Dependabot Alerts\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-UserWorkbook-alexdemichieli-github-update-1\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f80bd5e4-0e9d-4dc7-b999-110328e5b08e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"isGlobal\":true,\"value\":{\"durationMs\":7776000000},\"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}},{\"id\":\"1673856e-da45-4e3b-8c00-9790024bea39\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Repositories\",\"type\":5,\"description\":\"Repository selector\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s).full_name\\n| distinct tostring(repository)\\n| where isnotempty(repository)\\n\\n\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"f6c038fa-f6b7-4d31-9568-b1b4813e1104\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Actors\",\"type\":5,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend actor = todynamic(sender_s).login\\n| distinct tostring(actor)\\n| where isnotempty(actor)\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"4f71b2a0-62dc-4d47-9488-e2df545d99be\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Severity\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"jsonData\":\"[\\n \\\"critical\\\",\\n \\\"high\\\",\\n \\\"medium\\\",\\n \\\"moderate\\\",\\n \\\"low\\\",\\n \\\"error\\\",\\n \\\"warning\\\",\\n \\\"note\\\"\\n]\",\"defaultValue\":\"value::all\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"b7b61394-d7c7-4a2a-9e90-5d17ce94f8d8\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Advanced Security Overview\",\"subTarget\":\"Advanced Security Overview\",\"style\":\"link\"},{\"id\":\"7b984311-578d-4162-8e03-1c82cfa37519\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Code Scanning Alerts\",\"subTarget\":\"Code Scanning Alerts\",\"style\":\"link\"},{\"id\":\"03316284-9c39-4d15-853b-568d16d264f5\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Secret Scanning Alerts\",\"subTarget\":\"Secret Scanning Alerts\",\"style\":\"link\"},{\"id\":\"8853be7b-58d0-45cc-89c3-1a9897f01b19\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Dependabot Alerts\",\"subTarget\":\"Dependabot Alerts\",\"style\":\"link\"}]},\"customWidth\":\"100\",\"name\":\"links - 5\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Advanced Security Overview

\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity})\\n| where isnotempty(alertexternalidentifier)\\n| project EventType, Severity;\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| where Severity in ({Severity})\\n| where isnotempty(Severity) \\n| project EventType, Severity;\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity})\\n| where isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(Severity)\",\"size\":0,\"title\":\"Open Alerts By Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"Severity\",\"seriesLabelSettings\":[{\"seriesName\":\"high\",\"label\":\"High\",\"color\":\"redBright\"},{\"seriesName\":\"moderate\",\"label\":\"Moderate\",\"color\":\"orange\"},{\"seriesName\":\"medium\",\"label\":\"Medium\",\"color\":\"brown\"},{\"seriesName\":\"critical\",\"label\":\"Critical\",\"color\":\"redDark\"},{\"seriesName\":\"low\",\"label\":\"Low\",\"color\":\"yellow\"}]}},\"customWidth\":\"25\",\"name\":\"query - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity});\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| where Severity in ({Severity});\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity});\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(Repository)\",\"size\":0,\"title\":\"Open Alerts by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| where Severity in ({Severity})\\n| where isnotempty(alertexternalidentifier)\\n| project EventType, Severity;\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity})\\n| project EventType, Severity;\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"High\\\"\\n| where Severity in ({Severity})\\n| where isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(EventType)\",\"size\":0,\"title\":\"Open Alerts by Type\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('dismiss', 'resolve')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend Severity = tostring(alert.severity)\\n| where Severity in ({Severity});\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity});\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity});\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| count\",\"size\":4,\"title\":\"Resolved Alert Count\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy - Copy\",\"styleSettings\":{\"padding\":\"50px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let RepositoryVulnerabilityAlerts = \\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create', 'dismiss', 'resolve')\\n| extend EventType='Dependabot Alert'\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| where Severity in ({Severity})\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend id = alert.ghsa_id \\n| extend Status = action_s\\n| extend Reason = alert.affected_package_name\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at) \\n| where isnotempty(alertexternalidentifier)\\n|project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nlet CodeScanningAlerts =\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened_by_user', 'closed_by_user', 'fixed', 'appeared_in_branch', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend repo = todynamic(repository_s) \\n| extend Repository = repo.full_name \\n| extend Reason = alert.rule.name\\n| extend id = alert.rule.id\\n| extend Severity = alert.rule.security_severity_level\\n| where Severity in ({Severity})\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| where isnotempty(Severity) \\n| extend Age = now() - todatetime(Created_at)\\n|project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nlet SecretScanningAlerts = \\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'resolved', 'reopened')\\n| extend EventType='Secret Scanning Alert'\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Repository = repo.full_name \\n| extend Severity = \\\"high\\\"\\n| where Severity in ({Severity})\\n| extend Reason = alert.secret_type \\n| extend id = alert.number\\n| extend alertSecretType = alert.secret_type\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| where isnotempty(alertSecretType)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\",\"size\":0,\"title\":\"Alert Details\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AllEvents\",\"formatter\":5},{\"columnMatch\":\"Severity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"contains\",\"thresholdValue\":\"high\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"contains\",\"thresholdValue\":\"critical\",\"representation\":\"redDark\"},{\"operator\":\"contains\",\"thresholdValue\":\"moderate\",\"representation\":\"red\"},{\"operator\":\"contains\",\"thresholdValue\":\"medium\",\"representation\":\"orange\"},{\"operator\":\"contains\",\"thresholdValue\":\"low\",\"representation\":\"yellow\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"{0}{1}\"}]}}],\"rowLimit\":5000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"Age\",\"label\":\"Age(dd:hh:mm:ss)\"}]}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Advanced Security Overview\"},\"name\":\"Advanced Security Overview\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Code Scanning Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend url = alert.url\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('fixed') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Fixed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('reopened') and isnotempty(commit_oid_s)\\n| extend Status = action_s\\n| count\",\"size\":4,\"title\":\"Reopened\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', \\\"fixed\\\") and isnotempty(commit_oid_s)\\n| summarize event_count=count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"created\",\"label\":\"Created\"},{\"seriesName\":\"fixed\",\"label\":\"Fixed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let GithubPushes = githubscanaudit_CL\\n| extend EventType='Push'\\n| extend status = todynamic(action_s)\\n| extend commit = todynamic(commits_s)[0]\\n| extend added = commit.added\\n| extend modified = commit.modified\\n| extend removed = commit.removed\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories})\\n| where isnotempty(modified[0]) or isnotempty(added[0]);\\nlet CodeScanningAlerts = \\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert';\\nunion withsource=\\\"AllEvents\\\" CodeScanningAlerts, GithubPushes\\n| summarize event_count=count() by EventType, bin(TimeGenerated,1d)\\n\",\"size\":0,\"title\":\"Commit/Alert Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Push\",\"label\":\"Commits\"},{\"seriesName\":\"Code Scanning Alert\",\"label\":\"Alerts\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', \\\"appeared_in_branch\\\") and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend Tool = alert.tool.name\\n| project TimeGenerated, Tool\\n| summarize Count = count() by tostring(Tool), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Tool\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend URL = alert.html_url\\n| extend tool = alert.tool.name\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_To_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| project repository, URL, tool, created_at, resolved_at, Time_To_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"labelSettings\":[{\"columnId\":\"repository\",\"label\":\"Repository\"},{\"columnId\":\"tool\",\"label\":\"Tool\"},{\"columnId\":\"created_at\",\"label\":\"Created at\"},{\"columnId\":\"resolved_at\",\"label\":\"Resolved at\"},{\"columnId\":\"Time_To_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]}},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened_by_user', 'reopened') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n|extend repository = repo.full_name\\n| extend severity = alert.rule.security_severity_level\\n| where isnotempty(severity)\\n| summarize Total=count(severity), Critical=countif(severity=='critical'), High=countif(severity=='high'), Medium=countif(severity=='medium'), Low=countif(severity=='low') by tostring(repository)\\n\",\"size\":0,\"title\":\"Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"representation\":\"redDark\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"red\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"labelSettings\":[{\"columnId\":\"repository\",\"label\":\"Repository\"}]},\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Tool = tostring(alert.tool.name)\\n| extend Repository = repo.full_name\\n| project Repository, Tool\\n| evaluate pivot(tostring(Tool))\\n| order by tostring(Repository) asc\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":1}]},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Code Scanning Alerts\"},\"name\":\"Code Scanning Alerts\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Secret Scanning Alerts

\"},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.resolved_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| extend actor = todynamic(sender_s)\\n| extend actorname = actor.login\\n| where actorname in ({Actors})\\n| count \",\"size\":4,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| count \\n\",\"size\":4,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by tostring(alertSecretType)\",\"size\":0,\"title\":\"Secrets by Type\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Secrets by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created', 'resolved')\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType)\\n| summarize Count = count() by bin(TimeGenerated, 1d), action_s\",\"size\":0,\"title\":\"Secrets Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolved')\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend Resolved_at = alert.resolved_at\\n| extend Time_to_Resolution= format_timespan(todatetime(Resolved_at) - todatetime(Created_at), 'dd:hh:mm:ss' )\\n| extend Resolution = case(isnotnull(alert.resolution), alert.resolution, \\\"Null\\\") \\n| extend URL = todynamic(repository_s).url \\n| where isnotempty(Secret_Type)\\n|project Secret_Type, Organization, Repository, Resolution, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('created')\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend URL = alert.html_url \\n| where isnotempty(Secret_Type)\\n| project tostring(Secret_Type), tostring(Organization), tostring(Repository), tostring(URL), tostring(Created_at)\",\"size\":0,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Created_at\",\"label\":\"Created at\"}]},\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"Secret Scanning Alerts\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Dependabot Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve')\\n| extend alert = todynamic(alert_s)\\n| extend created_at = alert.created_at \\n| extend resolved_at = alert.fixed_at\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\\n\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Resolved\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('dismiss')\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| where isnotempty(alertexternalidentifier)\\n| count\",\"size\":4,\"title\":\"Dismissed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create', 'dismiss', 'resolve')\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| where isnotempty(alertexternalidentifier)\\n| summarize Count = count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"create\",\"label\":\"Found\"},{\"seriesName\":\"resolve\",\"label\":\"Fixed\"},{\"seriesName\":\"dismiss\",\"label\":\"Dismissed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='RepositoryVulnerabilityAlert'\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| where isnotempty(alertexternalidentifier)\\n| summarize Count=count() by tostring(Repository)\",\"size\":0,\"title\":\"Vulnerabilities by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend EventType='RepositoryVulnerabilityAlert'\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| where isnotempty(alertexternalidentifier)\\n| summarize Count=count() by tostring(Severity), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('resolve', 'dismiss')\\n| extend alert = todynamic(alert_s)\\n|extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = case(isnotnull(alert.fixed_at), alert.fixed_at, alert.dismissed_at)\\n| extend Time_to_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| where isnotempty(alertexternalidentifier)\\n| project Action, Repository, Severity, Alert_URL, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Alert_URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| where repositoryfullname in ({Repositories}) and action_s in ('create')\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_to_Resolution = todatetime(resolved_at) - todatetime(created_at)\\n| where isnotempty(alertexternalidentifier)\\n| summarize Total=count(Severity), Critical=countif(Severity=='critical'), High=countif(Severity=='high'), Medium=countif(Severity=='moderate'), Low=countif(Severity=='low') by tostring(Repository)\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redDark\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true}},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Dependabot Alerts\"},\"name\":\"Dependabot Alerts\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-UserWorkbook-alexdemichieli-github-update-1\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", "version": "1.0", "sourceId": "[variables('workspaceResourceId')]", "category": "sentinel" @@ -370,7 +386,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub Workbook with template version 3.1.4", + "description": "GitHub Workbook with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion2')]", @@ -388,7 +404,7 @@ }, "properties": { "displayName": "[parameters('workbook2-name')]", - "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Topics and repository filters are mutually exlusive. To filter for topics, deselect all repositories and vice versa\",\"style\":\"warning\"},\"name\":\"text - 6\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f80bd5e4-0e9d-4dc7-b999-110328e5b08e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"isGlobal\":true,\"value\":{\"durationMs\":2592000000},\"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}},{\"id\":\"87b3e22f-fc5b-4c56-a449-372be28ec152\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Orgs\",\"type\":5,\"description\":\"Org selector\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend organization = todynamic(organization_s).login\\n| distinct tostring(organization)\\n| where isnotempty(organization)\\n\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"dsp-testing\"]},{\"id\":\"1673856e-da45-4e3b-8c00-9790024bea39\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Repositories\",\"type\":5,\"description\":\"Repository selector\",\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s).full_name\\n| extend organization = todynamic(organization_s).login\\n| where isnotempty(repository) and tostring(organization) in ({Orgs})\\n| distinct tostring(repository)\\n\\n\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":604800000},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"10bfa980-1673-4a8c-9d59-fe12a24e297c\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Topics\",\"type\":5,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let selection = dynamic([{Repositories}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend topics = repository.topics\\n| extend org = todynamic(organization_s)\\n| extend orgName = org.login\\n| extend reposAreNotSelected = array_length((selection)) == 0\\n| where topics <> \\\"[]\\\" and orgName in ({Orgs}) //and reposAreNotSelected\\n| mv-expand topics\\n| distinct tostring(topics)\\n| project topics\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"b7b61394-d7c7-4a2a-9e90-5d17ce94f8d8\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Advanced Security Overview\",\"subTarget\":\"Advanced Security Overview\",\"style\":\"link\"},{\"id\":\"7b984311-578d-4162-8e03-1c82cfa37519\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Code Scanning Alerts\",\"subTarget\":\"Code Scanning Alerts\",\"style\":\"link\"},{\"id\":\"03316284-9c39-4d15-853b-568d16d264f5\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Secret Scanning Alerts\",\"subTarget\":\"Secret Scanning Alerts\",\"style\":\"link\"},{\"id\":\"8853be7b-58d0-45cc-89c3-1a9897f01b19\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Dependabot Alerts\",\"subTarget\":\"Dependabot Alerts\",\"style\":\"link\"}]},\"customWidth\":\"50\",\"name\":\"links - 5\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Advanced Security Overview

\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = tostring(alert.severity)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('create') and isnotempty(alertexternalidentifier)\\n| project EventType, Severity, orgFullName;\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s) and isnotempty(Severity) \\n| project EventType, Severity, orgFullName, repositoryfullname;\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"high\\\"\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(alertSecretType)\\n| project EventType, Severity, orgFullName, repositoryfullname;\\n union withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| summarize Count = count() by tostring(Severity)\",\"size\":0,\"title\":\"Open Alerts By Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"Severity\",\"seriesLabelSettings\":[{\"seriesName\":\"high\",\"label\":\"High\",\"color\":\"redBright\"},{\"seriesName\":\"moderate\",\"label\":\"Moderate\",\"color\":\"orange\"},{\"seriesName\":\"medium\",\"label\":\"Medium\",\"color\":\"brown\"},{\"seriesName\":\"critical\",\"label\":\"Critical\",\"color\":\"redDark\"},{\"seriesName\":\"low\",\"label\":\"Low\",\"color\":\"yellow\"}]}},\"customWidth\":\"25\",\"name\":\"query - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create');\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s);\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Open Alerts by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\n\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| project EventType, Severity;\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s)\\n| project EventType, Severity;\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"High\\\"\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(EventType)\",\"size\":0,\"title\":\"Open Alerts by Type\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\n\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend Repository = repository.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('dismiss', 'resolve') and isnotempty(alertexternalidentifier);\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Repository = repository.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s);\\n\\nlet SecretScanningAlerts = githubscanaudit_CL\\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Repository = repository.full_name \\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('resolved') and isnotempty(alertSecretType);\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| count\",\"size\":4,\"title\":\"Resolved Alert Count\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy - Copy\",\"styleSettings\":{\"padding\":\"50px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = \\ngithubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier = alert.external_identifier\\n| extend Severity = alert.severity\\n| extend id = alert.ghsa_id \\n| extend Status = action_s\\n| extend Reason = alert.affected_package_name\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('create', 'dismiss', 'resolve') and isnotempty(alertexternalidentifier)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\n\\nlet CodeScanningAlerts =\\ngithubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend Reason = alert.rule.name\\n| extend id = alert.rule.id\\n| extend Severity = alert.rule.security_severity_level\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened_by_user', 'closed_by_user', 'fixed', 'appeared_in_branch', 'reopened') and isnotempty(commit_oid_s) and isnotempty(Severity) \\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\n\\nlet SecretScanningAlerts = \\ngithubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s)\\n| extend Severity = \\\"high\\\"\\n| extend Reason = alert.secret_type \\n| extend id = alert.number\\n| extend alertSecretType = alert.secret_type\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'resolved', 'reopened') and isnotempty(alertSecretType)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\",\"size\":0,\"title\":\"Alert Details\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AllEvents\",\"formatter\":5},{\"columnMatch\":\"Severity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"contains\",\"thresholdValue\":\"high\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"contains\",\"thresholdValue\":\"critical\",\"representation\":\"redDark\"},{\"operator\":\"contains\",\"thresholdValue\":\"moderate\",\"representation\":\"red\"},{\"operator\":\"contains\",\"thresholdValue\":\"medium\",\"representation\":\"orange\"},{\"operator\":\"contains\",\"thresholdValue\":\"low\",\"representation\":\"yellow\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"{0}{1}\"}]}}],\"rowLimit\":5000,\"filter\":true}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Advanced Security Overview\"},\"name\":\"Advanced Security Overview\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Code Scanning Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend url = alert.url\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('fixed') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Fixed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('reopened') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Reopened\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', \\\"fixed\\\") and isnotempty(commit_oid_s)\\n| summarize event_count=count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"created\",\"label\":\"Created\"},{\"seriesName\":\"fixed\",\"label\":\"Fixed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet GithubPushes = githubscanaudit_CL\\n| extend EventType='Push'\\n| extend status = todynamic(action_s)\\n| extend commit = todynamic(commits_s)[0]\\n| extend added = commit.added\\n| extend modified = commit.modified\\n| extend removed = commit.removed\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(modified[0]) or isnotempty(added[0]);\\nlet CodeScanningAlerts = \\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert';\\nunion withsource=\\\"AllEvents\\\" CodeScanningAlerts, GithubPushes\\n| summarize event_count=count() by EventType, bin(TimeGenerated,1d)\\n\",\"size\":0,\"title\":\"Commit/Alert Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Push\",\"label\":\"Commits\"},{\"seriesName\":\"Code Scanning Alert\",\"label\":\"Alerts\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Tool = alert.tool.name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', \\\"appeared_in_branch\\\") and isnotempty(commit_oid_s)\\n| project TimeGenerated, Tool\\n| summarize Count = count() by tostring(Tool), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Tool\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend topics = repository.topics\\n| extend alert = todynamic(alert_s)\\n| extend URL = alert.html_url\\n| extend tool = alert.tool.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_To_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| project repository, URL, tool, created_at, resolved_at, Time_To_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}]}},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened_by_user', 'reopened') and isnotempty(commit_oid_s) and isnotempty(severity)\\n| summarize Total=count(severity), Critical=countif(severity=='critical'), High=countif(severity=='high'), Medium=countif(severity=='medium'), Low=countif(severity=='low') by tostring(repositoryfullname)\\n\",\"size\":0,\"title\":\"Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"representation\":\"redDark\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"red\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Tool = tostring(alert.tool.name)\\n| extend Repository = repo.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| project Repository, Tool\\n| evaluate pivot(tostring(Tool))\\n| order by tostring(Repository) asc\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Grype\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Grype\",\"sortOrder\":2}]},\"customWidth\":\"45\",\"name\":\"query - 1\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Code Scanning Alerts\"},\"name\":\"Code Scanning Alerts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Secret Scanning Alerts

\"},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.resolved_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\n\\nlet repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| project repositoryfullname, topic, repoTopics, Out, areTopicsSelected\\n| count\\n\",\"size\":4,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\n\\nlet repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n| extend Out = topic in (repoTopics)\\n| summarize topic = make_list(topic), Out= make_list(Out)\\n| project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('resolved')\\n| count\",\"size\":4,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| summarize Count = count() by tostring(alertSecretType)\",\"size\":0,\"title\":\"Secrets by Type\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Secrets by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created', 'resolved')\\n| summarize Count = count() by bin(TimeGenerated, 1d), action_s\",\"size\":0,\"title\":\"Secrets Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend Resolved_at = alert.resolved_at\\n| extend Time_to_Resolution= format_timespan(todatetime(Resolved_at) - todatetime(Created_at), 'dd:hh:mm:ss' )\\n| extend Resolution = case(isnotnull(alert.resolution), alert.resolution, \\\"Null\\\") \\n| extend URL = todynamic(repository_s).url\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(Secret_Type) and action_s in ('resolved')\\n|project Secret_Type, Organization, Repository, Resolution, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend URL = alert.html_url\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(Secret_Type) and action_s in ('created')\\n| project tostring(Secret_Type), tostring(Organization), tostring(Repository), tostring(URL), tostring(Created_at)\",\"size\":0,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Created_at\",\"label\":\"Created at\"}]},\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"Secret Scanning Alerts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Dependabot Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend created_at = alert.created_at \\n| extend resolved_at = alert.fixed_at\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve')\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\\n\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve')\\n| count\",\"size\":4,\"title\":\"Resolved\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('dismiss')\\n| count\",\"size\":4,\"title\":\"Dismissed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create', 'dismiss', 'resolve')\\n| summarize Count = count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"create\",\"label\":\"Found\"},{\"seriesName\":\"resolve\",\"label\":\"Fixed\"},{\"seriesName\":\"dismiss\",\"label\":\"Dismissed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend Repository = todynamic(repository_s).full_name\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Count=count() by tostring(Repository)\",\"size\":0,\"title\":\"Vulnerabilities by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Count=count() by tostring(Severity), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = case(isnotnull(alert.fixed_at), alert.fixed_at, alert.dismissed_at)\\n| extend Time_to_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve', 'dismiss')\\n| project Action, Repository, Severity, Alert_URL, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Alert_URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_to_Resolution = todatetime(resolved_at) - todatetime(created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Total=count(Severity), Critical=countif(Severity=='critical'), High=countif(Severity=='high'), Medium=countif(Severity=='moderate'), Low=countif(Severity=='low') by tostring(Repository)\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redDark\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Dependabot Alerts\"},\"name\":\"Dependabot Alerts\"}],\"fromTemplateId\":\"GitHubAdvancedSecurity - topics\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Topics and repository filters are mutually exlusive. To filter for topics, deselect all repositories and vice versa\",\"style\":\"warning\"},\"name\":\"text - 6\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"f80bd5e4-0e9d-4dc7-b999-110328e5b08e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"isGlobal\":true,\"value\":{\"durationMs\":2592000000},\"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}},{\"id\":\"87b3e22f-fc5b-4c56-a449-372be28ec152\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Orgs\",\"type\":5,\"description\":\"Org selector\",\"isRequired\":true,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend organization = todynamic(organization_s).login\\n| distinct tostring(organization)\\n| where isnotempty(organization)\\n\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"dsp-testing\"]},{\"id\":\"1673856e-da45-4e3b-8c00-9790024bea39\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Repositories\",\"type\":5,\"description\":\"Repository selector\",\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"githubscanaudit_CL \\n| extend repository = todynamic(repository_s).full_name\\n| extend organization = todynamic(organization_s).login\\n| where isnotempty(repository) and tostring(organization) in ({Orgs})\\n| distinct tostring(repository)\\n\\n\\n\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":604800000},\"timeContextFromParameter\":\"TimeRange\",\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"10bfa980-1673-4a8c-9d59-fe12a24e297c\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Topics\",\"type\":5,\"isGlobal\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let selection = dynamic([{Repositories}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend topics = repository.topics\\n| extend org = todynamic(organization_s)\\n| extend orgName = org.login\\n| extend reposAreNotSelected = array_length((selection)) == 0\\n| where topics <> \\\"[]\\\" and orgName in ({Orgs}) //and reposAreNotSelected\\n| mv-expand topics\\n| distinct tostring(topics)\\n| project topics\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"\",\"showDefault\":false},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"b7b61394-d7c7-4a2a-9e90-5d17ce94f8d8\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Advanced Security Overview\",\"subTarget\":\"Advanced Security Overview\",\"style\":\"link\"},{\"id\":\"7b984311-578d-4162-8e03-1c82cfa37519\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Code Scanning Alerts\",\"subTarget\":\"Code Scanning Alerts\",\"style\":\"link\"},{\"id\":\"03316284-9c39-4d15-853b-568d16d264f5\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Secret Scanning Alerts\",\"subTarget\":\"Secret Scanning Alerts\",\"style\":\"link\"},{\"id\":\"8853be7b-58d0-45cc-89c3-1a9897f01b19\",\"cellValue\":\"SelectedTab\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Dependabot Alerts\",\"subTarget\":\"Dependabot Alerts\",\"style\":\"link\"}]},\"customWidth\":\"50\",\"name\":\"links - 5\",\"styleSettings\":{\"margin\":\"0px\",\"padding\":\"0px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Advanced Security Overview

\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = tostring(alert.severity)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('create') and isnotempty(alertexternalidentifier)\\n| project EventType, Severity, orgFullName;\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Severity = tostring(alert.rule.security_severity_level)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s) and isnotempty(Severity) \\n| project EventType, Severity, orgFullName, repositoryfullname;\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"high\\\"\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(alertSecretType)\\n| project EventType, Severity, orgFullName, repositoryfullname;\\n union withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| summarize Count = count() by tostring(Severity)\",\"size\":0,\"title\":\"Open Alerts By Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"group\":\"Severity\",\"seriesLabelSettings\":[{\"seriesName\":\"high\",\"label\":\"High\",\"color\":\"redBright\"},{\"seriesName\":\"moderate\",\"label\":\"Moderate\",\"color\":\"orange\"},{\"seriesName\":\"medium\",\"label\":\"Medium\",\"color\":\"brown\"},{\"seriesName\":\"critical\",\"label\":\"Critical\",\"color\":\"redDark\"},{\"seriesName\":\"low\",\"label\":\"Low\",\"color\":\"yellow\"}]}},\"customWidth\":\"25\",\"name\":\"query - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create');\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s);\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Open Alerts by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"repositoryfullname\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\n\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend Severity = alert.severity\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| project EventType, Severity;\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s)\\n| project EventType, Severity;\\n\\nlet SecretScanningAlerts = githubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend Severity = \\\"High\\\"\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(alertSecretType)\\n| project EventType, Severity;\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n|summarize Count = count() by tostring(EventType)\",\"size\":0,\"title\":\"Open Alerts by Type\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\n\\nlet RepositoryVulnerabilityAlerts = githubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s) \\n| extend Repository = repository.full_name \\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('dismiss', 'resolve') and isnotempty(alertexternalidentifier);\\n\\nlet CodeScanningAlerts = githubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Repository = repository.full_name \\n| extend Severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s);\\n\\nlet SecretScanningAlerts = githubscanaudit_CL\\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Repository = repository.full_name \\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('resolved') and isnotempty(alertSecretType);\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\\n| count\",\"size\":4,\"title\":\"Resolved Alert Count\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 8 - Copy - Copy\",\"styleSettings\":{\"padding\":\"50px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet RepositoryVulnerabilityAlerts = \\ngithubscanaudit_CL \\n| extend EventType='Dependabot Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s) \\n| extend alertexternalidentifier = alert.external_identifier\\n| extend Severity = alert.severity\\n| extend id = alert.ghsa_id \\n| extend Status = action_s\\n| extend Reason = alert.affected_package_name\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('create', 'dismiss', 'resolve') and isnotempty(alertexternalidentifier)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\n\\nlet CodeScanningAlerts =\\ngithubscanaudit_CL \\n| extend EventType='Code Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s)\\n| extend Severity = alert.rule.security_severity_level\\n| extend Reason = alert.rule.name\\n| extend id = alert.rule.id\\n| extend Severity = alert.rule.security_severity_level\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened_by_user', 'closed_by_user', 'fixed', 'appeared_in_branch', 'reopened') and isnotempty(commit_oid_s) and isnotempty(Severity) \\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\n\\nlet SecretScanningAlerts = \\ngithubscanaudit_CL \\n| extend EventType='Secret Scanning Alert'\\n| extend repository = todynamic(repository_s)\\n| extend Repository = repository.full_name \\n| extend alert = todynamic(alert_s)\\n| extend Severity = \\\"high\\\"\\n| extend Reason = alert.secret_type \\n| extend id = alert.number\\n| extend alertSecretType = alert.secret_type\\n| extend Status = action_s\\n| extend Created_at = alert.created_at\\n| extend Number = alert.number\\n| extend Age = now() - todatetime(Created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'resolved', 'reopened') and isnotempty(alertSecretType)\\n| project Repository, Reason, id, EventType, tostring(Severity), Status, Created_at, Number, format_timespan(Age, 'dd:hh:mm:ss');\\nunion withsource=\\\"AllEvents\\\" RepositoryVulnerabilityAlerts, CodeScanningAlerts, SecretScanningAlerts\",\"size\":0,\"title\":\"Alert Details\",\"timeContextFromParameter\":\"TimeRange\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"AllEvents\",\"formatter\":5},{\"columnMatch\":\"Severity\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"contains\",\"thresholdValue\":\"high\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"},{\"operator\":\"contains\",\"thresholdValue\":\"critical\",\"representation\":\"redDark\"},{\"operator\":\"contains\",\"thresholdValue\":\"moderate\",\"representation\":\"red\"},{\"operator\":\"contains\",\"thresholdValue\":\"medium\",\"representation\":\"orange\"},{\"operator\":\"contains\",\"thresholdValue\":\"low\",\"representation\":\"yellow\"},{\"operator\":\"Default\",\"representation\":\"gray\",\"text\":\"{0}{1}\"}]}}],\"rowLimit\":5000,\"filter\":true}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Advanced Security Overview\"},\"name\":\"Advanced Security Overview\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Code Scanning Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend url = alert.url\\n| extend repo = todynamic(repository_s)\\n| extend repository = repo.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('fixed') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Fixed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('reopened') and isnotempty(commit_oid_s)\\n| count\",\"size\":4,\"title\":\"Reopened\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', \\\"fixed\\\") and isnotempty(commit_oid_s)\\n| summarize event_count=count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"created\",\"label\":\"Created\"},{\"seriesName\":\"fixed\",\"label\":\"Fixed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\nlet GithubPushes = githubscanaudit_CL\\n| extend EventType='Push'\\n| extend status = todynamic(action_s)\\n| extend commit = todynamic(commits_s)[0]\\n| extend added = commit.added\\n| extend modified = commit.modified\\n| extend removed = commit.removed\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(modified[0]) or isnotempty(added[0]);\\nlet CodeScanningAlerts = \\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| extend EventType='Code Scanning Alert';\\nunion withsource=\\\"AllEvents\\\" CodeScanningAlerts, GithubPushes\\n| summarize event_count=count() by EventType, bin(TimeGenerated,1d)\\n\",\"size\":0,\"title\":\"Commit/Alert Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"Push\",\"label\":\"Commits\"},{\"seriesName\":\"Code Scanning Alert\",\"label\":\"Alerts\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Tool = alert.tool.name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', \\\"appeared_in_branch\\\") and isnotempty(commit_oid_s)\\n| project TimeGenerated, Tool\\n| summarize Count = count() by tostring(Tool), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Tool\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend topics = repository.topics\\n| extend alert = todynamic(alert_s)\\n| extend URL = alert.html_url\\n| extend tool = alert.tool.name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_To_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('closed_by_user', 'fixed') and isnotempty(commit_oid_s)\\n| project repository, URL, tool, created_at, resolved_at, Time_To_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}]}},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend severity = alert.rule.security_severity_level\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened_by_user', 'reopened') and isnotempty(commit_oid_s) and isnotempty(severity)\\n| summarize Total=count(severity), Critical=countif(severity=='critical'), High=countif(severity=='high'), Medium=countif(severity=='medium'), Low=countif(severity=='low') by tostring(repositoryfullname)\\n\",\"size\":0,\"title\":\"Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"representation\":\"redDark\",\"text\":\"{0}{1}\"},{\"operator\":\"Default\",\"representation\":\"red\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"severity\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"event_count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"event_count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"event_count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"event_count\",\"heatmapPalette\":\"greenRed\"}}},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend alert = todynamic(alert_s)\\n| extend repo = todynamic(repository_s)\\n| extend Tool = tostring(alert.tool.name)\\n| extend Repository = repo.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (Repository in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where action_s in ('created', 'reopened') and isnotempty(commit_oid_s)\\n| project Repository, Tool\\n| evaluate pivot(tostring(Tool))\\n| order by tostring(Repository) asc\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Grype\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Grype\",\"sortOrder\":2}]},\"customWidth\":\"45\",\"name\":\"query - 1\",\"styleSettings\":{\"margin\":\"10px\",\"padding\":\"20px\"}}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Code Scanning Alerts\"},\"name\":\"Code Scanning Alerts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Secret Scanning Alerts

\"},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.resolved_at\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType)\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\n\\nlet repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| project repositoryfullname, topic, repoTopics, Out, areTopicsSelected\\n| count\\n\",\"size\":4,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}],\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":1}],\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"\\n\\nlet repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n| extend Out = topic in (repoTopics)\\n| summarize topic = make_list(topic), Out= make_list(Out)\\n| project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('resolved')\\n| count\",\"size\":4,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"33\",\"name\":\"query - 9\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| summarize Count = count() by tostring(alertSecretType)\",\"size\":0,\"title\":\"Secrets by Type\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created')\\n| summarize Count = count() by tostring(repositoryfullname)\",\"size\":0,\"title\":\"Secrets by Repository\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertSecretType = alert.secret_type\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertSecretType) and action_s in ('created', 'resolved')\\n| summarize Count = count() by bin(TimeGenerated, 1d), action_s\",\"size\":0,\"title\":\"Secrets Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend Resolved_at = alert.resolved_at\\n| extend Time_to_Resolution= format_timespan(todatetime(Resolved_at) - todatetime(Created_at), 'dd:hh:mm:ss' )\\n| extend Resolution = case(isnotnull(alert.resolution), alert.resolution, \\\"Null\\\") \\n| extend URL = todynamic(repository_s).url\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(Secret_Type) and action_s in ('resolved')\\n|project Secret_Type, Organization, Repository, Resolution, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"filter\":true,\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Time_to_Resolution\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Secret_Type = alert.secret_type\\n| extend Repository = todynamic(repository_s).full_name\\n| extend Organization = todynamic(organization_s).login\\n| extend Created_at = alert.created_at\\n| extend URL = alert.html_url\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(Secret_Type) and action_s in ('created')\\n| project tostring(Secret_Type), tostring(Organization), tostring(Repository), tostring(URL), tostring(Created_at)\",\"size\":0,\"title\":\"Found Secrets\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Secret_Type\",\"label\":\"Secret Type\"},{\"columnId\":\"Created_at\",\"label\":\"Created at\"}]},\"sortBy\":[{\"itemKey\":\"Created_at\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Secret Scanning Alerts\"},\"name\":\"Secret Scanning Alerts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"

Dependabot Alerts

\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend alert = todynamic(alert_s)\\n| extend created_at = alert.created_at \\n| extend resolved_at = alert.fixed_at\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend day = todatetime(resolved_at) - todatetime(created_at)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve')\\n| summarize format_timespan(avg(day), 'dd:hh:mm:ss')\\n\",\"size\":4,\"title\":\"Mean Time to Resolution (dd:hh:mm:ss)\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"MTTR\",\"sortOrder\":2}],\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| count\",\"size\":4,\"title\":\"Created\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve')\\n| count\",\"size\":4,\"title\":\"Resolved\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Status = action_s\\n| extend alertexternalidentifier= alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('dismiss')\\n| count\",\"size\":4,\"title\":\"Dismissed\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"card\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Status\",\"formatter\":5},{\"columnMatch\":\"Count\",\"formatter\":1}]},\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Status\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"style\":\"decimal\",\"maximumFractionDigits\":2,\"maximumSignificantDigits\":3}}},\"showBorder\":false,\"size\":\"auto\"},\"mapSettings\":{\"locInfo\":\"LatLong\",\"sizeSettings\":\"Count\",\"sizeAggregation\":\"Sum\",\"legendMetric\":\"Count\",\"legendAggregation\":\"Sum\",\"itemColorSettings\":{\"type\":\"heatmap\",\"colorAggregation\":\"Sum\",\"nodeColorField\":\"Count\",\"heatmapPalette\":\"greenRed\"}},\"textSettings\":{\"style\":\"bignumber\"}},\"customWidth\":\"25\",\"name\":\"query - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create', 'dismiss', 'resolve')\\n| summarize Count = count() by tostring(action_s), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"Alert Found/Fixed Ratio\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"create\",\"label\":\"Found\"},{\"seriesName\":\"resolve\",\"label\":\"Fixed\"},{\"seriesName\":\"dismiss\",\"label\":\"Dismissed\"}]}},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend Repository = todynamic(repository_s).full_name\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Count=count() by tostring(Repository)\",\"size\":0,\"title\":\"Vulnerabilities by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}],\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"action_s\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"event_count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"customWidth\":\"33\",\"name\":\"query - 7\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend Repository = todynamic(repository_s).full_name\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Count=count() by tostring(Severity), bin(TimeGenerated,1d)\",\"size\":0,\"title\":\"New Alerts by Severity\",\"timeContextFromParameter\":\"TimeRange\",\"timeBrushParameterName\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"customWidth\":\"33\",\"name\":\"query - 7 - Copy\",\"styleSettings\":{\"padding\":\"20px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = case(isnotnull(alert.fixed_at), alert.fixed_at, alert.dismissed_at)\\n| extend Time_to_Resolution = format_timespan(todatetime(resolved_at) - todatetime(created_at), 'dd:hh:mm:ss')\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('resolve', 'dismiss')\\n| project Action, Repository, Severity, Alert_URL, Time_to_Resolution\",\"size\":0,\"title\":\"Fixed Alerts\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Alert_URL\",\"formatter\":7,\"formatOptions\":{\"linkTarget\":\"Url\"}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Time_to_Resolution\",\"label\":\"Time to Resolution(dd:hh:mm:ss)\"}]},\"sortBy\":[{\"itemKey\":\"Repository\",\"sortOrder\":2}]},\"name\":\"query - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let repositoriesList = dynamic([{Repositories}]);\\nlet repoTopics = dynamic([{Topics}]);\\ngithubscanaudit_CL \\n| extend repository = todynamic(repository_s)\\n| extend repositoryfullname = repository.full_name\\n| extend alert = todynamic(alert_s)\\n| extend Action = todynamic(action_s)\\n| extend alertexternalidentifier = alert.external_identifier \\n| extend Severity = alert.severity\\n| extend repo = todynamic(repository_s)\\n| extend Alert_URL = alert.external_reference\\n| extend Repository = repo.full_name\\n| extend created_at = alert.created_at\\n| extend resolved_at = alert.fixed_at\\n| extend Time_to_Resolution = todatetime(resolved_at) - todatetime(created_at)\\n| extend org = todynamic(organization_s)\\n| extend orgFullName = org.login\\n| extend topic = repository.topics\\n| mv-apply repoTopics, topic on (\\n mv-expand topic\\n | extend Out = topic in (repoTopics)\\n | summarize topic = make_list(topic), Out= make_list(Out)\\n | project Out, topic\\n)\\n| extend areReposSelected = array_length((repositoriesList)) == 0\\n| extend areTopicsSelected = array_length((repoTopics)) > 0\\n| where\\n (repositoryfullname in (repositoriesList) and orgFullName in ({Orgs})) or\\n (set_has_element(Out, areTopicsSelected) and areTopicsSelected)\\n| where isnotempty(alertexternalidentifier) and action_s in ('create')\\n| summarize Total=count(Severity), Critical=countif(Severity=='critical'), High=countif(Severity=='high'), Medium=countif(Severity=='moderate'), Low=countif(Severity=='low') by tostring(Repository)\",\"size\":0,\"title\":\"Alerts by Repo\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Critical\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redDark\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"High\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"redBright\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Medium\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"orange\",\"text\":\"{0}{1}\"}]}},{\"columnMatch\":\"Low\",\"formatter\":18,\"formatOptions\":{\"thresholdsOptions\":\"colors\",\"thresholdsGrid\":[{\"operator\":\"Default\",\"representation\":\"yellow\",\"text\":\"{0}{1}\"}]}}],\"filter\":true,\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Total\",\"sortOrder\":2}]},\"name\":\"query - 1\"}]},\"conditionalVisibility\":{\"parameterName\":\"SelectedTab\",\"comparison\":\"isEqualTo\",\"value\":\"Dependabot Alerts\"},\"name\":\"Dependabot Alerts\"}],\"fromTemplateId\":\"GitHubAdvancedSecurity - topics\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", "version": "1.0", "sourceId": "[variables('workspaceResourceId')]", "category": "sentinel" @@ -458,7 +474,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - A payment method was removed_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - A payment method was removed_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", @@ -563,7 +579,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - Activities from Infrequent Country_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - Activities from Infrequent Country_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", @@ -668,7 +684,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - Oauth application - a client secret was removed_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - Oauth application - a client secret was removed_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]", @@ -773,7 +789,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - Repository was created_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - Repository was created_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]", @@ -878,7 +894,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - Repository was destroyed_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - Repository was destroyed_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]", @@ -983,7 +999,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - Two Factor Authentication Disabled in GitHub_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - Two Factor Authentication Disabled in GitHub_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]", @@ -1088,7 +1104,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - User visibility Was changed_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - User visibility Was changed_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]", @@ -1193,7 +1209,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - User was added to the organization_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - User was added to the organization_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]", @@ -1298,7 +1314,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - User was blocked_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - User was blocked_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]", @@ -1403,7 +1419,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - User was invited to the repository_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - User was invited to the repository_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]", @@ -1508,7 +1524,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - pull request was created_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - pull request was created_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject11').analyticRuleVersion11]", @@ -1613,7 +1629,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub - pull request was merged_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "GitHub - pull request was merged_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject12').analyticRuleVersion12]", @@ -1718,7 +1734,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NRT Two Factor Authentication Disabled_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "NRT Two Factor Authentication Disabled_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject13').analyticRuleVersion13]", @@ -1819,7 +1835,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Security Vulnerability in Repo_AnalyticalRules Analytics Rule with template version 3.1.4", + "description": "Security Vulnerability in Repo_AnalyticalRules Analytics Rule with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject14').analyticRuleVersion14]", @@ -1926,7 +1942,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "First Time User Invite and Add Member to Org_HuntingQueries Hunting Query with template version 3.1.4", + "description": "First Time User Invite and Add Member to Org_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]", @@ -2011,7 +2027,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Inactive or New Account Usage_HuntingQueries Hunting Query with template version 3.1.4", + "description": "Inactive or New Account Usage_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]", @@ -2096,7 +2112,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Mass Deletion of Repositories _HuntingQueries Hunting Query with template version 3.1.4", + "description": "Mass Deletion of Repositories _HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]", @@ -2181,7 +2197,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Oauth App Restrictions Disabled_HuntingQueries Hunting Query with template version 3.1.4", + "description": "Oauth App Restrictions Disabled_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]", @@ -2266,7 +2282,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Org Repositories Default Permissions Change_HuntingQueries Hunting Query with template version 3.1.4", + "description": "Org Repositories Default Permissions Change_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]", @@ -2351,7 +2367,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Repository Permission Switched to Public_HuntingQueries Hunting Query with template version 3.1.4", + "description": "Repository Permission Switched to Public_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]", @@ -2436,7 +2452,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "User First Time Repository Delete Activity_HuntingQueries Hunting Query with template version 3.1.4", + "description": "User First Time Repository Delete Activity_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]", @@ -2521,7 +2537,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "User Grant Access and Grants Other Access_HuntingQueries Hunting Query with template version 3.1.4", + "description": "User Grant Access and Grants Other Access_HuntingQueries Hunting Query with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]", @@ -2606,7 +2622,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHubAuditData Data Parser with template version 3.1.4", + "description": "GitHubAuditData Data Parser with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject1').parserVersion1]", @@ -2738,7 +2754,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHubCodeScanningData Data Parser with template version 3.1.4", + "description": "GitHubCodeScanningData Data Parser with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject2').parserVersion2]", @@ -2870,7 +2886,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHubDependabotData Data Parser with template version 3.1.4", + "description": "GitHubDependabotData Data Parser with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject3').parserVersion3]", @@ -3002,7 +3018,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHubSecretScanningData Data Parser with template version 3.1.4", + "description": "GitHubSecretScanningData Data Parser with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject4').parserVersion4]", @@ -3125,6 +3141,138 @@ } } }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('parserObject5').parserTemplateSpecName5]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "GitHubScanAudit Data Parser with template version 3.2.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('parserObject5').parserVersion5]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[variables('parserObject5')._parserName5]", + "apiVersion": "2025-07-01", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Parser for GitHubScanAudit (unified webhook events)", + "category": "Microsoft Sentinel Parser", + "functionAlias": "githubscanaudit", + "query": "// Union alias that combines the legacy CLv1 table (githubscanaudit_CL) with the\n// new CLv2 table (GitHubAdvancedSecurityAlerts_CL) introduced in the GitHub Webhook V2 connector.\n// Both tables share identical column names (with _s / _d / _b suffixes) so downstream\n// parsers (GitHubCodeScanningData, GitHubDependabotData, GitHubSecretScanningData),\n// workbooks, analytic rules, and hunting queries continue to work unchanged.\n//\n// If only one table exists the union is still valid thanks to isfuzzy=true.\nunion isfuzzy=true githubscanaudit_CL, GitHubAdvancedSecurityAlerts_CL\n", + "functionParameters": "", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject5')._parserId5,'/'))))]", + "dependsOn": [ + "[variables('parserObject5')._parserId5]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'githubscanaudit')]", + "contentId": "[variables('parserObject5').parserContentId5]", + "kind": "Parser", + "version": "[variables('parserObject5').parserVersion5]", + "source": { + "name": "GitHub", + "kind": "Solution", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('parserObject5').parserContentId5]", + "contentKind": "Parser", + "displayName": "Parser for GitHubScanAudit (unified webhook events)", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject5').parserContentId5,'-', '1.0.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject5').parserContentId5,'-', '1.0.0')))]", + "version": "[variables('parserObject5').parserVersion5]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2025-07-01", + "name": "[variables('parserObject5')._parserName5]", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Parser for GitHubScanAudit (unified webhook events)", + "category": "Microsoft Sentinel Parser", + "functionAlias": "githubscanaudit", + "query": "// Union alias that combines the legacy CLv1 table (githubscanaudit_CL) with the\n// new CLv2 table (GitHubAdvancedSecurityAlerts_CL) introduced in the GitHub Webhook V2 connector.\n// Both tables share identical column names (with _s / _d / _b suffixes) so downstream\n// parsers (GitHubCodeScanningData, GitHubDependabotData, GitHubSecretScanningData),\n// workbooks, analytic rules, and hunting queries continue to work unchanged.\n//\n// If only one table exists the union is still valid thanks to isfuzzy=true.\nunion isfuzzy=true githubscanaudit_CL, GitHubAdvancedSecurityAlerts_CL\n", + "functionParameters": "", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "location": "[parameters('workspace-location')]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject5')._parserId5,'/'))))]", + "dependsOn": [ + "[variables('parserObject5')._parserId5]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'githubscanaudit')]", + "contentId": "[variables('parserObject5').parserContentId5]", + "kind": "Parser", + "version": "[variables('parserObject5').parserVersion5]", + "source": { + "kind": "Solution", + "name": "GitHub", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com" + } + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", @@ -5541,7 +5689,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub data connector with template version 3.1.4", + "description": "GitHub data connector with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion2')]", @@ -5886,7 +6034,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "GitHub data connector with template version 3.1.4", + "description": "GitHub data connector with template version 3.2.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion3')]", @@ -6316,17 +6464,462 @@ } } }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('dataConnectorTemplateSpecName4')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "GitHub data connector with template version 3.2.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersion4')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "id": "[variables('_uiConfigId4')]", + "title": "GitHub (using Webhooks) V2", + "publisher": "Microsoft", + "descriptionMarkdown": "The [GitHub](https://www.github.com) webhook data connector (V2) provides the capability to ingest GitHub subscribed events into Microsoft Sentinel using [GitHub webhook events](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads). This connector uses the Azure Monitor **Logs Ingestion API (CLv2)** with **Managed Identity** authentication and is the designated successor to the original GitHub (using Webhooks) connector, which uses the CLv1 HTTP Data Collector API (ODS endpoint) that Microsoft is replacing with CLv2.\n\nEvents are written to the `GitHubAdvancedSecurityAlerts_CL` table. The `githubscanaudit` parser function provides a unified view across both the legacy `githubscanaudit_CL` table and the new `GitHubAdvancedSecurityAlerts_CL` table, so all existing workbooks, analytic rules, and hunting queries continue to work without modification.\n\n> **Note:** If you are currently using the original GitHub (using Webhooks) connector, both connectors can run side-by-side. To avoid duplicate data ingestion, stop the original V1 Function App once you have confirmed V2 is working correctly. See the migration instructions at the bottom of this connector page.\n\n> **Note:** If you intend to ingest GitHub Audit logs, refer to the GitHub Enterprise Audit Log Connector from the \"**Data Connectors**\" gallery.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "GitHubAdvancedSecurityAlerts_CL", + "baseQuery": "GitHubAdvancedSecurityAlerts_CL" + } + ], + "sampleQueries": [ + { + "description": "GitHub Advanced Security Alerts - All Activities (V2 table).", + "query": "GitHubAdvancedSecurityAlerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "GitHub Events - All Activities (unified view, includes legacy data).", + "query": "githubscanaudit()\n | sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "GitHubAdvancedSecurityAlerts_CL", + "lastDataReceivedQuery": "GitHubAdvancedSecurityAlerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "GitHubAdvancedSecurityAlerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(3d)" + ] + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Microsoft.Authorization/roleAssignments permissions", + "description": "Permissions to create role assignments are required at the resource group scope. This is needed to grant the Function App's Managed Identity the **Monitoring Metrics Publisher** role on the Data Collection Rule." + } + ] + }, + "instructionSteps": [ + { + "description": ">**NOTE:** This connector is built on an HTTP trigger based Azure Function using the **Logs Ingestion API (CLv2)** with **Managed Identity** authentication. There is no need to configure a Workspace Key — authentication is handled automatically by the Function App's system-assigned managed identity. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details." + }, + { + "description": ">**(Optional Step)** Securely store the GitHub Webhook Secret in Azure Key Vault. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App." + }, + { + "description": "**Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Github Webhook V2 connector, have the **Log Analytics Workspace Name** ready. The connector resources (Function App, DCE, DCR, table) must be deployed to the **same resource group** as the Log Analytics workspace.", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceName" + ], + "label": "Workspace Name" + }, + "type": "CopyableLabel" + } + ] + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Option 1 - Azure Resource Manager (ARM) Template", + "description": "Use this method for automated deployment of the GitHub V2 data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below.\n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FGitHub%2FData%2520Connectors%2FGithubWebhookV2%2Fazuredeploy_GithubWebhookV2_API_FunctionApp.json)\n2. Select the **Subscription** and **Resource Group** — deploy to the **same resource group** as your Log Analytics workspace.\n> **NOTE:** You can't mix Windows and Linux apps in the same region and resource group.\n3. Enter the **WorkspaceName** — the name of your Log Analytics workspace (not the full resource ID).\n4. Optionally enter a **GithubWebhookSecret** to enable payload signature validation.\n5. Mark the checkbox labeled **I agree to the terms and conditions stated above**.\n6. Click **Purchase** to deploy." + }, + { + "title": "Option 2 - Manual Deployment of Azure Functions", + "description": "Use the following step-by-step instructions to deploy the GitHub V2 webhook data connector manually with Azure Functions.", + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Step 1 - Deploy a Function App", + "description": "1. Download the [Azure Function App](https://aka.ms/sentinel-GitHubWebhookAPIV2-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it." + }, + { + "title": "Step 2 - Configure the Function App", + "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tDCE_ENDPOINT - The logs ingestion endpoint of your Data Collection Endpoint\n\t\tDCR_RULE_ID - The immutableId of your Data Collection Rule\n\t\tDCR_STREAM_NAME - Custom-GitHubAdvancedSecurityAlerts_CL\n\t\tGithubWebhookSecret (optional) - Your GitHub webhook secret for payload validation\n5. Once all application settings have been entered, click **Save**.\n6. Ensure the Function App has a **System Assigned Managed Identity** enabled.\n7. Grant the Managed Identity the **Monitoring Metrics Publisher** role on your Data Collection Rule." + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "description": "**Post Deployment steps**\n\n" + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "STEP 1 - To get the Azure Function url", + "description": " 1. Go to Azure function Overview page and Click on \"Functions\" in the left blade.\n 2. Click on the function called \"GithubWebhookConnectorV2\".\n 3. Go to \"GetFunctionurl\" and copy the function url." + }, + { + "title": "STEP 2 - Configure Webhook to Github Organization", + "description": "1. Go to [GitHub](https://www.github.com) and open your account and click on \"Your Organizations.\"\n 2. Click on Settings.\n 3. Click on \"Webhooks\" and enter the function app url which was copied from above STEP 1 under payload URL textbox.\n 4. Choose content type as \"application/json\".\n 5. Subscribe for events and Click on \"Add Webhook\"" + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "description": "*Now we are done with the GitHub Webhook V2 configuration. Once GitHub events are triggered, after the delay of 5 to 10 mins, you should be able to see all the transactional events from GitHub in the LogAnalytics workspace table called `GitHubAdvancedSecurityAlerts_CL`. Use the `githubscanaudit()` parser function for a unified view that includes data from both the legacy `githubscanaudit_CL` and new `GitHubAdvancedSecurityAlerts_CL` tables.*" + }, + { + "description": "If you are currently using the original **GitHub (using Webhooks)** connector (`githubscanaudit_CL` table), follow these steps to migrate to V2 without disrupting existing data or breaking workbooks and analytic rules.\n\n**Before you begin:** Both connectors can run side-by-side. V1 data lands in `githubscanaudit_CL` and V2 data lands in `GitHubAdvancedSecurityAlerts_CL`. The `githubscanaudit()` parser function unions both tables so all workbooks, analytic rules, and hunting queries continue to work unchanged during and after migration.\n\n**Migration Steps:**\n\n1. **Deploy V2 alongside V1.** Complete all steps above to deploy the GitHub Webhook V2 Function App. Do not remove V1 yet.\n\n2. **Verify V2 is receiving events.** Update the GitHub webhook payload URL in your GitHub Organization settings (**Settings → Webhooks**) to point to the new V2 Function App URL. Trigger some GitHub events and confirm data appears in `GitHubAdvancedSecurityAlerts_CL` within 5–10 minutes.\n\n3. **Validate the unified parser.** Run `githubscanaudit() | sort by TimeGenerated desc | take 50` in Log Analytics to confirm both V1 and V2 data appears under the same schema.\n\n4. **Disable the V1 Function App.** Once V2 is confirmed working, stop the original V1 Function App to prevent duplicate event ingestion:\n - In the Azure Portal, navigate to your original GitHub Webhook V1 Function App.\n - Under **Overview**, click **Stop** to halt execution.\n - Optionally, update the GitHub webhook payload URL to point exclusively to the V2 endpoint.\n\n5. **Retain V1 data.** The `githubscanaudit_CL` table data is subject to your Log Analytics workspace retention policy. No action is required — historical V1 data continues to be queryable via `githubscanaudit()` until it ages out per your retention settings.\n\n> **⚠️ Warning:** Do **not** delete the V1 Function App resources until you have verified V2 is fully operational and you no longer need to roll back. Running both simultaneously does **not** cause duplicate ingestion as long as only one webhook URL is active in GitHub at a time.", + "title": "⚠️ IMPORTANT: Migrating from GitHub Webhook V1 to V2" + } + ], + "metadata": { + "id": "a3f2c1d4-5e6b-7890-abcd-ef1234567890", + "version": "1.0.0", + "kind": "dataConnector", + "source": { + "kind": "community" + }, + "author": { + "name": "Microsoft" + }, + "support": { + "tier": "community", + "name": "Microsoft", + "link": "https://github.com/Azure/Azure-Sentinel/issues" + } + } + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]", + "contentId": "[variables('_dataConnectorContentId4')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion4')]", + "source": { + "kind": "Solution", + "name": "GitHub", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_dataConnectorContentId4')]", + "contentKind": "DataConnector", + "displayName": "GitHub (using Webhooks) V2", + "contentProductId": "[variables('_dataConnectorcontentProductId4')]", + "id": "[variables('_dataConnectorcontentProductId4')]", + "version": "[variables('dataConnectorVersion4')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]", + "dependsOn": [ + "[variables('_dataConnectorId4')]" + ], + "location": "[parameters('workspace-location')]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]", + "contentId": "[variables('_dataConnectorContentId4')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion4')]", + "source": { + "kind": "Solution", + "name": "GitHub", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "tier": "Microsoft", + "link": "https://support.microsoft.com" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "title": "GitHub (using Webhooks) V2", + "publisher": "Microsoft", + "descriptionMarkdown": "The [GitHub](https://www.github.com) webhook data connector (V2) provides the capability to ingest GitHub subscribed events into Microsoft Sentinel using [GitHub webhook events](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads). This connector uses the Azure Monitor **Logs Ingestion API (CLv2)** with **Managed Identity** authentication and is the designated successor to the original GitHub (using Webhooks) connector, which uses the CLv1 HTTP Data Collector API (ODS endpoint) that Microsoft is replacing with CLv2.\n\nEvents are written to the `GitHubAdvancedSecurityAlerts_CL` table. The `githubscanaudit` parser function provides a unified view across both the legacy `githubscanaudit_CL` table and the new `GitHubAdvancedSecurityAlerts_CL` table, so all existing workbooks, analytic rules, and hunting queries continue to work without modification.\n\n> **Note:** If you are currently using the original GitHub (using Webhooks) connector, both connectors can run side-by-side. To avoid duplicate data ingestion, stop the original V1 Function App once you have confirmed V2 is working correctly. See the migration instructions at the bottom of this connector page.\n\n> **Note:** If you intend to ingest GitHub Audit logs, refer to the GitHub Enterprise Audit Log Connector from the \"**Data Connectors**\" gallery.", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "GitHubAdvancedSecurityAlerts_CL", + "baseQuery": "GitHubAdvancedSecurityAlerts_CL" + } + ], + "dataTypes": [ + { + "name": "GitHubAdvancedSecurityAlerts_CL", + "lastDataReceivedQuery": "GitHubAdvancedSecurityAlerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "GitHubAdvancedSecurityAlerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(3d)" + ] + } + ], + "sampleQueries": [ + { + "description": "GitHub Advanced Security Alerts - All Activities (V2 table).", + "query": "GitHubAdvancedSecurityAlerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "GitHub Events - All Activities (unified view, includes legacy data).", + "query": "githubscanaudit()\n | sort by TimeGenerated desc" + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Microsoft.Authorization/roleAssignments permissions", + "description": "Permissions to create role assignments are required at the resource group scope. This is needed to grant the Function App's Managed Identity the **Monitoring Metrics Publisher** role on the Data Collection Rule." + } + ] + }, + "instructionSteps": [ + { + "description": ">**NOTE:** This connector is built on an HTTP trigger based Azure Function using the **Logs Ingestion API (CLv2)** with **Managed Identity** authentication. There is no need to configure a Workspace Key — authentication is handled automatically by the Function App's system-assigned managed identity. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details." + }, + { + "description": ">**(Optional Step)** Securely store the GitHub Webhook Secret in Azure Key Vault. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App." + }, + { + "description": "**Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Github Webhook V2 connector, have the **Log Analytics Workspace Name** ready. The connector resources (Function App, DCE, DCR, table) must be deployed to the **same resource group** as the Log Analytics workspace.", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceName" + ], + "label": "Workspace Name" + }, + "type": "CopyableLabel" + } + ] + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Option 1 - Azure Resource Manager (ARM) Template", + "description": "Use this method for automated deployment of the GitHub V2 data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below.\n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FGitHub%2FData%2520Connectors%2FGithubWebhookV2%2Fazuredeploy_GithubWebhookV2_API_FunctionApp.json)\n2. Select the **Subscription** and **Resource Group** — deploy to the **same resource group** as your Log Analytics workspace.\n> **NOTE:** You can't mix Windows and Linux apps in the same region and resource group.\n3. Enter the **WorkspaceName** — the name of your Log Analytics workspace (not the full resource ID).\n4. Optionally enter a **GithubWebhookSecret** to enable payload signature validation.\n5. Mark the checkbox labeled **I agree to the terms and conditions stated above**.\n6. Click **Purchase** to deploy." + }, + { + "title": "Option 2 - Manual Deployment of Azure Functions", + "description": "Use the following step-by-step instructions to deploy the GitHub V2 webhook data connector manually with Azure Functions.", + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "Step 1 - Deploy a Function App", + "description": "1. Download the [Azure Function App](https://aka.ms/sentinel-GitHubWebhookAPIV2-functionapp) file. Extract archive to your local development computer.\n2. Follow the [function app manual deployment instructions](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AzureFunctionsManualDeployment.md#function-app-manual-deployment-instructions) to deploy the Azure Functions app using VSCode.\n3. After successful deployment of the function app, follow next steps for configuring it." + }, + { + "title": "Step 2 - Configure the Function App", + "description": "1. Go to Azure Portal for the Function App configuration.\n2. In the Function App, select the Function App Name and select **Configuration**.\n3. In the **Application settings** tab, select **New application setting**.\n4. Add each of the following application settings individually, with their respective string values (case-sensitive):\n\t\tDCE_ENDPOINT - The logs ingestion endpoint of your Data Collection Endpoint\n\t\tDCR_RULE_ID - The immutableId of your Data Collection Rule\n\t\tDCR_STREAM_NAME - Custom-GitHubAdvancedSecurityAlerts_CL\n\t\tGithubWebhookSecret (optional) - Your GitHub webhook secret for payload validation\n5. Once all application settings have been entered, click **Save**.\n6. Ensure the Function App has a **System Assigned Managed Identity** enabled.\n7. Grant the Managed Identity the **Monitoring Metrics Publisher** role on your Data Collection Rule." + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "description": "**Post Deployment steps**\n\n" + }, + { + "instructions": [ + { + "parameters": { + "instructionSteps": [ + { + "title": "STEP 1 - To get the Azure Function url", + "description": " 1. Go to Azure function Overview page and Click on \"Functions\" in the left blade.\n 2. Click on the function called \"GithubWebhookConnectorV2\".\n 3. Go to \"GetFunctionurl\" and copy the function url." + }, + { + "title": "STEP 2 - Configure Webhook to Github Organization", + "description": "1. Go to [GitHub](https://www.github.com) and open your account and click on \"Your Organizations.\"\n 2. Click on Settings.\n 3. Click on \"Webhooks\" and enter the function app url which was copied from above STEP 1 under payload URL textbox.\n 4. Choose content type as \"application/json\".\n 5. Subscribe for events and Click on \"Add Webhook\"" + } + ] + }, + "type": "InstructionStepsGroup" + } + ] + }, + { + "description": "*Now we are done with the GitHub Webhook V2 configuration. Once GitHub events are triggered, after the delay of 5 to 10 mins, you should be able to see all the transactional events from GitHub in the LogAnalytics workspace table called `GitHubAdvancedSecurityAlerts_CL`. Use the `githubscanaudit()` parser function for a unified view that includes data from both the legacy `githubscanaudit_CL` and new `GitHubAdvancedSecurityAlerts_CL` tables.*" + }, + { + "description": "If you are currently using the original **GitHub (using Webhooks)** connector (`githubscanaudit_CL` table), follow these steps to migrate to V2 without disrupting existing data or breaking workbooks and analytic rules.\n\n**Before you begin:** Both connectors can run side-by-side. V1 data lands in `githubscanaudit_CL` and V2 data lands in `GitHubAdvancedSecurityAlerts_CL`. The `githubscanaudit()` parser function unions both tables so all workbooks, analytic rules, and hunting queries continue to work unchanged during and after migration.\n\n**Migration Steps:**\n\n1. **Deploy V2 alongside V1.** Complete all steps above to deploy the GitHub Webhook V2 Function App. Do not remove V1 yet.\n\n2. **Verify V2 is receiving events.** Update the GitHub webhook payload URL in your GitHub Organization settings (**Settings → Webhooks**) to point to the new V2 Function App URL. Trigger some GitHub events and confirm data appears in `GitHubAdvancedSecurityAlerts_CL` within 5–10 minutes.\n\n3. **Validate the unified parser.** Run `githubscanaudit() | sort by TimeGenerated desc | take 50` in Log Analytics to confirm both V1 and V2 data appears under the same schema.\n\n4. **Disable the V1 Function App.** Once V2 is confirmed working, stop the original V1 Function App to prevent duplicate event ingestion:\n - In the Azure Portal, navigate to your original GitHub Webhook V1 Function App.\n - Under **Overview**, click **Stop** to halt execution.\n - Optionally, update the GitHub webhook payload URL to point exclusively to the V2 endpoint.\n\n5. **Retain V1 data.** The `githubscanaudit_CL` table data is subject to your Log Analytics workspace retention policy. No action is required — historical V1 data continues to be queryable via `githubscanaudit()` until it ages out per your retention settings.\n\n> **⚠️ Warning:** Do **not** delete the V1 Function App resources until you have verified V2 is fully operational and you no longer need to roll back. Running both simultaneously does **not** cause duplicate ingestion as long as only one webhook URL is active in GitHub at a time.", + "title": "⚠️ IMPORTANT: Migrating from GitHub Webhook V1 to V2" + } + ], + "id": "[variables('_uiConfigId4')]" + } + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.1.4", + "version": "3.2.0", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "GitHub", "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", - "descriptionHtml": "

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

\n

• Review the solution Release Notes

\n

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

\n

The GitHub Solution for Microsoft Sentinel enables you to easily ingest events and logs from GitHub to Microsoft Sentinel using GitHub audit log API and webhooks. This enables you to view and analyze this data in your workbooks, query it to create custom alerts, and incorporate it to improve your investigation process, giving you more insight into your platform security.

\n

Underlying Microsoft Technologies used:

\n

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

\n
    \n
  1. Codeless Connector Framework (CCF) (used in GitHub Enterprise Audit Log data connector)

    \n
  2. \n
  3. Azure Functions

    \n
  4. \n
\n

NOTE: Microsoft recommends installation of \"GitHubAuditDefinitionV2\" (via Codeless Connector Framework). This connector is build on the Codeless Connector Framework (CCF), which uses the Log Ingestion API, which replaces ingestion via the deprecated HTTP Data Collector API. CCF-based data connectors also support Data Collection Rules (DCRs) offering transformations and enrichment.

\n

Important: While the updated connector(s) can coexist with their legacy versions, running them together will result in duplicated data ingestion. You can disable the older versions of these connectors to avoid duplication of data..

\n

Data Connectors: 3, Parsers: 4, Workbooks: 2, Analytic Rules: 14, Hunting Queries: 8

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

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

\n

• Review the solution Release Notes

\n

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

\n

The GitHub Solution for Microsoft Sentinel enables you to easily ingest events and logs from GitHub to Microsoft Sentinel using GitHub audit log API and webhooks. This enables you to view and analyze this data in your workbooks, query it to create custom alerts, and incorporate it to improve your investigation process, giving you more insight into your platform security.

\n

Underlying Microsoft Technologies used:

\n

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

\n
    \n
  1. Codeless Connector Framework (CCF) (used in GitHub Enterprise Audit Log data connector)

    \n
  2. \n
  3. Azure Functions

    \n
  4. \n
\n

NOTE: Microsoft recommends installation of \"GitHubAuditDefinitionV2\" (via Codeless Connector Framework). This connector is build on the Codeless Connector Framework (CCF), which uses the Log Ingestion API, which replaces ingestion via the deprecated HTTP Data Collector API. CCF-based data connectors also support Data Collection Rules (DCRs) offering transformations and enrichment.

\n

Important: While the updated connector(s) can coexist with their legacy versions, running them together will result in duplicated data ingestion. You can disable the older versions of these connectors to avoid duplication of data..

\n

Data Connectors: 4, Parsers: 5, Workbooks: 2, Analytic Rules: 14, Hunting Queries: 8

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -6491,6 +7084,11 @@ "contentId": "[variables('parserObject4').parserContentId4]", "version": "[variables('parserObject4').parserVersion4]" }, + { + "kind": "Parser", + "contentId": "[variables('parserObject5').parserContentId5]", + "version": "[variables('parserObject5').parserVersion5]" + }, { "kind": "DataConnector", "contentId": "[variables('_dataConnectorContentIdConnections1')]", @@ -6505,6 +7103,11 @@ "kind": "DataConnector", "contentId": "[variables('_dataConnectorContentId3')]", "version": "[variables('dataConnectorVersion3')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId4')]", + "version": "[variables('dataConnectorVersion4')]" } ] }, diff --git a/Solutions/GitHub/Parsers/GitHubScanAudit.yaml b/Solutions/GitHub/Parsers/GitHubScanAudit.yaml new file mode 100644 index 00000000000..4b04d28c545 --- /dev/null +++ b/Solutions/GitHub/Parsers/GitHubScanAudit.yaml @@ -0,0 +1,17 @@ +id: b7e4f210-3c9a-4d8e-a1f5-6c0b2e8d4f37 +Function: + Title: Parser for GitHubScanAudit (unified webhook events) + Version: '1.0.0' + LastUpdated: '2026-04-01' +Category: Microsoft Sentinel Parser +FunctionName: githubscanaudit +FunctionAlias: githubscanaudit +FunctionQuery: | + // Union alias that combines the legacy CLv1 table (githubscanaudit_CL) with the + // new CLv2 table (GitHubAdvancedSecurityAlerts_CL) introduced in the GitHub Webhook V2 connector. + // Both tables share identical column names (with _s / _d / _b suffixes) so downstream + // parsers (GitHubCodeScanningData, GitHubDependabotData, GitHubSecretScanningData), + // workbooks, analytic rules, and hunting queries continue to work unchanged. + // + // If only one table exists the union is still valid thanks to isfuzzy=true. + union isfuzzy=true githubscanaudit_CL, GitHubAdvancedSecurityAlerts_CL diff --git a/Solutions/GitHub/ReleaseNotes.md b/Solutions/GitHub/ReleaseNotes.md index e244f1ea153..21a6356b4a6 100644 --- a/Solutions/GitHub/ReleaseNotes.md +++ b/Solutions/GitHub/ReleaseNotes.md @@ -1,5 +1,6 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|--------------------------------------------------------------------------| +| 3.2.0 | 24-04-2026 | Added **GitHub Webhook V2** data connector (CLv2/Logs Ingestion API) public preview | | 3.1.4 | 19-03-2026 | Fix NRT 2FA rule for new parser format. | | 3.1.3 | 29-01-2026 | Promoted GitHub Enterprise Cloud Audit Log CCF connector from Public Preview to GA. | | 3.1.2 | 24-11-2025 | Added clarity to Github Enterprise Audit CCF connector definition to use API URL. | diff --git a/Solutions/GitHub/data/Solution_GitHub.json b/Solutions/GitHub/data/Solution_GitHub.json index 46d8d754b99..9cfc366b2eb 100644 --- a/Solutions/GitHub/data/Solution_GitHub.json +++ b/Solutions/GitHub/data/Solution_GitHub.json @@ -37,16 +37,18 @@ "Parsers/GitHubAuditData.yaml", "Parsers/GitHubCodeScanningData.yaml", "Parsers/GitHubDependabotData.yaml", - "Parsers/GitHubSecretScanningData.yaml" + "Parsers/GitHubSecretScanningData.yaml", + "Parsers/GitHubScanAudit.yaml" ], "Data Connectors": [ "Data Connectors/GitHubAuditLogs_CCF/GitHubAuditLogs_ConnectorDefinition.json", "Data Connectors/azuredeploy_GitHub_native_poller_connector.json", - "Data Connectors/GithubWebhook/GithubWebhook_API_FunctionApp.json" + "Data Connectors/GithubWebhook/GithubWebhook_API_FunctionApp.json", + "Data Connectors/GithubWebhookV2/GithubWebhookV2_API_FunctionApp.json" ], "Metadata": "SolutionMetadata.json", "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\GitHub", - "Version": "3.1.4", + "Version": "3.2.0", "TemplateSpec": true, "Is1PConnector": false -} \ No newline at end of file +}