| 1 | --- |
| 2 | title: Supply chain |
| 3 | description: The dependency graph, an SPDX SBOM of it, dependency review on pull requests, and vulnerability alerts. |
| 4 | --- |
| 5 | |
| 6 | g1t reads every lockfile on your default branch, on every push to it and |
| 7 | daily: `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `Cargo.lock`, |
| 8 | `go.mod`, `go.sum`, `requirements.txt` and `poetry.lock`, up to four |
| 9 | directories deep and outside `node_modules`, `vendor`, `target`, `dist` |
| 10 | and the like. From them come the dependency graph, its SBOM, vulnerability |
| 11 | alerts and [security updates](/guides/security/#security-updates). |
| 12 | |
| 13 | | Feature | Public repositories | Private repositories | |
| 14 | | --- | --- | --- | |
| 15 | | Dependency graph and SBOM | Free | Free | |
| 16 | | Vulnerability alerts and security updates | Free | Free | |
| 17 | | Dependency review | Free | With the g1t plan | |
| 18 | |
| 19 | ## The dependency graph |
| 20 | |
| 21 | `g1t.sh/<owner>/<project>/security/dependency-graph` lists every package the |
| 22 | lockfiles resolve, per lockfile, with: |
| 23 | |
| 24 | | Column | | |
| 25 | | --- | --- | |
| 26 | | Relationship | **Direct** (the project asks for it) or **transitive** (another package does), where the lockfile says; **not said** where it does not. | |
| 27 | | Development | Whether it is for development or tests only, where the lockfile says. | |
| 28 | | License | The license the lockfile records (npm's lockfiles do; most others do not). | |
| 29 | | Vulnerabilities | Open vulnerability alerts on that version. | |
| 30 | |
| 31 | What each lockfile says: |
| 32 | |
| 33 | | Lockfile | Direct or transitive | Development | License | |
| 34 | | --- | --- | --- | --- | |
| 35 | | `package-lock.json` (v2, v3) | From the project's and its workspaces' own `dependencies` | Yes | Yes | |
| 36 | | `pnpm-lock.yaml` | From `importers` (or the top-level lists in older files) | Yes | No | |
| 37 | | `Cargo.lock` | From the dependencies of the workspace's own crates | No | No | |
| 38 | | `go.mod` | `// indirect` marks transitive | No | No | |
| 39 | | `requirements.txt` | Every line is direct, unless pip-compile wrote it: then its `# via` notes say | No | No | |
| 40 | | `yarn.lock`, `go.sum`, `poetry.lock`, `package-lock.json` v1 | Not said | v1 only | No | |
| 41 | |
| 42 | ## Exporting an SBOM |
| 43 | |
| 44 | **Export SBOM (SPDX)** downloads the graph as an |
| 45 | [SPDX 2.3](https://spdx.github.io/spdx-spec/v2.3/) JSON document, |
| 46 | `<owner>-<project>.spdx.json`: |
| 47 | |
| 48 | - The repository is the document's one described package, versioned by the |
| 49 | commit the lockfiles were read at. |
| 50 | - Every dependency is a package named by its |
| 51 | [package URL](https://github.com/package-url/purl-spec) |
| 52 | (`pkg:npm/%40babel/core@7.24.0`), with its license when the lockfile |
| 53 | records one as an SPDX expression, and `NOASSERTION` otherwise. |
| 54 | - The repository `DEPENDS_ON` each runtime dependency; each development |
| 55 | dependency is a `DEV_DEPENDENCY_OF` it. |
| 56 | |
| 57 | Over the API, `GET /repos/{owner}/{name}/dependency-graph/sbom` returns it in |
| 58 | `sbom`, as SPDX spells it: |
| 59 | |
| 60 | ```sh |
| 61 | curl -s -H "Authorization: Bearer $G1T_TOKEN" \ |
| 62 | https://api.g1t.sh/repos/acme/rocket/dependency-graph/sbom | jq .sbom > rocket.spdx.json |
| 63 | ``` |
| 64 | |
| 65 | ## Dependency review |
| 66 | |
| 67 | On every pull request that opens, or whose head moves, g1t compares the |
| 68 | dependencies at the point it left the default branch with those at its |
| 69 | head. A pull request that changes no lockfile passes at once. Otherwise |
| 70 | each package it adds (or moves to another version) is checked against |
| 71 | [OSV](https://osv.dev), and the **Dependency review** check fails when it |
| 72 | adds: |
| 73 | |
| 74 | - a package with a known vulnerability at or above the severity you |
| 75 | choose, or |
| 76 | - a package with a license you do not allow. |
| 77 | |
| 78 | The review's summary is commented on the pull request, a table per |
| 79 | lockfile of what was added and removed, and the check links to |
| 80 | `g1t.sh/<owner>/<project>/security/pulls/<number>`. Require **Dependency |
| 81 | review** under **Settings → Branches** to block merges on it. |
| 82 | |
| 83 | A pull request has one review comment. When a later review says something |
| 84 | new, that comment is changed in place; when it says the same, the comment |
| 85 | is left alone. A push whose lockfile changes are the ones already reviewed, |
| 86 | such as catching the branch up with its base, is not reviewed again: the |
| 87 | check's result carries over to the new head. |
| 88 | |
| 89 | Advisories are published every day, so a review can be made again: **Re-run |
| 90 | dependency review** in the pull request's checks, or **Re-run** on its |
| 91 | Security checks page, takes the Write role. It updates the check and the |
| 92 | same comment. |
| 93 | |
| 94 | In the repository's **Security settings**: |
| 95 | |
| 96 | | Setting | Default | | |
| 97 | | --- | --- | --- | |
| 98 | | Dependency review | On | Whether pull requests get the check. | |
| 99 | | Fail on vulnerabilities of | High severity or higher | Critical, high, medium, any severity, or never. | |
| 100 | | Licenses not allowed | None | SPDX ids, such as `GPL-3.0-only, AGPL-3.0-only`. An `OR` expression passes when any side is allowed. | |
| 101 | | Comment the summary | On | Whether the review comments on the pull request. | |
| 102 | |
| 103 | Licenses come from the lockfile, so only npm's packages can be refused for |
| 104 | one today. |
| 105 | |
| 106 | `GET /repos/{owner}/{name}/dependency-graph/compare/{basehead}` makes the |
| 107 | same comparison between any two commits, branches or tags, as |
| 108 | `base...head`: |
| 109 | |
| 110 | ```sh |
| 111 | curl -s -H "Authorization: Bearer $G1T_TOKEN" \ |
| 112 | "https://api.g1t.sh/repos/acme/rocket/dependency-graph/compare/main...upgrade-deps" |
| 113 | ``` |
| 114 | |
| 115 | ## Vulnerability alerts |
| 116 | |
| 117 | Vulnerability alerts are at `g1t.sh/<owner>/<project>/security/vulnerabilities`. |
| 118 | How they are found, dismissed and fixed by security updates is in |
| 119 | [Security](/guides/security/#dependencies). Like the other alerts, each can |
| 120 | be dismissed with a reason and reopened. |
| 121 | |
| 122 | ## API and MCP |
| 123 | |
| 124 | | Route | What it does | Scope | |
| 125 | | --- | --- | --- | |
| 126 | | `GET /repos/{owner}/{name}/dependency-graph` | The graph, per lockfile. | `security:read` | |
| 127 | | `GET /repos/{owner}/{name}/dependency-graph/sbom` | The SPDX document, in `sbom`. | `security:read` | |
| 128 | | `GET /repos/{owner}/{name}/dependency-graph/compare/{basehead}` | What changed between two commits, and whether it passes review. | `security:read` | |
| 129 | | `POST /repos/{owner}/{name}/pulls/{number}/dependency-review/rerun` | Runs a pull request's Dependency review check again and returns the review. | `security:write` | |
| 130 | | `GET /repos/{owner}/{name}/vulnerability-alerts` | Lists alerts; filter with `state`, `severity`, `ecosystem`, `package`. | `security:read` | |
| 131 | | `GET /workspaces/{workspace}/vulnerability-alerts` | The same across a workspace. | `security:read` | |
| 132 | | `GET /repos/{owner}/{name}/vulnerability-alerts/{id}` | One alert. | `security:read` | |
| 133 | | `PATCH /repos/{owner}/{name}/vulnerability-alerts/{id}` | `state` `dismissed` with `reason` and `comment`, or `open`. | `security:write` | |
| 134 | |
| 135 | Over MCP, the [`security` tool](/reference/mcp/#security) has |
| 136 | `dependency_graph`, `sbom`, `compare_dependencies`, `rerun_dependency_review`, `vulnerability_alerts`, |
| 137 | `vulnerability_alert` and `update_vulnerability_alert`. Webhooks: |
| 138 | `vulnerability_alert.created`, `.fixed`, `.dismissed` and `.reopened`. |