Repository: google/osv-scanner
Pull request #584 (2023-10-11 00:38:29)

Fix permissions and attempt "Download Artifact" option to allow custom lockfiles
Fix permissions and attempt "Download Artifact" option to allow custom lockfiles

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/google/osv-scanner/pull/584?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#584](https://app.codecov.io/gh/google/osv-scanner/pull/584?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (9f1847f) into [main](https://app.codecov.io/gh/google/osv-scanner/commit/8da35f011503af43d67750f93dfbb1a56da88564?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (8da35f0) will **not change** coverage.
> Report is 2 commits behind head on main.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main     #584   +/-   ##
=======================================
  Coverage   80.14%   80.14%           
=======================================
  Files          77       77           
  Lines        5314     5314           
=======================================
  Hits         4259     4259           
  Misses        881      881           
  Partials      174      174           
```





Patch:
diff --git a/.github/workflows/osv-scanner-pr.yml b/.github/workflows/osv-scanner-pr.yml
index 48a0ce3..01e8304 100644
--- a/.github/workflows/osv-scanner-pr.yml
+++ b/.github/workflows/osv-scanner-pr.yml
@@ -20,9 +20,9 @@ on:
   merge_group:
     branches: [ main ]
 
-# Declare default permissions as read only.
-permissions: read-all
-
 jobs:
   scan-pr:
     uses: "./.github/workflows/osv-scanner-reusable-pr.yml"
+    permissions:
+      security-events: write
+      contents: read
diff --git a/.github/workflows/osv-scanner-reusable-pr.yml b/.github/workflows/osv-scanner-reusable-pr.yml
index ed570d3..e19bdcd 100644
--- a/.github/workflows/osv-scanner-reusable-pr.yml
+++ b/.github/workflows/osv-scanner-reusable-pr.yml
@@ -14,6 +14,10 @@
 
 name: OSV-Scanner PR scanning reusable
 
+permissions:
+  contents: read
+  security-events: write
+
 on:
   workflow_call:
     inputs:
diff --git a/.github/workflows/osv-scanner-reusable.yml b/.github/workflows/osv-scanner-reusable.yml
index 8153029..2a138bd 100644
--- a/.github/workflows/osv-scanner-reusable.yml
+++ b/.github/workflows/osv-scanner-reusable.yml
@@ -14,6 +14,10 @@
 
 name: OSV-Scanner scanning reusable
 
+permissions:
+  contents: read
+  security-events: write
+
 on:
   workflow_call:
     inputs:
@@ -28,21 +32,35 @@ on:
         description: "File name of the result SARIF file"
         type: string
         default: results.sarif
+      download-artifact:
+        description: "Optional artifact to download for scanning"
+        required: false
+        default: ""
+        type: string
 
 jobs:
   osv-scan:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
+        with:
+          persist-credentials: false
+      - name: "Download custom artifact if specified"
+        uses: actions/download-artifact@v3
+        if: "${{ inputs.download-artifact != '' }}"
+        with:
+          name: "${{ inputs.download-artifact }}"
+          path: "./"
       - name: "Run scanner"
-        uses: google/osv-scanner/actions/scanner@main
+        uses: another-rex/osv-scanner/actions/scanner@fix-permisisons
         with:
           scan-args: |-
             --output=results.json
             --format=json
             ${{ inputs.scan-args }}
+        continue-on-error: true
       - name: "Run osv-scanner-reporter"
-        uses: google/osv-scanner/actions/reporter@main
+        uses: another-rex/osv-scanner/actions/reporter@fix-permisisons
         with:
           scan-args: |-
             --output=${{ inputs.results-file-name }}
diff --git a/.github/workflows/osv-scanner-scheduled.yml b/.github/workflows/osv-scanner-scheduled.yml
index 27ad76b..d384ce7 100644
--- a/.github/workflows/osv-scanner-scheduled.yml
+++ b/.github/workflows/osv-scanner-scheduled.yml
@@ -20,12 +20,12 @@ on:
   push:
     branches: [ "main" ]
 
-permissions:
-  # Require writing security events to upload SARIF file to security tab
-  security-events: write
-  # Only need to read contents
-  contents: read
-
 jobs:
   scan-scheduled:
     uses: "./.github/workflows/osv-scanner-reusable.yml"
+    permissions:
+      # Require writing security events to upload SARIF file to security tab
+      security-events: write
+      # Read commit contents
+      contents: read
+
diff --git a/cmd/osv-scanner/fixtures/locks-insecure/osv-scanner-flutter-deps.json b/cmd/osv-scanner/fixtures/locks-insecure/osv-scanner-flutter-deps.json
new file mode 100644
index 0000000..e70711e
--- /dev/null
+++ b/cmd/osv-scanner/fixtures/locks-insecure/osv-scanner-flutter-deps.json
@@ -0,0 +1,38 @@
+{
+  "results": [
+    {
+      "packageSource": {
+        "path": "/path/to/engine/DEPS",
+        "type": "lockfile"
+      },
+      "packages": [
+        {
+          "package": {
+            "name": "https://github.com/flutter/buildroot.git",
+            "commit": "5d60bd2eb4642b64d00c845e5ca9f1ea41fd6db6"
+          }
+        },
+        {
+          "package": {
+            "name": "https://github.com/brendan-duncan/archive.git",
+            "commit": "9de7a0544457c6aba755ccb65abb41b0dc1db70d"
+          }
+        }
+      ]
+    },
+    {
+      "packageSource": {
+        "path": "/path/to/engine/third_party/accessibility/README.md",
+        "type": "lockfile"
+      },
+      "packages": [
+        {
+          "package": {
+            "name": "https://chromium.googlesource.com/chromium/src",
+            "commit": "4579d5538f06c5ef615a15bc67ebb9ac0523a973"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/docs/github-action.md b/docs/github-action.md
index b76c354..4d91c4a 100644
--- a/docs/github-action.md
+++ b/docs/github-action.md
@@ -58,31 +58,36 @@ Results may be viewed by clicking on the details of the failed action, either fr
 
 `osv-scanner-reusable.yml` takes two optional inputs:
 
-- `scan-args`: This value is passed to `osv-scanner` CLI after being split by each line. See the [usage]()./usage) page for the available options.
+- `scan-args`: This value is passed to `osv-scanner` CLI after being split by each line. See the [usage](./usage) page for the available options.
   Importantly `--format` and `--output` flags are already set by the reusable workflow and should not be overridden here.
   Default:
-  ```
+  ```bash
     --recursive # Recursively scan subdirectories
     --skip-git=true # Skip commit scanning to focus on dependencies
     ./ # Start the scan from the root of the repository
   ```
 - `results-file-name`: This is the name of the final SARIF file uploaded to Github.
   Default: `results.sarif`
