# プルリクエストへのコメント

GitHub のすべてのプルリクエストに、既知のセキュリティアドバイザリがある依存関係をすべて一覧にしたコメントを1件投稿します。Deepの機能で、オンにするまではオフです。

プルリクエストへのコメントは、ロックファイル内のどの依存関係のバージョンに既知のセキュリティアドバイザリがあるかを、プルリクエストの中でチームに伝えます。変更で追加されたものから順に示します。これはDeepの機能で、オンにするまではオフです。

## 何をするか

プルリクエストが作成されたとき、新しいコミットが追加されたとき、または再オープンされたとき、Lockpickはロックファイルを2つの時点で読み取ります。プルリクエストのheadと、そのブランチがベースブランチから分岐した時点（マージベース）です。両方の正確なバージョンを、既知のセキュリティアドバイザリと照合します。

このチェックは決定的です。コードは実行されず、AIによるレビューもありません。

Lockpickは2つのリストを比較するため、プルリクエストが追加または変更したものと、もともとあったものを区別できます。ブランチを作成した後にベースブランチに入った問題は、そのプルリクエストのものとしては数えません。

リポジトリにあるすべてのロックファイル、または選んだロックファイルを読み取ります。ロックファイルはそれぞれ個別にチェックされるため、モノレポのGoモジュールとJavaScriptプロジェクトがすべて対象になります。プルリクエストで変更されていないロックファイルは、Lockpickがまったく同じファイルをすでに読み取っていれば、再ダウンロードしません。

## 対応しているロックファイル

読み取るのは、ロックファイルが固定している正確なバージョンだけです。依存関係の解決、インストール、実行は一切行いません。

| スタック                    | ロックファイル                                                                                            | アドバイザリの取得元  |
| ----------------------- | -------------------------------------------------------------------------------------------------- | ----------- |
| JavaScript と TypeScript | `pnpm-lock.yaml`、`package-lock.json`、`npm-shrinkwrap.json`、`yarn.lock`（classic と Berry）、`bun.lock` | npm         |
| Python                  | `poetry.lock`、`uv.lock`、`Pipfile.lock`、`pdm.lock`、`requirements.txt`（`==` で固定したものだけ）               | PyPI        |
| PHP                     | `composer.lock`（開発用パッケージを含む）                                                                       | Packagist   |
| Ruby                    | `Gemfile.lock`、`gems.locked`                                                                       | RubyGems    |
| Go                      | `go.mod`、およびビルドに使う Go ツールチェーン                                                                      | Go          |
| Java と Kotlin           | `gradle.lockfile`、`buildscript-gradle.lockfile`、`pom.xml`                                          | Maven       |
| Rust                    | `Cargo.lock`                                                                                       | crates.io   |
| .NET                    | `packages.lock.json`                                                                               | NuGet       |
| Dart と Flutter          | `pubspec.lock`                                                                                     | Pub         |
| Elixir                  | `mix.lock`                                                                                         | Hex         |
| Swift                   | `Package.resolved`                                                                                 | Swift パッケージ |

次の2種類のファイルは、チェックできるようにする方法を伝えるためだけに認識されます。

* **`bun.lockb`** は Bun のバイナリ形式のロックファイルです。`bun install --save-text-lockfile` を実行し、生成された `bun.lock` をコミットして、それを選んでください。
* **ロックファイルのない Gradle ビルド**（`build.gradle` または `build.gradle.kts`）はチェックできません。依存関係のロック（`dependencyLocking { lockAllConfigurations() }`）を有効にし、`./gradlew dependencies --write-locks` を実行して、`gradle.lockfile` をコミットし、それを選んでください。

これらのファイルや、Lockpickが読み取れなかったロックファイルについては、コメントにはチェックできなかったと表示されます。プルリクエストに問題がないとは決して表示されません。

## オンにする

必要なもの:

* GitHub リポジトリが接続されているサイト（**設定**、**リポジトリ**の順に開いた画面で接続します）
* ワークスペースのDeepまたはMaster Key
* そのサイトの管理権限

リポジトリをリンクすると、**プルリクエストへのコメント**がオンになります。スイッチはサイトごとに1つあり、**設定**、**GitHub**の順に開いた画面にあります。そこでオフにすると、同じリポジトリをもう一度リンクしてもオフのままです。別のリポジトリをリンクすると、再びオンになります。DeepもMaster Keyもない場合、スイッチには「オンですが一時停止中です」と表示され、何も投稿されません。

リポジトリをリンクすると、Lockpickは見つかったすべてのロックファイルを最大20個までチェックし、リポジトリを読み取るたびに探し直します。そのため、あとから追加したプロジェクトも対象になります。`testdata` と `fixtures` フォルダ内のロックファイルは除外され、GitHub がリポジトリで集計する言語によって、どれを先にするかが決まります。たとえば、ほとんどが Go のリポジトリなら、その `go.mod` ファイルが先になります。ロックファイルのチェックを外したり、代わりに `apps/web/pnpm-lock.yaml` のようなパスを入力したりできます。選んだリストは、もう一度すべてのロックファイルを選ぶまで保持されます。

## コメントの内容

Lockpickはプルリクエストごとに1件のコメントを保持し、そのコメントをその場で編集します。プッシュのたびに新しいコメントを投稿することはありません。

