diff --git a/.github/workflows/appinspect_api.yml b/.github/workflows/appinspect_api.yml
index 99a88cd..8a6f02b 100644
--- a/.github/workflows/appinspect_api.yml
+++ b/.github/workflows/appinspect_api.yml
@@ -45,3 +45,9 @@ jobs:
splunkUser: ${{ secrets.SPLUNKBASE_USER }}
splunkPassword: ${{ secrets.SPLUNKBASE_PASSWORD }}
includedTags: cloud
+ - name: Release
+ uses: fnkr/github-action-ghr@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ env:
+ GHR_PATH: ./dist/github_app_for_splunk.spl
+ GITHUB_TOKEN: ${{ secrets.API_TOKEN }}
diff --git a/.github/workflows/appinspect_cli.yml b/.github/workflows/appinspect_cli.yml
index d80e9ed..c0c0e6c 100644
--- a/.github/workflows/appinspect_cli.yml
+++ b/.github/workflows/appinspect_cli.yml
@@ -42,11 +42,23 @@ jobs:
sed -i "s/$old_str/$new_str/g" package.json
sed -i "s/$old_str/$new_str/g" ./github_app_for_splunk/default/app.conf
- - name: Build Package
- run: COPYFILE_DISABLE=1 tar -cvzf package.tar.gz ./github_app_for_splunk
+ - name: Install slim
+ run: |
+ pip install https://download.splunk.com/misc/packaging-toolkit/splunk-packaging-toolkit-1.0.1.tar.gz
+
+ - name: Create package
+ run: |
+ mkdir build
+ slim package ./github_app_for_splunk
- name: Run App Inspect CLI
uses: splunk/appinspect-cli-action@v1
with:
- app_path: package.tar.gz
+ app_path: github_app_for_splunk-1.0.0.tar.gz
included_tags: cloud, splunk_appinspect
+
+ - name: Upload package
+ uses: actions/upload-artifact@v3
+ with:
+ name: github_app_for_splunk-1.0.0.tar.gz
+ path: ./github_app_for_splunk-1.0.0.tar.gz
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4fc208e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Splunk GitHub
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/docs/ghe_audit_logs.MD b/docs/ghe_audit_logs.MD
index c9eed4b..a0fee5b 100644
--- a/docs/ghe_audit_logs.MD
+++ b/docs/ghe_audit_logs.MD
@@ -65,9 +65,12 @@ The following are the required scopes for the personal access token allowing the
- **Hostname**
- - This is the hostname of your GitHub Enterprise instance. Make sure there are no trailing `/` in the URL provided. This could either be a FQDN or an IP address. Do not append any paths beyond the tld.
+ - This is the hostname of your GitHub Enterprise instance. Make sure there are no trailing `/` in the URL provided. This could either be a FQDN or an IP address. Do not append any paths beyond the tld. **Most Users Will Not Need to change this!**
- Example: [https://api.github.com](https://api.github.com)
+- **Account Type**
+ - This is the type of GitHub account you are using. GitHub Enterprise Cloud users should keep it at `enterprise`, however some users that only have an enterprise tier paid Organization should change it to `organization`. If you can't tell which you have, go to your user icon in GitHub in the upper right corner. If you have an entry listed as "Your enterprises", then you should use `enterprise`, otherwise use `organization`.
+
- **Enterprise**
- The enterprise name for which to fetch audit log events
diff --git a/docs/images/79E9DCE3-B358-4BAC-9667-7866C2CE4D00.png b/docs/images/79E9DCE3-B358-4BAC-9667-7866C2CE4D00.png
index d9933d9..188b3e3 100644
Binary files a/docs/images/79E9DCE3-B358-4BAC-9667-7866C2CE4D00.png and b/docs/images/79E9DCE3-B358-4BAC-9667-7866C2CE4D00.png differ
diff --git a/github_app_for_splunk/appserver/static/example_customtables.js b/github_app_for_splunk/appserver/static/example_customtables.js
index ca9f045..0dced37 100644
--- a/github_app_for_splunk/appserver/static/example_customtables.js
+++ b/github_app_for_splunk/appserver/static/example_customtables.js
@@ -16,7 +16,7 @@ require([
id: "search2",
preview: true,
cache: true,
- search: "index=github_webhook \"workflow_run.name\"=\"*\" | spath \"repository.full_name\" | search repository.full_name=* | eval started=if(action=\"requested\",_time,NULL), completed=if(action=\"completed\",_time, NULL), created=round(strptime('workflow_run.created_at',\"%Y-%m-%dT%H:%M:%SZ\")) | stats latest(created) as created, latest(started) as started, latest(completed) as completed, latest(duration) as duration, latest(workflow_run.conclusion) as workflow_run.conclusion by repository.full_name,workflow_run.name,workflow_run.id | eval started=if(isnull(started), created, started) | eval duration=if(isnotnull(completed),tostring(completed-started,\"Duration\"),\"In Progress\") | rename workflow_run.conclusion as status, repository.full_name as \"Repository Name\", workflow_run.name as \"Workflow Name\", workflow_run.id as \"Run ID\" | table status, \"Repository Name\", \"Workflow Name\", \"Run ID\", duration,completed|sort completed|fields - completed",
+ search: "`github_webhooks` \"workflow_run.name\"=\"*\" | spath \"repository.full_name\" | search repository.full_name=* | eval started=if(action=\"requested\",_time,NULL), completed=if(action=\"completed\",_time, NULL), created=round(strptime('workflow_run.created_at',\"%Y-%m-%dT%H:%M:%SZ\")) | stats latest(created) as created, latest(started) as started, latest(completed) as completed, latest(duration) as duration, latest(workflow_run.conclusion) as workflow_run.conclusion by repository.full_name,workflow_run.name,workflow_run.id | eval started=if(isnull(started), created, started) | eval duration=if(isnotnull(completed),tostring(completed-started,\"Duration\"),\"In Progress\") | rename workflow_run.conclusion as status, repository.full_name as \"Repository Name\", workflow_run.name as \"Workflow Name\", workflow_run.id as \"Run ID\" | table status, \"Repository Name\", \"Workflow Name\", \"Run ID\", duration,completed|sort completed|fields - completed",
earliest_time: mvc.tokenSafe("$field1.earliest$"),
latest_time: mvc.tokenSafe("$field1.latest$")
});
@@ -102,7 +102,7 @@ require([
window.open("/app/github_app_for_splunk/workflow_details?form.workflow_id="+workflowIDCell.value+"&form.repoName="+repoNameCell.value+"&form.workflowName="+workflowName.value+"&form.field1.earliest=-24h%40h&form.field1.latest=now&form.timeRange.earliest=-30d%40d&form.timeRange.latest=now&form.workflowCount=25",'_self');
});
- this._searchManager.set({ search: 'index=github_webhook (workflow_run.id='+workflowIDCell.value+' OR workflow_job.run_id='+workflowIDCell.value+') | eval started=if(action=="requested", _time, null), completed=if(action=="completed", _time,null) | stats latest(workflow_run.conclusion) as Status, earliest(started) as Started, latest(completed) as Completed, latest(workflow_run.head_branch) as Branch, latest(workflow_run.event) as Trigger | eval Duration=tostring(Completed-Started, "Duration") | eval Started=strftime(Started,"%Y-%m-%dT%H:%M:%S"), Completed=strftime(Completed,"%Y-%m-%dT%H:%M:%S")| fields Status, Started, Completed, Duration, Branch, Trigger | eval Details="Click here for Workflow Details" | transpose|rename column AS Details| rename "row 1" AS values'});
+ this._searchManager.set({ search: '`github_webhooks` (workflow_run.id='+workflowIDCell.value+' OR workflow_job.run_id='+workflowIDCell.value+') | eval started=if(action=="requested", _time, null), completed=if(action=="completed", _time,null) | stats latest(workflow_run.conclusion) as Status, earliest(started) as Started, latest(completed) as Completed, latest(workflow_run.head_branch) as Branch, latest(workflow_run.event) as Trigger | eval Duration=tostring(Completed-Started, "Duration") | eval Started=strftime(Started,"%Y-%m-%dT%H:%M:%S"), Completed=strftime(Completed,"%Y-%m-%dT%H:%M:%S")| fields Status, Started, Completed, Duration, Branch, Trigger | eval Details="Click here for Workflow Details" | transpose|rename column AS Details| rename "row 1" AS values'});
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._TableView.render().el);
diff --git a/github_app_for_splunk/default/data/ui/nav/default.xml b/github_app_for_splunk/default/data/ui/nav/default.xml
index d80e7a3..e952452 100644
--- a/github_app_for_splunk/default/data/ui/nav/default.xml
+++ b/github_app_for_splunk/default/data/ui/nav/default.xml
@@ -10,6 +10,7 @@
+
diff --git a/github_app_for_splunk/default/data/ui/views/code_scanning_overview.xml b/github_app_for_splunk/default/data/ui/views/code_scanning_overview.xml
index 9522135..eeaab84 100644
--- a/github_app_for_splunk/default/data/ui/views/code_scanning_overview.xml
+++ b/github_app_for_splunk/default/data/ui/views/code_scanning_overview.xml
@@ -2,7 +2,7 @@
- `github_webhooks` (eventtype="GitHub::CodeScanning" OR eventtype="GitHub::Push") | eval action='action', tool=if(isnotnull('alert.tool.name'),'alert.tool.name','unknown'), repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.rule.security_severity_level'),'alert.rule.security_severity_level','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.html_url'),'alert.html_url','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), duration=received_time - created, duration_str=tostring(avg(duration), "duration")
+ `github_webhooks` (eventtype="GitHub::CodeScanning" OR eventtype="GitHub::Push") | eval action='action', tool=if(isnotnull('alert.tool.name'),'alert.tool.name','unknown'), repository=if(isnotnull('repository.name'),'repository.name','unknown'), severity=if(isnotnull('alert.rule.security_severity_level'),'alert.rule.security_severity_level','none'), create_time=if(isnotnull('alert.created_at'),'alert.created_at','unknown'), received_time='_time', alert_url=if(isnotnull('alert.html_url'),'alert.html_url','unknown'), eventtype='eventtype', created=strptime(create_time, "%Y-%m-%dT%H:%M:%S%Z"), resolved_at=case('alert.dismissed_at' != "null", 'alert.dismissed_at', isnotnull('alert.fixed_at'), 'alert.fixed_at', isnotnull('alert.resolved_at'),'alert.resolved_at', 1=1, _time), duration = toString(round(strptime(resolved_at, "%Y-%m-%dT%H:%M:%S") - strptime(create_time, "%Y-%m-%dT%H:%M:%S"))), duration_str=tostring(avg(duration), "duration")
$timeTkn.earliest$$timeTkn.latest$
@@ -46,62 +46,78 @@
+ Mean Time to Resolution (MTTR)
+
+
+ | search eventtype="GitHub::CodeScanning" (action=fixed OR action=closed_by_user) tool=$tool_name$ repository=$repoTkn$
+| eval action=action, , repository=if(isnotnull('repository.name'),'repository.name','unknown')
+| eval age = avg(duration)
+| appendpipe [ stats avg(age) as totalTime ]
+| eval mttr = toString(round(totalTime), "duration"), clean_mttr = replace (mttr , "\+" , " days, ")
+| stats max(clean_mttr)
+
+
+
+
+
+
+
+ Created
- Created| search tool=$tool_name$ repository=$repoTkn$ action="created" | stats count
-
+
+ Fixed
- Fixed| search tool=$tool_name$ repository=$repoTkn$ action="fixed" | stats count
-
+
+ Reopened
- Reopened| search tool=$tool_name$ repository=$repoTkn$ action="reopened" | stats count
-
+
+ Alert Found/Fixed Ratio
- Alert Found/Fixed Ratio| search tool=$tool_name$ repository=$repoTkn$ (action=created OR action=fixed)
-| timechart count(_raw) by action
+| timechart count(_raw) by action
| accum created
-| accum fixed
-| rename created as "Found"
+| accum fixed
+| rename created as "Found"
| rename fixed as "Fixed"
-
+
+ Commit/Alert Ratio
- Commit/Alert Ratio| search (eventtype="GitHub::Push" repository=$repoTkn$) OR ((action=created OR action=reopened) tool=$tool_name$ repository=$repoTkn$ )
| timechart count(_raw) by eventtype
@@ -122,8 +138,8 @@
+ New Alerts by Tool
- New Alerts by Tool| search tool=$tool_name$ repository=$repoTkn$ (action=created OR action=appeared_in_branch) | timechart count(_raw) by tool
@@ -141,8 +157,9 @@
Fixed Alerts | search (action=fixed OR action=closed_by_user) repository=$repoTkn$ tool=$tool_name$
-| table repository, tool, alert_url,duration_str
-| rename repository AS "Repository" duration_str AS "Time to Resolution",tool AS "Tool", alert_url AS "Alert URL"
+|eval clean_duration = replace (duration_str , "\+" , " days, ")
+| table repository, tool, alert_url,clean_duration
+| rename repository AS "Repository" clean_duration AS "Time to Resolution",tool AS "Tool", alert_url AS "Alert URL"
| sort -"Time to Resolution"
@@ -157,11 +174,8 @@
| search (action=created OR action=reopened) repository=$repoTkn$ tool=$tool_name$ | chart usenull=f count over repository by severity
+
-
-
-
-
diff --git a/github_app_for_splunk/default/data/ui/views/dependabot_alerts.xml b/github_app_for_splunk/default/data/ui/views/dependabot_alerts.xml
new file mode 100644
index 0000000..3496568
--- /dev/null
+++ b/github_app_for_splunk/default/data/ui/views/dependabot_alerts.xml
@@ -0,0 +1,181 @@
+
\ No newline at end of file
diff --git a/github_app_for_splunk/default/data/ui/views/integration_overview.xml b/github_app_for_splunk/default/data/ui/views/integration_overview.xml
index 04fad00..f3d6fdb 100644
--- a/github_app_for_splunk/default/data/ui/views/integration_overview.xml
+++ b/github_app_for_splunk/default/data/ui/views/integration_overview.xml
@@ -27,7 +27,7 @@
- index=_internal component=ExecProcessor "TA_splunk_ghe_audit_log_monitoring" "stream_events(): Fetched:" OR "API Rate limits"| rex "\'x_rl_limit\'\: \'(?<x_rl_limit>\d+?)\', \'x_rl_remainig\'\: \'(?<x_rl_remaining>\d+?)\', 'x_rl_reset_timestamp\'\: \'(?<x_rl_reset_timestamp>\d+?)\', \'x_rl_used\'\: \'(?<x_rl_used>\d+?)\'" | rex "stream_events\(\)\: Fetched: (?<event_count>\d+?) events" | timechart sum(event_count) as fetched_event max(x_rl_limit) as x_rl_limit, min(x_rl_remaining) as x_rl_remaining, max(x_rl_used) as x_rl_used | stats max(x_rl_limit) as "Rate Limit", avg(x_rl_used) as "Average Rate Limit Used", min(fetched_event) as "Minimum Fetched Events", avg(fetched_event) as "Average Fetched Events", max(fetched_event) as "Maximum Fetched Events"
+ index=_internal component=ExecProcessor "github-audit-log-monitoring-add-on-for-splunk" "stream_events(): Fetched:" OR "API Rate limits"| rex "\'x_rl_limit\'\: \'(?<x_rl_limit>\d+?)\', \'x_rl_remainig\'\: \'(?<x_rl_remaining>\d+?)\', 'x_rl_reset_timestamp\'\: \'(?<x_rl_reset_timestamp>\d+?)\', \'x_rl_used\'\: \'(?<x_rl_used>\d+?)\'" | rex "stream_events\(\)\: Fetched: (?<event_count>\d+?) events" | timechart sum(event_count) as fetched_event max(x_rl_limit) as x_rl_limit, min(x_rl_remaining) as x_rl_remaining, max(x_rl_used) as x_rl_used | stats max(x_rl_limit) as "Rate Limit", avg(x_rl_used) as "Average Rate Limit Used", min(fetched_event) as "Minimum Fetched Events", avg(fetched_event) as "Average Fetched Events", max(fetched_event) as "Maximum Fetched Events"-24h@hnow1
@@ -57,7 +57,7 @@
Rate Limit Usage
- index=_internal component=ExecProcessor "TA_splunk_ghe_audit_log_monitoring" "API Rate limits"| rex "\'x_rl_limit\'\: \'(?<x_rl_limit>\d+?)\', \'x_rl_remainig\'\: \'(?<x_rl_remaining>\d+?)\', 'x_rl_reset_timestamp\'\: \'(?<x_rl_reset_timestamp>\d+?)\', \'x_rl_used\'\: \'(?<x_rl_used>\d+?)\'" | timechart max(x_rl_limit) as "Rate Limit", min(x_rl_remaining) as "Rate Limit Remaining", max(x_rl_used) as "Rate Limit Used"
+ index=_internal component=ExecProcessor "github-audit-log-monitoring-add-on-for-splunk" "API Rate limits"| rex "\'x_rl_limit\'\: \'(?<x_rl_limit>\d+?)\', \'x_rl_remainig\'\: \'(?<x_rl_remaining>\d+?)\', 'x_rl_reset_timestamp\'\: \'(?<x_rl_reset_timestamp>\d+?)\', \'x_rl_used\'\: \'(?<x_rl_used>\d+?)\'" | timechart max(x_rl_limit) as "Rate Limit", min(x_rl_remaining) as "Rate Limit Remaining", max(x_rl_used) as "Rate Limit Used"$timeRng.earliest$$timeRng.latest$1
@@ -101,7 +101,7 @@
Fetched Events
- index=_internal component=ExecProcessor "TA_splunk_ghe_audit_log_monitoring" "stream_events(): Fetched:" | rex "stream_events\(\)\: Fetched: (?<event_count>\d+?) events" | timechart sum(event_count) as fetched_event
+ index=_internal component=ExecProcessor "github-audit-log-monitoring-add-on-for-splunk" "stream_events(): Fetched:" | rex "stream_events\(\)\: Fetched: (?<event_count>\d+?) events" | timechart sum(event_count) as fetched_event$timeRng.earliest$$timeRng.latest$1
diff --git a/github_app_for_splunk/default/data/ui/views/secret_scanning_overview.xml b/github_app_for_splunk/default/data/ui/views/secret_scanning_overview.xml
index 5fc7164..1cdf640 100644
--- a/github_app_for_splunk/default/data/ui/views/secret_scanning_overview.xml
+++ b/github_app_for_splunk/default/data/ui/views/secret_scanning_overview.xml
@@ -1,8 +1,8 @@
-
@@ -78,19 +94,32 @@
| search repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ action="resolved" | stats count
-
+
+
+
+
+
+ Secrets by Type
+
+ | search repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ action="created" | chart count by secret_type
+
+
+
+
+
+
- Secret Types
+ Secrets by Repository
- | search repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ | chart count by secret_type
+ | search repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ action="created" | chart count by repository
-
+
@@ -98,17 +127,17 @@
Secrets Found/Fixed Ratio| search repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ (action=created OR action=resolved)
-| timechart count(_raw) by action
+| timechart count(_raw) by action
| accum created
-| accum resolved
-| rename created as "Found"
+| accum resolved
+| rename created as "Found"
| rename resolved as "Fixed"
-
+
@@ -117,12 +146,11 @@
Fixed Secrets
- | search action=resolved repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ | table secret_type, organization, repository, resolution, resolved_by, _time
- | rename secret_type as "Secret Type"
- | rename organization as "Organization"
- | rename repository as "Repository"
- | rename resolution as "Resolution"
- | rename resolved_by as "Resolved By"
+ | search action=resolved repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$
+| eval mttr = toString(round(duration), "duration"), clean_mttr = replace (mttr , "\+" , " days, ")
+| table secret_type, organization, repository, resolution, resolved_by, clean_mttr
+| rename secret_type as "Secret Type", organization as "Organization", repository as "Repository", resolution as "Resolution", resolved_by as "Resolved By", clean_mttr as "Time to Resolution"
+
@@ -134,11 +162,8 @@
Found Secrets
- | search action=created repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ | table secret_type, organization, repository, action, _time
- | rename secret_type as "Secret Type"
- | rename organization as "Organization"
- | rename repository as "Repository"
- | rename action as "Action"
+ | search action=created repository=$repoTkn$ organization=$orgTkn$ secret_type=$secret_type$ | table secret_type, organization, repository, url, create_time
+ | rename secret_type as "Secret Type", organization as "Organization", repository as "Repository", url as "URL", create_time as "Created At"
diff --git a/github_app_for_splunk/default/data/ui/views/security_alert_overview.xml b/github_app_for_splunk/default/data/ui/views/security_alert_overview.xml
index 8cefd7c..a85551d 100644
--- a/github_app_for_splunk/default/data/ui/views/security_alert_overview.xml
+++ b/github_app_for_splunk/default/data/ui/views/security_alert_overview.xml
@@ -2,7 +2,15 @@
- index=gh_vuln OR (`github_webhooks` alert.created_at=*) | eval reason=if(isnotnull('alert.affected_package_name'),'alert.affected_package_name','alert.rule.name'), id=if(isnotnull('alert.external_identifier'),'alert.external_identifier','alert.rule.id'), severity=if(isnotnull('alert.severity'),'alert.severity','alert.rule.security_severity_level'), type=if(isnotnull('alert.external_identifier'),"Dependabot Alert","Code Scanning Alert") | stats latest(action) as status, earliest(alert.created_at) as created_at, latest(alert.number) as number by repository.full_name, reason, id, type, severity | eval source=if(type=="Dependabot Alert","dependabot","code-scanning") | eval age = toString(round(now() - strptime(created_at, "%Y-%m-%dT%H:%M:%S")),"Duration")
+ index=gh_vuln OR (`github_webhooks` alert.created_at=*)
+ | eval type=case((eventtype="GitHub::CodeScanning"), "Code Scanning Alert", (eventtype="GitHub::VulnerabilityAlert"), "Dependabot Alert", (eventtype="GitHub::SecretScanning"), "Secret Scanning Alert")
+ | eval url=case((eventtype="GitHub::CodeScanning"), 'alert.html_url', (eventtype="GitHub::VulnerabilityAlert"), 'repository.html_url'+"/security/dependabot/"+'alert.number', (eventtype="GitHub::SecretScanning"), 'alert.html_url')
+ | eval reason=case((type="Dependabot Alert"),'alert.affected_package_name',(type="Code Scanning Alert"), 'alert.rule.name', (type="Secret Scanning Alert"), 'alert.secret_type'), id=case((type="Dependabot Alert"),'alert.external_identifier',(type="Code Scanning Alert"), 'alert.rule.id', (type="Secret Scanning Alert"), 'alert.number'), severity=case((type="Dependabot Alert"),'alert.severity',(type="Code Scanning Alert"), 'alert.rule.security_severity_level', (type="Secret Scanning Alert"), "high"), repository = 'repository.full_name'
+ | stats latest(action) as status, earliest(alert.created_at) as created_at, latest(alert.number) as number by repository, reason, id, type, severity, url
+ | eval source=type
+ | eval age = toString(round(now() - strptime(created_at, "%Y-%m-%dT%H:%M:%S")),"Duration")
+ | search severity IN("*") status IN("*") type IN("*")
+ | sort -age
$timeTkn.earliest$$timeTkn.latest$
@@ -27,7 +35,7 @@
repository.namerepository.name
- index=github_webhook alert.created_at=* | dedup repository.name | table repository.name
+ `github_webhooks` alert.created_at=* | dedup repository.name | table repository.name$timeTkn.earliest$$timeTkn.latest$
@@ -62,6 +70,9 @@
+
@@ -78,7 +89,7 @@
Open Alerts By Repository
- | search status IN("create","created") | stats count by repository.full_name
+ | search status IN("create","created") | stats count by repository
@@ -229,11 +240,9 @@
|search severity IN($severityTkn$) status IN($statusTkn$) type IN($typeTkn$) | sort -age
- repository.full_name, reason, id, type,severity,status, created_at, age
+ repository, reason, id, type,severity,status, created_at, age
-
- https://github.com/$row.repository.full_name|n$/security/$row.source$/$row.number$
-
+ $row.url|n$
@@ -244,7 +253,7 @@
- {"critical":#DC4E41,"high":#F1813F,"moderate":#F8BE34}
+ {"critical":#DC4E41,"high":#F1813F,"moderate":#F8BE34, "medium":#F8BE34}