オープンソースソフトウェア(OSS)を利用する際、ライセンス管理は避けて通れない重要な課題です。
しかし、プロジェクトが大規模になるほど、使用しているライブラリやコンポーネントのライセンスを手動で確認するのは困難になります。そこで活躍するのがscancode-toolkitです。

scancode-toolkitとは

scancode-toolkitは、ソースコードからOSSライセンス、著作権、依存関係などを自動的に検出するオープンソースのツールです。AboutCode(旧nexB)によって開発され、Eclipse Foundation、OpenEmbedded.org、FSF、Red Hatなど多くの組織で利用されています。

📌 公式リンク

主な特徴

包括的なライセンス検出 ScanCode LicenseDBには2,000以上のライセンスが登録されています。MIT、Apache、GPLといった主要なライセンスはもちろん、マイナーなライセンスや独自ライセンスも検出可能です。

高精度な検出エンジン scancode-toolkitは、単純な正規表現や確率的検索に頼らず、ライセンステキストのデータベースとの完全比較(diffベース)を行います。2,000以上のライセンステキストとその多数のバリエーションを基にした検出を実施します。

多様な検出機能 ライセンスだけでなく、以下の情報も抽出できます:

  • 著作権表示
  • パッケージマニフェスト(package.json、requirements.txt、pom.xml等)
  • 直接依存関係と推移的依存関係
  • メールアドレスやURL
  • Package URL(PURL)による一意識別

バイナリファイルにも対応 ソースコードだけでなく、バイナリファイル(.jar、.dll、.so等)やコンパイル済みライブラリからもライセンス情報を検出できます。ソースコードが入手できない商用ライブラリのライセンス確認にも活用できます。

柔軟な出力形式 結果はJSON、YAML、HTML、CSV、SPDX、CycloneDX形式など、様々なフォーマットで出力できます。特にHTML形式は視覚的に分かりやすく、ブラウザで簡単に確認できます。

インストール方法

scancode-toolkitはPythonで書かれており、pipで簡単にインストールできます:

pip install scancode-toolkit

または、GitHubリポジトリからクローンして使用することも可能です。

基本的な使い方

最もシンプルな使用方法は、スキャンしたいディレクトリを指定するだけです:

# HTML形式で出力(視覚的に確認)
scancode -clpieu --html output.html /path/to/project

# JSON形式で出力(プログラム処理用)
scancode -clpieu --json-pp output.json /path/to/project

各オプションの意味:

  • -c: 著作権情報を検出
  • -l: ライセンス情報を検出
  • -p: パッケージ情報を検出
  • -i: 詳細情報を含める
  • -e: メールアドレスを検出
  • -u: URLを検出

実行例:Flaskプロジェクトのスキャン

実際にPythonの人気フレームワークFlaskをスキャンしてみましょう。

スキャンの実行

# Flaskのソースコードを取得
git clone --depth 1 https://github.com/pallets/flask.git

# JSON形式でスキャン実行
scancode -clpieu --json-pp flask_scan.json flask/

実行中の出力