ロックファイルに触れているかどうかに関係なく、すべてのプルリクエストにコメントが付きます。コメントには、プルリクエストのheadにある依存関係のバージョンのうち、既知のアドバイザリがあるものが、直接・推移的の両方ですべて一覧表示されます。先頭の行では、重大度ごとの件数が示されます（例: 「脆弱なバージョン 81 件: 緊急 6 · 高 14 · 中 30」）。行は、**悪用確認済み**、緊急、高、中、低、**未評価**の順に並び、その中ではパッケージ名順です。

* **このプルリクエストで追加・変更**: 各行に、パッケージ、バージョン（プルリクエストで変更された場合は置き換え前のバージョンも）、重大度、攻撃者がすでにその問題を悪用している場合は**悪用確認済み**バッジ、アドバイザリへのリンク、修正されたバージョンが表示されます。
* **このプルリクエストの後もリポジトリに残るもの**: ベースブランチにあり、プルリクエストのheadにも残っている脆弱なバージョンです。すべてのロックファイルを通じて最も重大な25件が、ロックファイルごとにまとめて表示され、Lockpickで残りを見るためのリンクが付きます。
* Go リポジトリの場合は、ビルドに使う Go のバージョン（`go.mod` の `toolchain` 行、なければ `go` 行）も対象になります。その標準ライブラリのアドバイザリは、**Go 標準ライブラリ**という1行にまとめられ、件数と、それらをすべて修正するリリースが表示されます。Lockpickはバージョンを比較するだけなので、到達可能性はチェックしていないと明記します。
* プルリクエストで修正されるアドバイザリの件数を示す行と、修正されたバージョンの短いリスト（パッケージ、古いバージョン → 新しいバージョン、または削除）が、重大度の高い順に表示されます。最初の10件が表示され、残りへのリンクが付きます。

既知のアドバイザリがあるバージョンがない場合、コメントは読み取ったロックファイルとコミットを示して、そのことを1行で伝えます。

後のコミットで状況が変わると、Lockpickはコメントを編集します。古くなった警告が残ることはありません。

Lockpickがロックファイルを読み取れない場合は、チェックできなかったと表示します。これは、ファイルが25 MBを超えている場合、別の形式の場合、またはファイルがない場合に起こります。ロックファイルがない場合は、探した場所（ベースブランチとプルリクエストのhead）を示し、リポジトリの言語から考えられるロックファイルを提案し、設定へのリンクを表示します。ファイルを読み取っていないのに、プルリクエストに問題がないと表示することは決してありません。

Go の脆弱性データベースにある多くのアドバイザリのように、重大度がないアドバイザリもあります。その場合、Lockpickは手元にある一致するCVEやGitHubアドバイザリの重大度を使います。どちらもない場合、その行は**未評価**と表示され、評価済みの行の後に並びます。

## 権限

Lockpick GitHub App は **Contents** と **Metadata** を読み取ります。この機能では、プルリクエストを読み取ってコメントを投稿するために、読み取りと書き込みの **Pull requests** 権限も必要です。

Lockpickは、その1つのリポジトリだけに限定された有効期間の短いトークンを使います。マージは行わず、コードも変更しません。

### 既存のインストール

この機能より前に Lockpick GitHub App をインストールしている場合は、GitHub で新しい権限を承認する必要があります。インストールのオーナーにメールが届き、GitHub はインストールの設定ページにバナーを表示します。

承認されるまで、**設定**、**リポジトリ**の順に開いた画面には、インストールへのリンクとともに**権限の承認待ち**と表示されます。それより前にスイッチをオンにしておくこともできます。承認すると動作し始めます。

## 枠と上限

プルリクエストへのコメントは、スキャン枠を使いません。スキャンも作成しません。

公平さを保つため、Lockpickが実行するチェックは、プルリクエストごとに1時間あたり約20回、ワークスペースごとに1時間あたり600回までです。上限によって拒否されたチェックは破棄されます。1時間が過ぎた後の次のプッシュで再試行され、常に最新のコミットが読み取られます。

## 誰として動作するか

コメントを投稿するのは Lockpick GitHub App ですが、スイッチは、それをオンにした管理者のアクセス権で動作します。

* その人がサイトへのアクセス権を失うと、この機能は自動的にオフになります。別の管理者がもう一度オンにできます。
* ワークスペースがDeepを失うと、この機能は一時停止し、コメントは止まります。アップグレードすると自動的に再開します。

## オフにする

スイッチをオフにする、リポジトリの接続を解除する、または別のリポジトリを選ぶと、Lockpickは停止します。すでに GitHub にあるコメントはそのまま残ります。Lockpickがそれらを削除することはありません。

GitHub で Lockpick GitHub App をアンインストールすると、Lockpickはそのリポジトリへのアクセス権をすべて失います。

## 2つのサイトが同じリポジトリを使う場合

2つのLockpickサイトが同じリポジトリを接続している場合、コメントを保持するのはそのうち1つだけです。プルリクエストに付くコメントは2件ではなく、1件のままです。

> **注意**
>
> コメントに一覧表示されるのは、ロックファイル内の正確なバージョンに対する既知のアドバイザリです。完全なセキュリティレビューではありません。コメントのないプルリクエストが、安全だと証明されたわけではありません。