何を見るチェックか
GitHub Actions のワークフローには、GITHUB_TOKEN という自動発行のトークンが渡されます。
Scorecard は、そのトークンにどこまでの権限が与えられているかを、
ワークフローファイルの permissions: の記述から調べます。
見ているのは主に次の点です。
- ワークフロー全体(トップレベル)に
permissions: read-allなどの読み取りのみ指定があるか - 書き込みが要るジョブにだけ、必要な範囲で
permissionsが指定されているか contents: writeやpackages: writeのような強い権限が、ジョブ単位に限定されているか
トップレベルで読み取りのみに絞り、必要なジョブだけ個別に緩める、 という書き方が最も高く評価されます。
点が低いと何を意味するか
点が低いということは、CI が持っている権限が、その処理に必要な範囲より広い可能性がある、 という意味です。
CI で任意のコードが実行されてしまう状況(依存の乗っ取り、悪意ある Pull Request など)が 起きたとき、権限の広さがそのまま被害の大きさになります。
contents: writeがあれば、リポジトリのコードを書き換えられるpackages: writeがあれば、パッケージを公開できるid-token: writeがあれば、外部サービスへの認証を取得できる
逆に読み取りだけに絞ってあれば、同じことが起きてもできることが限られます。
これは「攻撃を受けている」ではなく、事故が起きたときの被害範囲の話です。
誤解しやすい点
permissions: を書いていないだけで低く出ます。ここが最も多いケースです。
GitHub Actions は、permissions: を明示していない場合、
リポジトリまたは組織の既定値を使います。既定が「読み書き」のままだと、
すべてのワークフローが書き込み権限を持ちます。
つまりこの項目が低いプロジェクトの大半は、 意図して広い権限を与えているのではなく、既定のまま何も書いていないだけです。
また、次の場合も低く出ます。
- リポジトリ設定側で既定を読み取りのみにしている場合。 実際には絞られていますが、Scorecard はワークフローファイルしか見ないため、 その設定を読み取れません。
- GitHub Actions を使っていない場合。 検査対象が無いので評価されません。
- リリースや自動コミットのために、本当に書き込みが要る場合。 必要な権限を与えているだけでも、トップレベルに書かれていれば減点されます。
「絞っていない」であって「漏れている」ではありません。
採用する側が確認すべきこと
利用者の立場では、この項目はそのプロジェクトの CI が乗っ取られたときの被害の大きさを示します。 直接あなたのコードに影響するものではありません。
見るとすれば、次の組み合わせです。
-
リリース成果物が CI で自動生成されているか。 自動生成なら、CI の権限がそのままリリースの汚染につながります。
-
Pinned-Dependencies と Dangerous-Workflow を合わせて見る。 「固定していない依存」×「広い権限」×「危険な書き方」が重なると、 CI が入口になる経路が現実的になります。単独で見ても意味は薄いです。
-
自分のプロジェクト側の権限を絞る。 相手側は変えられませんが、自分の CI は今日から絞れます。
メンテナーなら何を改善できるか
2か所を直すだけで、多くの場合は満点になります。
1. ワークフローのトップレベルで読み取りのみにする
name: CI
permissions:
contents: read
on: [push, pull_request]
2. 書き込みが要るジョブにだけ、必要な権限を足す
jobs:
release:
permissions:
contents: write # リリースを作るため
id-token: write # provenance を付けるため
あわせて、リポジトリ設定の
Settings → Actions → General → Workflow permissions を
Read repository contents and packages permissions にしておくと、
新しく足したワークフローも既定で絞られます。
組織であれば、組織設定で同じことを一括で指定できます。