+- `download-artifact`: Optional artifact to download for scanning. Can be used if you need to do some preprocessing to prepare the lockfiles for scanning.
+  If the file names in the artifact are not standard lockfile names, make sure to add custom scan-args to specify the lockfile type and path (see [specify lockfiles](./usage#specify-lockfiles)).
+
+<details markdown="block">
+<summary>
+Examples
+</summary>
 
-#### Examples
+##### Scan specific lockfiles
 ```yml
-# Scan specific lockfiles
 jobs:
   scan-pr:
     uses: "google/osv-scanner/.github/workflows/osv-scanner-reusable.yml"
     with:
       scan-args: |-
         ./path/to/lockfile1
-        ./path/to/lockfile2
+        requirements.txt:./path/to/python-lockfile2.txt
 ```
-
+##### Default arguments
 ```yml
-# Default arguments
 jobs:
   scan-pr:
     uses: "google/osv-scanner/.github/workflows/osv-scanner-reusable.yml"
@@ -93,6 +98,39 @@ jobs:
         ./
 ```
 
+##### Using download-artifact input to support preprocessing
+```yml
+jobs:
+  extract-deps:
+    name: Extract Dependencies
+    # ...
+    steps:
+      # ... Steps to extract your dependencies
+      - name: "upload osv-scanner deps" # Upload the deps
+        uses: actions/upload-artifact@v4
+        with:
+          name: converted-OSV-Scanner-deps
+          path: osv-scanner-deps.json
+          retention-days: 2
+  vuln-scan:
+    name: Vulnerability scanning
+    # makes sure the extraction step is completed before running the scanner
+    needs:
+      extract-deps
+    uses: "google/osv-scanner/.github/workflows/osv-scanner-reusable.yml@main"
+    with:
+      # Download the artifact uploaded in extract-deps step
+      download-artifact: converted-OSV-Scanner-deps
+      # Scan only the file inside the uploaded artifact
+      scan-args: |-
+        --lockfile=osv-scanner:osv-scanner-deps.json
+    permissions:
+      # Needed to upload the SARIF results to code-scanning dashboard.
+      security-events: write
+      contents: read
+```
+
+</details>
 
 ## Scheduled scans
 
diff --git a/docs/usage.md b/docs/usage.md
index 15612fa..89f9f02 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -25,9 +25,9 @@ osv-scanner -r /path/to/your/dir
 
 The preceding command will find lockfiles, SBOMs, and git directories in your target directory and use them to determine the dependencies to check against the OSV database for any known vulnerabilities.
 
-The recursive flag `-r` or `--recursive` will tell the scanner to search all subdirectories in addition to the specified directory. It can find additional lockfiles, dependencies, and vulnerabilities. If your project has deeply nested subdirectories, a recursive search may take a long time. 
+The recursive flag `-r` or `--recursive` will tell the scanner to search all subdirectories in addition to the specified directory. It can find additional lockfiles, dependencies, and vulnerabilities. If your project has deeply nested subdirectories, a recursive search may take a long time.
 
-Git directories are searched for the latest commit hash. Searching for git commit hash is intended to work with projects that use git submodules or a similar mechanism where dependencies are checked out as real git repositories. 
+Git directories are searched for the latest commit hash. Searching for git commit hash is intended to work with projects that use git submodules or a similar mechanism where dependencies are checked out as real git repositories.
 
 ## Ignored files
 
@@ -110,7 +110,7 @@ osv-scanner --lockfile ':/path/to/my:projects/package-lock.json'
 
 ### Custom Lockfiles
 
-If you have a custom lockfile that we do not support or prefer to do your own custom parsing, you can extract the custom lockfile information and create a custom intermediate file containing dependency information so that osv-scanner can still check for vulnerabilities. 
+If you have a custom lockfile that we do not support or prefer to do your own custom parsing, you can extract the custom lockfile information and create a custom intermediate file containing dependency information so that osv-scanner can still check for vulnerabilities.
 
 Once you extracted your own dependency information, place it in a `osv-scanner.json` file, with the same format as the JSON output of osv-scanner, e.g.:
 
@@ -121,6 +121,7 @@ Once you extracted your own dependency information, place it in a `osv-scanner.j
       "packages": [
         {
           "package": {
+            "name": "github.com/repo/url",
             "commit": "9a6bd55c9d0722cb101fe85a3b22d89e4ff4fe52"
           }
         },
@@ -145,7 +146,7 @@ osv-scanner --lockfile osv-scanner:/path/to/osv-scanner.json
 
 ## Scanning a Debian based docker image packages
 Preview
-{: .label } 
+{: .label }
 
 This tool will scrape the list of installed packages in a Debian image and query for vulnerabilities on them.
 
@@ -180,4 +181,4 @@ appropriate osv-scanner flags:
 
 ```bash
 docker run -it -v ${PWD}:/src ghcr.io/google/osv-scanner -L /src/go.mod
-```
\ No newline at end of file
+```
diff --git a/internal/output/fixtures/commit-grouped.json b/internal/output/fixtures/commit-grouped.json
new file mode 100644
index 0000000..3960b8f
--- /dev/null
+++ b/internal/output/fixtures/commit-grouped.json
@@ -0,0 +1,129 @@
+{
+  "DisplayID": "OSV-2023-72",
+  "PkgSource": [
+    {
+      "Package": {
+        "name": "https://fuchsia.googlesource.com/third_party/android.googlesource.com/platform/external/perfetto",
+        "version": "",
+        "ecosystem": "",
+        "commit": "b8da07095979310818f0efde2ef3c69ea70d62c5"
+      },
+      "Source": {
+        "path": "/usr/local/google/home/rexpan/Documents/Project/engine/deps_flatten.txt",
+        "type": "lockfile"
+      }
+    }
+  ],
+  "AliasedVulns": {
+    "OSV-2023-72": {
+      "modified": "2023-04-20T22:43:30Z",
+      "published": "2023-02-18T13:00:15Z",
+      "schema_version": "1.6.0",
+      "id": "OSV-2023-72",
+      "summary": "Heap-buffer-overflow in perfetto::trace_processor::TrackEventParser::ParseTrackDescriptor",
+      "details": "OSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56057\n\n```\nCrash type: Heap-buffer-overflow WRITE 4\nCrash state:\nperfetto::trace_processor::TrackEventParser::ParseTrackDescriptor\nperfetto::trace_processor::TrackEventModule::ParseTracePacketData\nperfetto::trace_processor::ProtoTraceParser::ParseTracePacket\n```\n",
+      "affected": [
+        {
+          "package": {
+            "ecosystem": "OSS-Fuzz",
+            "name": "perfetto",
+            "purl": "pkg:generic/perfetto"
+          },
+          "ranges": [
+            {
+              "type": "GIT",
+              "events": [
+                {
+                  "introduced": "8209fb9b9a4156232aa87ad4621e541bfb777ec1"
+                },
+                {
+                  "fixed": "9a7f09383dd39f19e662d428321ca708a2a600a3"
+                }
+              ],
+              "repo": "https://android.googlesource.com/platform/external/perfetto/"
+            }
+          ],
+          "versions": [
+            "android-13.0.0_r1",
+            "android-13.0.0_r12",
+            "android-13.0.0_r2",
+            "android-13.0.0_r3",
+            "android-13.0.0_r31",
+            "android-13.0.0_r4",
+            "android-13.0.0_r5",
+            "android-13.0.0_r6",
+            "android-13.0.0_r7",
+            "android-13.0.0_r8",
+            "android-cts-13.0_r1",
+            "android-cts-13.0_r2",
+            "android-cts-13.0_r3",
+            "android-mainline-12.0.0_r100",
+            "android-mainline-12.0.0_r122",
+            "android-mainline-12.0.0_r49",
+            "android-mainline-12.0.0_r59",
+            "android-mainline-12.0.0_r63",
+            "android-mainline-12.0.0_r70",
+            "android-mainline-12.0.0_r77",
+            "android-mainline-12.0.0_r99",
+            "android-platform-13.0.0_r1",
+            "android-platform-13.0.0_r2",
+            "android-security-13.0.0_r1",
+            "android-security-13.0.0_r2",
+            "android-vts-13.0_r1",
+            "android-vts-13.0_r2",
+            "android-vts-13.0_r3",
+            "platform-tools-29.0.1",
+            "platform-tools-29.0.2",
+            "platform-tools-29.0.3",
+            "platform-tools-29.0.4",
+            "platform-tools-29.0.5",
+            "platform-tools-29.0.6",
+            "platform-tools-30.0.0",
+            "platform-tools-30.0.1",
+            "platform-tools-30.0.2",
+            "platform-tools-30.0.3",
+            "platform-tools-30.0.4",
+            "platform-tools-30.0.5",
+            "platform-tools-31.0.0",
+            "platform-tools-31.0.1",
+            "platform-tools-31.0.2",
+            "platform-tools-31.0.3",
+            "platform-tools-32.0.0",
+            "platform-tools-33.0.0",
+            "platform-tools-33.0.1",
+            "platform-tools-33.0.2",
+            "platform-tools-33.0.3",
+            "platform-tools-33.0.4",
+            "platform-tools-34.0.0",
+            "v27.0",
+            "v27.1",
+            "v28.0",
+            "v29.0",
+            "v30.0",
+            "v31.0",
+            "v32.0",
+            "v32.1",
+            "v32.2",
+            "android-security-13.0.0_r3",
+            "android-security-13.0.0_r4"
+          ],
+          "database_specific": {
+            "source": "https://github.com/google/oss-fuzz-vulns/blob/main/vulns/perfetto/OSV-2023-72.yaml"
+          },
+          "ecosystem_specific": {
+            "severity": "HIGH"
+          }
+        }
+      ],
+      "references": [
+        {
+          "type": "REPORT",
+          "url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56057"
+        }
+      ]
+    }
+  },
+  "AliasedIDList": [
+    "OSV-2023-72"
+  ]
+}
diff --git a/internal/output/fixtures/sarif-commit-output.md b/internal/output/fixtures/sarif-commit-output.md
new file mode 100644
index 0000000..983f897
--- /dev/null
+++ b/internal/output/fixtures/sarif-commit-output.md
@@ -0,0 +1,58 @@
+
+**Your dependency is vulnerable to [OSV-2023-72](https://osv.dev/list?q=OSV-2023-72)**.
+
+
+## [OSV-2023-72](https://osv.dev/vulnerability/OSV-2023-72)
+
+<details>
+<summary>Details</summary>
+
+> OSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56057
+> 
+> ```
+> Crash type: Heap-buffer-overflow WRITE 4
+> Crash state:
+> perfetto::trace_processor::TrackEventParser::ParseTrackDescriptor
+> perfetto::trace_processor::TrackEventModule::ParseTracePacketData
+> perfetto::trace_processor::ProtoTraceParser::ParseTracePacket
+> ```
+> 
+
+</details>
+
+
+
+---
+
+### Affected Packages
+| Source | Package Name | Package Version |
+| --- | --- | --- |
+| lockfile:/usr/local/google/home/rexpan/Documents/Project/engine/deps_flatten.txt | https://fuchsia.googlesource.com/third_party/android.googlesource.com/platform/external/perfetto | b8da07095979310818f0efde2ef3c69ea70d62c5 |
+
+## Remediation
+
+
+
+To fix these vulnerabilities, update the vulnerabilities past the listed fixed versions below.
+
+### Fixed Versions
+| Vulnerability ID | Package Name | Fixed Version |
+| --- | --- | --- |
+| OSV-2023-72 | perfetto | 9a7f09383dd39f19e662d428321ca708a2a600a3 |
+
+
+If you believe these vulnerabilities do not affect your code and wish to ignore them, add them to the ignore list in an
+`osv-scanner.toml` file located in the same directory as the lockfile containing the vulnerable dependency.
+
+See the format and more options in our documentation here: https://google.github.io/osv-scanner/configuration/
+
+Add or append these values to the following config files to ignore this vulnerability:
+
+
+`/usr/local/google/home/rexpan/Documents/Project/engine/osv-scanner.toml`
+```
+[[IgnoredVulns]]
+id = "OSV-2023-72"
+reason = "Your reason for ignoring this vulnerability"
+```
+
diff --git a/internal/output/sarif.go b/internal/output/sarif.go
index 5ff47a9..525d68e 100644
--- a/internal/output/sarif.go
+++ b/internal/output/sarif.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 	"text/template"
 
+	"github.com/google/osv-scanner/internal/utility/results"
 	"github.com/google/osv-scanner/internal/version"
 	"github.com/google/osv-scanner/pkg/models"
 	"github.com/jedib0t/go-pretty/v6/table"
@@ -120,10 +121,14 @@ func createSARIFAffectedPkgTable(pkgWithSrc []pkgWithSource) table.Writer {
 	helpTable.AppendHeader(table.Row{"Source", "Package Name", "Package Version"})
 
 	for _, ps := range pkgWithSrc {
+		version := ps.Package.Version
+		if ps.Package.Commit != "" {
+			version = ps.Package.Commit
+		}
 		helpTable.AppendRow(table.Row{
 			ps.Source.String(),
 			ps.Package.Name,
-			ps.Package.Version,
+			version,
 		})
 	}
 
@@ -259,6 +264,12 @@ func PrintSARIFReport(vulnResult *models.VulnerabilityResults, outputWriter io.W
 			}
 		}
 
+		// If no advisory for this vulnerability has a summary field,
+		// just show the ID in the shortDescription
+		if shortDescription == "" {
+			shortDescription = gv.DisplayID
+		}
+
 		rule := run.AddRule(gv.DisplayID).
 			WithShortDescription(sarif.NewMultiformatMessageString(shortDescription)).
 			WithFullDescription(sarif.NewMultiformatMessageString(longDescription).WithMarkdown(longDescription)).
@@ -285,9 +296,8 @@ func PrintSARIFReport(vulnResult *models.VulnerabilityResults, outputWriter io.W
 				WithMessage(
 					sarif.NewTextMessage(
 						fmt.Sprintf(
-							"Package '%s@%s' is vulnerable to '%s'%s.",
-							pws.Package.Name,
-							pws.Package.Version,
+							"Package '%s' is vulnerable to '%s'%s.",
+							results.PkgToString(pws.Package),
 							gv.DisplayID,
 							alsoKnownAsStr,
 						))).
diff --git a/internal/output/table.go b/internal/output/table.go
index 3eb7523..6976772 100644
--- a/internal/output/table.go
+++ b/internal/output/table.go
@@ -12,6 +12,7 @@ import (
 	v2_metric "github.com/goark/go-cvss/v2/metric"
 	v3_metric "github.com/goark/go-cvss/v3/metric"
 
+	"github.com/google/osv-scanner/internal/utility/results"
 	"github.com/google/osv-scanner/pkg/models"
 
 	"github.com/jedib0t/go-pretty/v6/table"
@@ -109,7 +110,8 @@ func tableBuilderInner(vulnResult *models.VulnerabilityResults, addStyling bool,
 				outputRow = append(outputRow, MaxSeverity(group, pkg))
 
 				if pkg.Package.Ecosystem == "" && pkg.Package.Commit != "" {
-					outputRow = append(outputRow, "GIT", pkg.Package.Commit, pkg.Package.Commit)
+					pkgCommitStr := results.PkgToString(pkg.Package)
+					outputRow = append(outputRow, "GIT", pkgCommitStr, pkgCommitStr)
 					shouldMerge = true
 				} else {
 					outputRow = append(outputRow, pkg.Package.Ecosystem, pkg.Package.Name, pkg.Package.Version)
diff --git a/internal/utility/results/results.go b/internal/utility/results/results.go
new file mode 100644
index 0000000..131be97
--- /dev/null
+++ b/internal/utility/results/results.go
@@ -0,0 +1,24 @@
+package results
+
+import (
+	"fmt"
+
+	"github.com/google/osv-scanner/pkg/models"
+)
+
+// Number of characters to display a git commit
+const ShortCommitLen = 8
+
+func PkgToString(pkgInfo models.PackageInfo) string {
+	if pkgInfo.Commit != "" {
+		if pkgInfo.Name != "" {
+			// https://github.com/google/osv-scanner@12345678
+			return fmt.Sprint(pkgInfo.Name, "@", pkgInfo.Commit[:ShortCommitLen])
+		}
+		// 1234567890abcdefghij1234567890abcdefghij
+		return pkgInfo.Commit
+	}
+
+	// abc@v1.2.3
+	return fmt.Sprint(pkgInfo.Name, "@", pkgInfo.Version)
+}
diff --git a/pkg/lockfile/osv-vuln-results.go b/pkg/lockfile/osv-vuln-results.go
index 2f2cf48..c1e1ed1 100644
--- a/pkg/lockfile/osv-vuln-results.go
+++ b/pkg/lockfile/osv-vuln-results.go
@@ -32,6 +32,7 @@ func (e OSVScannerResultsExtractor) Extract(f DepFile) ([]PackageDetails, error)
 			if pkg.Package.Commit != "" { // Prioritize results
 				packages = append(packages, PackageDetails{
 					Commit: pkg.Package.Commit,
+					Name:   pkg.Package.Name,
 				})
 			} else {
 				packages = append(packages, PackageDetails{
diff --git a/pkg/models/results.go b/pkg/models/results.go
index 2ed4cc1..02d9f2e 100644
--- a/pkg/models/results.go
+++ b/pkg/models/results.go
@@ -49,6 +49,10 @@ type SourceInfo struct {
 	Type string `json:"type"`
 }
 
+type Metadata struct {
+	RepoURL string `json:"repo_url"`
+}
+
 func (s SourceInfo) String() string {
 	return s.Type + ":" + s.Path
 }
diff --git a/pkg/osv/osv.go b/pkg/osv/osv.go
index 6cb95af..3d9a13b 100644
--- a/pkg/osv/osv.go
+++ b/pkg/osv/osv.go
@@ -39,10 +39,11 @@ type Package struct {
 
 // Query represents a query to OSV.
 type Query struct {
-	Commit  string            `json:"commit,omitempty"`
-	Package Package           `json:"package,omitempty"`
-	Version string            `json:"version,omitempty"`
-	Source  models.SourceInfo `json:"-"`
+	Commit   string            `json:"commit,omitempty"`
+	Package  Package           `json:"package,omitempty"`
+	Version  string            `json:"version,omitempty"`
+	Source   models.SourceInfo `json:"-"` // TODO: Move this into Info struct in v2
+	Metadata models.Metadata   `json:"-"`
 }
 
 // BatchedQuery represents a batched query to OSV.
@@ -95,6 +96,9 @@ func MakePkgRequest(pkgDetails lockfile.PackageDetails) *Query {
 	// API has trouble parsing requests with both commit and Package details filled in
 	if pkgDetails.Ecosystem == "" && pkgDetails.Commit != "" {
 		return &Query{
+			Metadata: models.Metadata{
+				RepoURL: pkgDetails.Name,
+			},
 			Commit: pkgDetails.Commit,
 		}
 	} else {
diff --git a/pkg/osvscanner/osvscanner.go b/pkg/osvscanner/osvscanner.go
index 6bb9e0f..3f18e86 100644
--- a/pkg/osvscanner/osvscanner.go
+++ b/pkg/osvscanner/osvscanner.go
@@ -589,7 +589,7 @@ func DoScan(actions ScannerActions, r reporter.Reporter) (models.VulnerabilityRe
 		return models.VulnerabilityResults{}, err
 	}
 
-	vulnerabilityResults := groupResponseBySource(r, query, hydratedResp, actions.CallAnalysis)
+	vulnerabilityResults := buildVulnerabilityResults(r, query, hydratedResp, actions.CallAnalysis)
 
 	filtered := filterResults(r, &vulnerabilityResults, &configManager)
 	if filtered > 0 {
diff --git a/pkg/osvscanner/vulnerability_result.go b/pkg/osvscanner/vulnerability_result.go
index 7ad57fc..64170f0 100644
--- a/pkg/osvscanner/vulnerability_result.go
+++ b/pkg/osvscanner/vulnerability_result.go
@@ -11,9 +11,9 @@ import (
 	"github.com/google/osv-scanner/pkg/reporter"
 )
 
-// groupResponseBySource converts raw OSV API response into structured vulnerability information
+// buildVulnerabilityResults converts raw OSV API response into structured vulnerability information
 // grouped by source location.
-func groupResponseBySource(r reporter.Reporter, query osv.BatchedQuery, resp *osv.HydratedBatchedResponse, callAnalysis bool) models.VulnerabilityResults {
+func buildVulnerabilityResults(r reporter.Reporter, query osv.BatchedQuery, resp *osv.HydratedBatchedResponse, callAnalysis bool) models.VulnerabilityResults {
 	output := models.VulnerabilityResults{
 		Results: []models.PackageSource{},
 	}
@@ -27,6 +27,7 @@ func groupResponseBySource(r reporter.Reporter, query osv.BatchedQuery, resp *os
 		var pkg models.PackageVulns
 		if query.Commit != "" {
 			pkg.Package.Commit = query.Commit
+			pkg.Package.Name = query.Metadata.RepoURL
 		} else if query.Package.PURL != "" {
 			var err error
 			pkg.Package, err = models.PURLToPackage(query.Package.PURL)


Test patch:
diff --git a/cmd/osv-scanner/main_test.go b/cmd/osv-scanner/main_test.go
index f8ef129..9505318 100644
--- a/cmd/osv-scanner/main_test.go
+++ b/cmd/osv-scanner/main_test.go
@@ -710,6 +710,141 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
 	}
 }
 
+// TestRun_GithubActions tests common actions the github actions reusable workflow will run
+func TestRun_GithubActions(t *testing.T) {
+	t.Parallel()
+
+	tests := []cliTestCase{
+		{
+			name:         "scanning osv-scanner custom format",
+			args:         []string{"", "-L", "osv-scanner:./fixtures/locks-insecure/osv-scanner-flutter-deps.json"},
+			wantExitCode: 1,
+			wantStdout: `
+				Scanned <rootdir>/fixtures/locks-insecure/osv-scanner-flutter-deps.json file as a osv-scanner and found 3 packages
+				+--------------------------------+------+-----------+----------------------------+----------------------------+-------------------------------------------------------+
+				| OSV URL                        | CVSS | ECOSYSTEM | PACKAGE                    | VERSION                    | SOURCE                                                |
+				+--------------------------------+------+-----------+----------------------------+----------------------------+-------------------------------------------------------+
+				| https://osv.dev/CVE-2023-39137 | 7.8  | GIT       |  https://github.com/brendan-duncan/archive.git@9de7a054 | fixtures/locks-insecure/osv-scanner-flutter-deps.json |
+				| https://osv.dev/CVE-2023-39139 | 7.8  | GIT       |  https://github.com/brendan-duncan/archive.git@9de7a054 | fixtures/locks-insecure/osv-scanner-flutter-deps.json |
+				+--------------------------------+------+-----------+---------------------------------------------------------+-------------------------------------------------------+
+`,
+			wantStderr: "",
+		},
+		{
+			name:         "scanning osv-scanner custom format output json",
+			args:         []string{"", "-L", "osv-scanner:./fixtures/locks-insecure/osv-scanner-flutter-deps.json", "--format=sarif"},
+			wantExitCode: 1,
+			wantStdout: `
+        {
+          "version": "2.1.0",
+          "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
+          "runs": [
+            {
+              "tool": {
+                "driver": {
+                  "informationUri": "https://github.com/google/osv-scanner",
+                  "name": "osv-scanner",
+                  "rules": [
+                    {
+                      "id": "CVE-2023-39137",
+                      "shortDescription": {
+                        "text": "CVE-2023-39137"
+                      },
+                      "fullDescription": {
+                        "text": "An issue in Archive v3.3.7 allows attackers to spoof zip filenames which can lead to inconsistent filename parsing.",
+                        "markdown": "An issue in Archive v3.3.7 allows attackers to spoof zip filenames which can lead to inconsistent filename parsing."
+                      },
+                      "deprecatedIds": [
+                        "CVE-2023-39137"
+                      ],
+                      "help": {
+                        "text": "%%",
+                        "markdown": "%%"
+                      }
+                    },
+                    {
+                      "id": "CVE-2023-39139",
+                      "shortDescription": {
+                        "text": "CVE-2023-39139"
+                      },
+                      "fullDescription": {
+                        "text": "An issue in Archive v3.3.7 allows attackers to execute a path traversal via extracting a crafted zip file.",
+                        "markdown": "An issue in Archive v3.3.7 allows attackers to execute a path traversal via extracting a crafted zip file."
+                      },
+                      "deprecatedIds": [
+                        "CVE-2023-39139"
+                      ],
+                      "help": {
+                        "text": "%%",
+                        "markdown": "%%"
+                      }
+                    }
+                  ],
+                  "version": "1.4.1"
+                }
+              },
+              "artifacts": [
+                {
+                  "location": {
+                    "uri": "file://<rootdir>/fixtures/locks-insecure/osv-scanner-flutter-deps.json"
+                  },
+                  "length": -1
+                }
+              ],
+              "results": [
+                {
+                  "ruleId": "CVE-2023-39137",
+                  "ruleIndex": 0,
+                  "level": "warning",
+                  "message": {
+                    "text": "Package 'https://github.com/brendan-duncan/archive.git@9de7a054' is vulnerable to 'CVE-2023-39137'."
+                  },
+                  "locations": [
+                    {
+                      "physicalLocation": {
+                        "artifactLocation": {
+                          "uri": "file://<rootdir>/fixtures/locks-insecure/osv-scanner-flutter-deps.json"
+                        }
+                      }
+                    }
+                  ]
+                },
+                {
+                  "ruleId": "CVE-2023-39139",
+                  "ruleIndex": 1,
+                  "level": "warning",
+                  "message": {
+                    "text": "Package 'https://github.com/brendan-duncan/archive.git@9de7a054' is vulnerable to 'CVE-2023-39139'."
+                  },
+                  "locations": [
+                    {
+                      "physicalLocation": {
+                        "artifactLocation": {
+                          "uri": "file://<rootdir>/fixtures/locks-insecure/osv-scanner-flutter-deps.json"
+                        }
+                      }
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }`,
+			wantStderr: `
+				Scanned <rootdir>/fixtures/locks-insecure/osv-scanner-flutter-deps.json file as a osv-scanner and found 3 packages
+			`,
+		},
+	}
+	for _, tt := range tests {
+		tt := tt
+		t.Run(tt.name, func(t *testing.T) {
+			t.Parallel()
+
+			testCli(t, tt)
+		})
+	}
+}
+
 func TestRun_LocalDatabases(t *testing.T) {
 	t.Parallel()
 
diff --git a/internal/output/sarif_internal_test.go b/internal/output/sarif_internal_test.go
index 529a545..03e0de4 100644
--- a/internal/output/sarif_internal_test.go
+++ b/internal/output/sarif_internal_test.go
@@ -18,6 +18,10 @@ func Test_createSARIFHelpText(t *testing.T) {
 			gv:       testutility.LoadJSONFixture[groupedSARIFFinding](t, "fixtures/vuln-grouped.json"),
 			wantPath: "fixtures/sarif-output.md",
 		},
+		{
+			gv:       testutility.LoadJSONFixture[groupedSARIFFinding](t, "fixtures/commit-grouped.json"),
+			wantPath: "fixtures/sarif-commit-output.md",
+		},
 	}
 	for _, tt := range tests {
 		tt := tt
diff --git a/pkg/osvscanner/vulnerability_result_internal_test.go b/pkg/osvscanner/vulnerability_result_internal_test.go
index 36b789e..73ccf51 100644
--- a/pkg/osvscanner/vulnerability_result_internal_test.go
+++ b/pkg/osvscanner/vulnerability_result_internal_test.go
@@ -26,7 +26,7 @@ func Test_groupResponseBySource(t *testing.T) {
 		tt := tt // Reinitialize for t.Parallel()
 		t.Run(tt.name, func(t *testing.T) {
 			t.Parallel()
-			if got := groupResponseBySource(tt.args.r, tt.args.query, tt.args.resp, tt.args.callAnalysis); !reflect.DeepEqual(got, tt.want) {
+			if got := buildVulnerabilityResults(tt.args.r, tt.args.query, tt.args.resp, tt.args.callAnalysis); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("groupResponse() = %v, want %v", got, tt.want)
 			}
 		})