Setup plugins...
Collect file inventory...
Scan files for: info, packages, licenses, copyrights, emails, urls with 8 process(es)...
[####################] 231
Scanning done.
Summary:        info, packages, licenses, copyrights, emails, urls with 8 process(es)
Errors count:   0
Scan Speed:     13.11 files/sec. 97.63 KB/sec.
Initial counts: 282 resource(s): 231 file(s) and 51 directorie(s)
Final counts:   282 resource(s): 231 file(s) and 51 directorie(s) for 1.64 MB
Timings:
  scan_start: 2025-11-03T224718.394746
  scan_end:   2025-11-03T224736.017246
  setup_scan:licenses: 12.34s
  setup: 12.34s
  inventory: 0.18s
  scan: 17.62s
  output:json-pp: 0.31s
  output: 0.31s
  total: 30.47s
Removing temporary files...done.

HTML形式での結果確認

生成されたflask_report.htmlをブラウザで開くと、以下のような情報がテーブル形式で表示されます:

1. Copyrights and Licenses Information(著作権とライセンス情報)

各ファイルで検出されたライセンスと著作権情報が一覧表示されます:

pathstartendwhatvalue
flask/LICENSE.txt11copyrightCopyright 2010 Pallets
flask/LICENSE.txt328licensebsd-new
flask/src/flask/__init__.py13licensebsd-new
flask/src/flask/__init__.py22copyrightCopyright 2010 Pallets

各行には以下の情報が含まれます:

  • path: ファイルパス
  • start/end: ライセンス・著作権表示の行番号
  • what: copyright(著作権)またはlicense(ライセンス)
  • value: 検出された内容(ライセンス名はクリック可能なリンク)

2. File Information(ファイル情報)

スキャンされたファイルの基本情報:

pathtypenamesizeprogramming_language
flask/LICENSE.txtfileLICENSE.txt1475None
flask/src/flask/app.pyfileapp.py60738Python

各ファイルのタイプ、サイズ、プログラミング言語が確認できます。

3. Holders(著作権者)

著作権を保持している組織・個人の一覧:

pathholderstartend
flask/LICENSE.txtPallets11
flask/tests/test_cli.pyCERN22

Flaskの場合、主な著作権者はPalletsですが、一部のファイル(test_cli.py)にはCERNの著作権も含まれていることが分かります。

4. Package Information(パッケージ情報)

検出されたパッケージマニフェスト:

pathtypepackagingprimary_language
flask/pyproject.tomlpypiPython

5. License References(ライセンス参照)

検出されたライセンスの詳細情報:

keyshort_namecategoryownerspdx_license_key
bsd-newBSD-3-ClausePermissiveRegents of the University of CaliforniaBSD-3-Clause

各ライセンスのカテゴリ(Permissive、Copyleftなど)や、SPDX標準のライセンスキーが確認できます。

HTMLレポートの特徴:

  • シンプルで見やすい:テーブル形式で情報が整理されている
  • リンク機能:ライセンス名をクリックすると、詳細情報にジャンプできる
  • 色分け:交互の行が色分けされ、ホバーするとハイライトされる
  • 印刷・保存が容易:標準的なHTML形式なので、印刷やPDF保存が簡単

JSON形式での出力

プログラムで処理する場合は、JSON形式が便利です:

scancode -clpieu --json-pp flask_scan.json flask/

JSON出力の主要な構造:

{
  "headers": [
    {
      "tool_name": "scancode-toolkit",
      "tool_version": "v32.4.1-29-g930e30e9e6",
      "options": {
        "input": ["flask/"],
        "--copyright": true,
        "--license": true,
        "--package": true
      },
      "start_timestamp": "2025-11-03T224718.394746",
      "end_timestamp": "2025-11-03T224736.017246",
      "duration": 17.622557878494263,
      "extra_data": {
        "spdx_license_list_version": "3.27",
        "files_count": 231
      }
    }
  ],
  "packages": [
    {
      "type": "pypi",
      "name": "Flask",
      "version": "3.2.0.dev",
      "description": "A simple framework for building complex web applications.",
      "declared_license_expression": "bsd-new",
      "declared_license_expression_spdx": "BSD-3-Clause",
      "purl": "pkg:pypi/flask@3.2.0.dev",
      "parties": [
        {
          "type": "person",
          "role": "maintainer",
          "name": "Pallets",
          "email": "contact@palletsprojects.com"
        }
      ]
    }
  ],
  "dependencies": [
    {
      "purl": "pkg:pypi/blinker",
      "extracted_requirement": ">=1.9.0",
      "scope": "install",
      "is_runtime": true,
      "is_optional": false
    },
    {
      "purl": "pkg:pypi/werkzeug",
      "extracted_requirement": ">=3.1.0",
      "scope": "install",
      "is_runtime": true,
      "is_optional": false
    }
  ],
  "license_detections": [
    {
      "identifier": "bsd_new-27f0ced9-dc7b-0fe1-9c69-3273179866a7",
      "license_expression": "bsd-new",
      "license_expression_spdx": "BSD-3-Clause",
      "detection_count": 3,
      "reference_matches": [
        {
          "license_expression": "bsd-new",
          "from_file": "flask/LICENSE.txt",
          "start_line": 3,
          "end_line": 28,
          "matcher": "2-aho",
          "score": 100.0,
          "matched_length": 216,
          "match_coverage": 100.0,
          "rule_identifier": "bsd-new_105.RULE"
        }
      ]
    }
  ],
  "files": [
    {
      "path": "flask/LICENSE.txt",
      "type": "file",
      "size": 1475,
      "detected_license_expression": "bsd-new",
      "detected_license_expression_spdx": "BSD-3-Clause",
      "percentage_of_license_text": 98.63,
      "copyrights": [
        {
          "copyright": "Copyright 2010 Pallets",
          "start_line": 1,
          "end_line": 1
        }
      ],
      "holders": [
        {
          "holder": "Pallets",
          "start_line": 1,
          "end_line": 1
        }
      ]
    }
  ]
}

JSON形式は、スクリプトでの自動処理や他のツールとの連携に適しています。

JSON出力の主要セクション

1. headers: スキャン実行情報

  • ツールバージョン、実行オプション、タイムスタンプ
  • スキャン時間(duration)やファイル数(files_count
  • SPDX License Listバージョン(この例では3.27)

2. packages: 検出されたパッケージ情報

  • パッケージ名、バージョン、説明
  • Package URL(PURL)による一意識別子
  • 宣言されたライセンス情報
  • メンテナ情報(名前、メールアドレス)

3. dependencies: 依存関係の詳細

  • 各依存パッケージのPURL
  • バージョン要件(extracted_requirement
  • スコープ(install、async、dotenvなど)
  • ランタイム依存かどうか(is_runtime
  • オプショナルかどうか(is_optional

4. license_detections: ライセンス検出の詳細

  • 一意の識別子(identifier
  • ライセンス式(通常形式とSPDX形式)
  • 検出回数(detection_count
  • マッチング情報(検出されたファイル、行番号、スコア)

5. files: 各ファイルの詳細情報

  • ファイルパス、タイプ、サイズ
  • 検出されたライセンス
  • 著作権情報(copyrights)と著作権者(holders
  • ライセンステキストの割合(percentage_of_license_text

出力形式の使い分け

scancode-toolkitは様々な出力形式をサポートしていますが、用途に応じて使い分けることが重要です:

HTML形式(推奨:人間が確認する場合)

  • メリット: 視覚的に分かりやすい、技術知識不要、グラフやツリー表示
  • 用途: 初回確認、経営層・法務部門への報告、プロジェクト概要の把握
  • コマンド--html output.html

JSON形式(推奨:プログラムで処理する場合)

  • メリット: 完全な情報、プログラムでの処理が容易、公式推奨フォーマット
  • 用途: 自動化スクリプト、他ツールとの連携、詳細分析
  • コマンド--json-pp output.json-ppは整形オプション)

その他の形式

  • SPDX/CycloneDX: SBOM(Software Bill of Materials)生成に使用
  • YAML: JSONと同様だが、人間が読みやすい形式
  • CSV: スプレッドシートでの確認(※現在非推奨、将来的に新形式に置き換わる予定)

詳しい出力オプションについては、公式ドキュメントをご確認ください。

開発者向け:よくある疑問と実践的な使い方

Q1: 依存関係のライセンスも自動的に検出できる?

A: はい、できます!

scancode-toolkitは、package.json、requirements.txt、pom.xml、Gemfile等のマニフェストファイルを解析し、依存関係のメタデータを抽出します。

# パッケージ情報を含めてスキャン
scancode -clp --html report.html ./my-project/

# JSON形式で依存関係の詳細を確認
scancode -clp --json-pp report.json ./my-project/

JSON出力のdependenciesセクションには、各パッケージの詳細な依存情報が含まれます:

{
  "dependencies": [
    {
      "purl": "pkg:pypi/blinker",
      "extracted_requirement": ">=1.9.0",
      "scope": "install",
      "is_runtime": true,
      "is_optional": false,
      "is_pinned": false,
      "is_direct": true
    },
    {
      "purl": "pkg:pypi/asgiref",
      "extracted_requirement": ">=3.2",
      "scope": "async",
      "is_runtime": true,
      "is_optional": true
    }
  ]
}

各依存関係には以下の情報が含まれます:

  • purl: Package URL(標準化された識別子)
  • extracted_requirement: バージョン要件(>=1.9.0など)
  • scope: 依存のスコープ(install、async、dotenvなど)
  • is_runtime: ランタイムに必要かどうか
  • is_optional: オプショナル依存かどうか
  • is_direct: 直接依存(vs 推移的依存)かどうか

Q2: node_modulesやvendorディレクトリもスキャンすべき?

A: 通常は除外すべきです

これらのディレクトリには、依存関係としてインストールされたパッケージが含まれています。これらは:

  • スキャン時間が非常に長くなる(数千〜数万ファイル)
  • パッケージマネージャーで管理されている
  • マニフェストファイル(package.json等)から情報を得られる

推奨アプローチ

# 依存関係ディレクトリを除外してスキャン
scancode --ignore "*/node_modules/*" \
  --ignore "*/vendor/*" \
  --ignore "*/.venv/*" \
  --ignore "*/venv/*" \
  -clpieu --html report.html ./my-project/

依存関係を含めて完全にスキャンしたい場合は、専用のツールや別途スキャンすることをお勧めします。

Q3: バイナリファイル(.jar、.dll等)のライセンスも確認できる?

A: はい、できます!

scancode-toolkitはバイナリファイルやコンパイル済みライブラリからもライセンス情報を検出できます。これは、ソースコードが入手できない商用ライブラリやレガシーコンポーネントを扱う際に特に有用です。

# バイナリファイルを含むディレクトリをスキャン
scancode -clpieu --html binary_report.html ./lib/

埋め込まれたライセンステキストやメタデータから情報を抽出します。

Q4: テストコードやドキュメントのライセンスも気にすべき?

A: プロダクトに含めるかどうかで判断

  • 本番環境に含まれる: スキャン必須
  • 開発環境のみ: リスクは低いが、組織のポリシー次第
  • ドキュメント: 通常は除外して問題ない
# テストやドキュメントを除外
scancode --ignore "*/tests/*" \
  --ignore "*/test/*" \
  --ignore "*/docs/*" \
  --ignore "*/__tests__/*" \
  -clpieu --html report.html ./my-project/

Q5: スキャンに時間がかかりすぎる場合は?

A: 以下の最適化テクニックを試してください

# 1. 並列処理数を増やす(CPUコア数に応じて調整)
scancode --processes 8 -clpieu --html report.html ./project/

# 2. 不要なディレクトリを除外
scancode --ignore "*/node_modules/*" \
  --ignore "*/.git/*" \
  --ignore "*/build/*" \
  --ignore "*/dist/*" \
  -clpieu --html report.html ./project/

# 3. 特定の検出機能だけを使用
scancode -l --html report.html ./project/  # ライセンスのみ

除外すべき一般的なディレクトリ

  • node_modules/vendor/: パッケージマネージャーの依存関係
  • .git/.svn/: バージョン管理システム
  • build/dist/target/: ビルド成果物
  • __pycache__/*.pyc: キャッシュファイル
  • .venv/venv/: Python仮想環境
  • coverage/.pytest_cache/: テスト関連

実践的な活用シーン

シーン1: 新規ライブラリの評価

新しく依存関係を追加する前に、そのライブラリのライセンスを確認:

# ダウンロードしたライブラリをスキャン
scancode -clpieu --html lib_report.html ./downloaded-library/

ブラウザでHTMLレポートを開き、ライセンスが自社のポリシーに適合するか確認できます。

シーン2: プロジェクト全体のライセンス監査

既存プロジェクトのライセンス状況を把握:

# プロジェクト全体をスキャン(最適化済み)
scancode --processes 4 \
  --ignore "*/node_modules/*" \
  --ignore "*/vendor/*" \
  --ignore "*/.git/*" \
  -clpieu --html project_audit.html ./my-project/

HTMLレポートで、意図しないライセンスが混入していないか確認できます。

シーン3: レガシーコンポーネントの調査

ソースコードが不明なバイナリファイルやJARファイルの調査:

# バイナリを含むディレクトリをスキャン
scancode -clpieu --html legacy_libs.html ./legacy-components/

埋め込まれたライセンス情報から、使用可能かどうかを判断できます。

シーン4: リリース前の最終確認

製品リリース前に、配布物に含まれるすべてのコンポーネントのライセンスを確認:

# 配布用ディレクトリをスキャン
scancode -clpieu --html release_audit.html ./dist/

# SBOM(ソフトウェア部品表)も生成
scancode -clpieu --spdx-rdf release_sbom.spdx ./dist/

注意点とベストプラクティス

検出精度について

scancode-toolkitは業界トップクラスの精度を誇り、「最も正確なライセンス検出エンジン」として知られています。ただし、以下のケースでは人間による確認を推奨します:

注意が必要なケース

  • コメントアウトされた古いライセンステキスト
  • サンプルコードとして引用されたライセンス
  • ライセンスに言及しているだけのドキュメント
  • 独自に改変されたライセンステキスト

これらは実際のライセンスとして検出される可能性があるため、score値(信頼度)を確認し、低いスコア(90%未満)の検出結果は手動確認することをお勧めします。

スキャン時間の最適化

大規模なプロジェクトでは、スキャンに時間がかかる場合があります:

# 並列処理数を指定(CPUコア数に応じて調整)
scancode --processes 4 -clpieu --html output.html /path/to/project

# 不要なディレクトリを除外
scancode --ignore "*/node_modules/*" --ignore "*/vendor/*" \
  --ignore "*/.git/*" --ignore "*/build/*" \
  -clpieu --html output.html /path/to/project

除外すべき一般的なディレクトリ

  • node_modules/vendor/: 依存関係(別途管理すべき)
  • .git/.svn/: バージョン管理システム
  • build/dist/: ビルド成果物
  • __pycache__/*.pyc: キャッシュファイル

アーカイブファイルの取り扱い

デフォルトでは、scancode-toolkitはtar、zip等のアーカイブファイルを展開しません:

# アーカイブを展開
extractcode archive.tar.gz -o extracted/

# 展開したファイルをスキャン
scancode -clpieu --html output.html extracted/

定期的な実行

ライセンス管理は継続的なプロセスです。以下のタイミングでスキャンを実行することを推奨します:

  • 新規依存関係の追加時: ライブラリを追加する前に確認
  • リリース前: 必ず実行してライセンス状況を確認
  • 定期監査: 四半期ごとや半期ごとに実施

エコシステムツール

scancode-toolkitには、補完的なツールも用意されています:

  • ScanCode.io: サーバーサイドでスキャンを自動化するWebアプリケーション
  • ScanCode Workbench: デスクトップベースのスキャン結果可視化ツール(JSON形式を読み込み)
  • ScanCode LicenseDB: 2,100以上のライセンス定義を持つ公開データベース

まとめ

scancode-toolkitは、OSSライセンス管理の強力な味方です。特にHTML形式での出力は、技術者だけでなく経営層や法務担当者にも分かりやすく、プロジェクトのライセンス状況を一目で把握できます。

本記事で紹介したFlaskのスキャン例のように、わずか約18秒で231ファイルのライセンスと著作権情報を完全に把握でき、視覚的なHTMLレポートで確認できます。

高精度な自動ライセンス検出により、コンプライアンスリスクを大幅に軽減できます。複数のOSSライブラリを使用する現代的な開発において、このようなツールの活用は必須と言えるでしょう。

Apache 2.0ライセンスの下で完全にオープンソースとして公開されており、誰でも無料で利用でき、コードを検証し、貢献することができます。

ライセンス管理は面倒に感じるかもしれませんが、適切なツールを使うことで、負担を最小限に抑えながら法的リスクを回避できます。まだscancode-toolkitを使ったことがない方は、ぜひ一度試してみてください。


より詳しい情報は、scancode-toolkitの公式ドキュメントGitHubリポジトリをご覧ください。