EmotionTechテックブログ

株式会社エモーションテックのProduct Teamのメンバーが、日々の取り組みや技術的なことを発信していくブログです。

GitHubのリポジトリを横断的にライセンスチェックする方法

はじめに

こんにちは、PMのかどたみです。
今回はライセンスに関するお話です。以前cargo-deny によるクレートのライセンス確認
という記事でよしかわさんにRustにおいて採用しているクレートに意図しないライセンスが含まれていないかをチェックする方法を紹介してもらいました。 Rustであれば記事の方法をなぞればよいのですが、エモーションテックではRustの他にもTypeScriptやPythonといった言語も利用してアプリケーション開発を行っています。
今回は言語をまたがってライセンスチェックができないか検討したのでその紹介をしたいと思います。

背景

Rust以外の言語でのライセンス管理も便利なライブラリが用意されているようですが、利用する言語やプロジェクトが増えるたびに設定をいれるのは手間です。できればGitHub上で管理されているリポジトリを横断的に精査して意図しないソフトウェアライセンスが含まれていないかどうかチェックできるとありがたいです。

方針

ライセンス情報の取得はSBOMから行います。SBOM自体は各リポジトリの「Insights」タブの「Dependency Graph」からもエクスポートすることができます。
この機能を利用すればRPAのような自動化手法でも管理対象のすべてのリポジトリのSBOMを出力することもできますが、今回はGitHub Actionsを用いて出力してみたいと思います。

GitHub Actions

GitHubからSBOMをダウンロードできるREST APIが提供されています。こちらをGitHub Actionsから実行します。

gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/${{orgName}}/${{repoName}}/dependency-graph/sbom

この結果をパースして各ライブラリのライセンス情報を取得してみます。まずはSBOMのJSONの構造を見てみましょう。

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "com.github.org/repo",
  "documentNamespace": "https://spdx.org/spdxdocs/protobom/82154409-d0dc-418b-8057-7e70cc2a9cf4",
  "creationInfo": {
    "creators": [
      "Tool: protobom-v0.0.0-20250424205439-da85b2033087+dirty",
      "Tool: GitHub.com-Dependency-Graph"
    ],
    "created": "2025-04-25T00:18:35Z"
  },
  "packages": [
    {
      "name": "ライブラリ名",
      "SPDXID": "SPDXRef-XXXXX",
      "versionInfo": "3.0.2",
      "downloadLocation": "NOASSERTION",
      "filesAnalyzed": false,
      "licenseConcluded": "ライセンス名",
      "copyrightText": "コピーライト",
      "externalRefs": [
        {
          "referenceCategory": "XXX",
          "referenceType": "XXX",
          "referenceLocator": "XXX"
        }
      ]
    },
  ],
  "relationships": [
    {
    "spdxElementId": "SPDXRef-XXXXX",
    "relatedSpdxElement": "SPDXRef-XXXXX",
    "relationshipType": "DEPENDS_ON"
    }
  ]
}

packages にライブラリの情報が配列で格納されており、その中のlicenseConcluded にライセンス情報が記載されていることがわかります。
これらを抽出し、csvで出力するコマンドは以下です。

gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/${{orgName}}/${{repoName}}/dependency-graph/sbom | jq -r '.sbom.packages[] | ["${{repoName}}", .name , .licenseConcluded ] | @csv' > license.csv

これでレポジトリ名、ライブラリ名、ライセンスの3列のcsvが生成できます。
csvをそのままダウンロードしても良いですし、ここから工夫して入ってほしくないライセンスがある場合はアラートを飛ばすなどをしても良いかもしれません。
注意点としてlicenseConcludedが存在せず、SBOMからではライセンス情報がわからないライブラリもいくつか確認できました。GitHubから取得できるSBOMの情報はnpmなどのパッケージ管理ベンダーの情報に依存しているようでそこに情報がない場合は取得できません。
存在しないライブラリについては定期的に確認する必要がありそうです。

最後に複数のリポジトリのライセンス情報を出力するworkflowの設定ファイルを記載しておきます。どなたかの参考になれば幸いです。

on:
  workflow_dispatch:

jobs:
  create-license-lists:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        repo:
          - repositoryName
    steps:
      - name: Generate github token
        id: generate_token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.PRIVATE_KEY }}

      - name: use token
        run: echo "$GITHUB_TOKEN"
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}

      - name: mkdir result
        run: mkdir result

      - name: get sbom
        working-directory: result
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
        run: |
          gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/wizpra/${{matrix.repo}}/dependency-graph/sbom | jq -r '.sbom.packages[] | ["${{matrix.repo}}", .name , .licenseConcluded ] | @csv' > ${{matrix.repo}}.csv

      - name: upload list
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.repo }}
          path: result/${{ matrix.repo }}.csv

おわりに

今回はライセンス情報をGitHub Actionsで一括取得する方法を紹介しました。日々の開発で便利なライブラリを使うことは多いですが、なかなかライセンスチェックをもれなく行うのは難しいので機械的にチェックして組織として健全な開発をしていきたいですね。

エモーションテックでは顧客体験、従業員体験の改善をサポートし、世の中の体験を変えるプロダクトを開発しています。プロダクトに興味のある方はぜひ採用ページからご応募をお願いいたします。

hrmos.co hrmos.co hrmos.co