プログラマのための IT 教科書

ライセンスと依存ライブラリ

この部の 6 / 9 章 ・ 全体で 18 / 76 章 ・ 読了目安 35 分

この章を読むとできるようになること
  • AGPL / GPL を自己判断で導入してはいけない理由を説明できる
  • 依存を追加すべきかを基準を持って判断できる
  • ロックファイルの差分から異常に気づける

あなたが今日書いたコードのうち、自分で書いた行は数パーセントです。 残りは node_modules と go.sum の中にあります。

そして依存ライブラリは、技術的な負債であると同時に、法的なリスクでもあります。

・ライセンス違反 → 会社が訴えられる。最悪、製品のソースコード公開を求められる
・脆弱性         → 攻撃される
・乗っ取り       → 気づかないうちに悪意あるコードを取り込む

バグは直せますが、ライセンス違反は「直しました」で済まないことがあります。 この章は、多くの入門書が飛ばすところです。

ライセンスが無いものは使えない

まず前提として、世界中のコードには自動的に著作権があります。

ライセンスとは、著作権者が「この条件なら使っていい」と示した許諾です。

つまり、

GitHub に公開されている = 自由に使ってよい ← 誤り
LICENSE ファイルが無いリポジトリ            → 原則、使う権利がない

公開されていることと、使ってよいことは別です。 LICENSE が無いコードをコピーしてくるのは、実務では避けてください。

主要なライセンス

実務で出会うものは、だいたい次のどれかです。

ライセンス商用利用改変表示義務自社コードの公開義務
MIT○○ありなし
BSD (2/3条項)○○ありなし
Apache-2.0○○あり(変更点の明示も)なし
MPL-2.0○○あり改変したファイルのみ
LGPL○○あり改変した部分(リンク形態で条件が変わる)
GPL○○あり派生物全体(配布する場合)
AGPL○○あり派生物全体(ネットワーク越しの提供でも)

コピーレフトの強さ

「自分たちのコードも公開しなければならなくなるか」の強さで並びます。

なし          MIT / BSD / Apache-2.0
  ↓
ファイル単位   MPL-2.0
  ↓
リンク条件つき LGPL
  ↓
派生物全体     GPL          ← 配布した場合
  ↓
SaaS も対象   AGPL          ← 配布しなくても、サービスとして提供したら対象
AGPL が実務で最も注意が要る

GPL の公開義務は「ソフトウェアを配布した場合」に発生します。 自社サーバーで動かして Web サービスとして提供するだけなら、配布に当たりません。

AGPL は、この抜け道を塞いだライセンスです。 ネットワーク越しにサービスを提供する場合も、 利用者にソースコードを提供する義務が生じ得ます。

つまり、Web サービスのバックエンドに AGPL のライブラリを組み込むと、 自社のコードを公開しなければならなくなる可能性があります。

有名なミドルウェアやライブラリにも AGPL のものがあります。 依存を足す前に、必ずライセンスを確認してください。

MIT でも「何もしなくてよい」わけではない

MIT は最も緩いライセンスの1つですが、表示義務があります。

著作権表示とライセンス文を、ソフトウェアの複製物に含めること

つまり、アプリを配布・提供する際には 使っているライブラリのライセンス一覧を同梱する必要があります。

  • モバイルアプリ: 「ライセンス情報」画面を用意する
  • Web サービス: /licenses のようなページを置く
  • 配布物: THIRD_PARTY_LICENSES.txt を同梱する

「MIT だから自由」と考えて何も同梱していないのは、よくある違反状態です。 自動生成するツールがあるので、CI で作ってしまうのが確実です。

go-licenses report ./...        # Go
npx license-checker --summary   # Node

Apache-2.0 の特許条項

Apache-2.0 には特許の許諾が明示されています。 また、貢献者が特許訴訟を起こすと、その人の権利が終了する条項もあります。

企業が Apache-2.0 を好むのは、この明確さのためです。 MIT には特許についての記述がありません(そのぶん解釈の余地が残ります)。

依存の構造を把握する

直接依存    自分で package.json / go.mod に書いたもの
推移的依存  そのライブラリが依存しているもの(自分では選んでいない)

問題の大半は、推移的依存で起きます。 自分が入れた覚えのないパッケージが、数百個入っているのが普通です。

# なぜこの依存が入っているのかを追う
go mod why github.com/some/pkg
pnpm why some-package
npm ls some-package
ロックファイルは必ずコミットする

go.sum pnpm-lock.yaml package-lock.json は必ず git に入れます。

無いと、

  • 人によって入るバージョンが変わり、「自分の環境だけ動かない」が起きる(開発環境を作る)
  • 中身がすり替わっても気づけない(go.sum はハッシュを保持している)

ロックファイルのコンフリクトは、手で直さず再生成してください。

脆弱性

依存ライブラリに脆弱性が見つかるのは、日常です。

govulncheck ./...          # Go(実際に到達するコードだけ報告してくれる)
pnpm audit                 # Node
用語意味
CVE個々の脆弱性に振られた識別番号(例: CVE-2021-44228)
CVSS深刻度のスコア(0.0〜10.0)。9.0 以上は Critical
SBOM使っているソフトウェア部品の一覧。近年は納品時に求められることも
スコアだけで慌てない

CVSS 9.8 でも、その機能を使っていなければ影響しないことがあります。 逆にスコアが低くても、自社の使い方では致命的なこともあります。

見るべき順番はこうです。

  1. 自分たちがその機能を使っているか(govulncheck はここまで見てくれる)
  2. インターネットに公開されている経路から到達するか
  3. 修正版があるか、回避策があるか

判断に迷ったら、セキュリティ担当に上げるのが正解です。 新人が1人で「影響なし」と判断しないでください。

サプライチェーン攻撃

依存を通じて悪意あるコードを送り込む攻撃が、近年増えています。

手口内容
タイポスクワッティングよく似た名前のパッケージを公開する(reqeusts, lodahs)
アカウント乗っ取り正規パッケージのメンテナが乗っ取られ、悪意ある版が公開される
依存混同社内用パッケージと同名のものを公開レジストリに置き、そちらを取得させる
postinstall スクリプトインストール時に任意のコードが実行される

対策は地味なものばかりですが、効きます。

□ パッケージ名を目視で確認してから入れる(コピペ元を信用しない)
□ ロックファイルを使い、CI では pnpm install --frozen-lockfile / go mod verify
□ 依存の自動更新は、まとめず小さく、CI を通してからマージする
□ 見慣れないパッケージが増えていたら、PR で必ず質問する
新人が最も貢献できるポイント

PR の差分にロックファイルの巨大な変更があったら、質問してください。

「この依存は何のために増えましたか」と聞くだけで、 意図しない依存の混入を止められることがあります。

レビューでロックファイルを開く人はほとんどいません。 だからこそ、そこを見る人が価値を持ちます。

依存を足すかどうかの判断

ライブラリを入れるのはタダではありません。

入れると得られるもの: 実装時間の節約、実績のある実装
入れると背負うもの  : ライセンス、脆弱性対応、更新追従、ビルド時間、学習コスト

判断のチェックリストです。

□ 自分で書くと何行になるか(10行で済むなら書く)
□ 最終コミットはいつか(2年動いていないなら要注意)
□ メンテナは何人か(1人だけなら、その人が離れたら終わる)
□ Issue と PR が放置されていないか
□ 依存の依存はいくつ増えるか
□ ライセンスは何か
□ 同じ用途のものが既にプロジェクトに入っていないか
1行のライブラリを入れない

2016 年、11行の JavaScript ライブラリが公開レジストリから削除され、 世界中のビルドが壊れるという事件がありました(left-pad 事件)。

数行で書けるものにライブラリを使うと、 その数行のために、他人のリリース都合とセキュリティ対応を背負うことになります。

AI が生成したコードのライセンス

AI と一緒に開発するでも扱いますが、ここでも触れておきます。

生成されたコードが既存の OSS とほぼ同一になることがあります。 その OSS が GPL だった場合、由来を知らないまま取り込むリスクがあります。

□ 生成されたコードが、特定のライブラリの実装と酷似していないか
□ 会社が定めた AI ツールの利用ルールに従っているか
□ 大きな塊をそのまま貼り付けていないか

「AI が書いたので分かりません」は、法務上の説明になりません。

迷ったら聞く

ライセンスの判断は、エンジニアが1人で決めるものではありません。

□ AGPL / GPL のライブラリを入れたい     → 必ず上長・法務に相談
□ OSS に会社のコードを出したい          → 会社の手続きを確認
□ 顧客に納品する製品に依存を追加する    → ライセンス条件を確認
□ ライセンスが書かれていないコードを使いたい → 使わない
OSS へのコントリビュート

業務中に見つけたバグを OSS に報告・修正するのは、良いことです。 ただし、会社ごとに手続きが決まっていることがあります。

  • 業務時間中に書いたコードの権利は、通常は会社にあります
  • CLA(Contributor License Agreement)への署名が必要なプロジェクトもあります
  • 会社名で出すか、個人で出すかの方針がある場合もあります

やる前に一度確認してください。やってはいけないという意味ではありません。

バックエンドで使いたいライブラリが AGPL-3.0 でした。どうしますか。

実務の落とし穴まとめ

  1. LICENSE の無いコードをコピー — 使う権利が無い
  2. AGPL / GPL を自己判断で導入 — 自社コードの公開義務が生じ得る
  3. MIT だから何もしなくてよいと思う — 著作権表示とライセンス文の同梱が必要
  4. ロックファイルをコミットしない — 再現性が失われ、すり替えにも気づけない
  5. CVSS スコアだけで判断 — その機能を使っているかを先に見る
  6. ロックファイルの差分をレビューしない — 依存の混入に気づけない
  7. 数行で書けるものにライブラリを使う — 他人のリリース都合を背負う
  8. メンテされていないライブラリを選ぶ — 脆弱性が出ても直らない
  9. AI 生成コードの由来を確認しない — 説明できない権利関係を抱える

まとめ

  • ライセンスが無い = 使えない。公開されていることと使ってよいことは別
  • AGPL はネットワーク提供でも公開義務が生じ得る。GPL は配布時。 どちらも自己判断で入れない
  • MIT / BSD / Apache-2.0 でも表示義務がある。ライセンス一覧は自動生成して同梱する
  • 問題の多くは推移的依存で起きる。go mod why / pnpm why で追う
  • ロックファイルは必ずコミットする
  • 脆弱性は CVE / CVSS で管理されるが、自分たちが使っているかを先に見る
  • サプライチェーン攻撃に対しては、ロックファイル・小さな更新・ ロックファイルの差分を読むことが効く
  • 依存を足すのはタダではない。メンテ状況・依存の数・ライセンスを見て決める
  • 判断に迷ったら法務・上長へ。 これは相談すべき事柄であって、面倒ではない

公式ドキュメント

迷ったら一次情報に戻ってください。

対象リンク
choosealicense.comhttps://choosealicense.com/
SPDX ライセンス一覧https://spdx.org/licenses/
Open Source Initiativehttps://opensource.org/licenses
IPA: Japan Open Source Hubhttps://www.ipa.go.jp/digital/kaihatsu/oss/index.html
GitHub Dependabot(日本語)https://docs.github.com/ja/code-security/dependabot

章末問題

PR のレビューで、コード差分は10行なのに pnpm-lock.yaml が2000行変更されていました。どうしますか。

配列を特定の文字数まで空白で埋める処理が必要です。npm に専用パッケージがあります。どうしますか。

次の章では、こうした日々の判断をチームでどう回すか—— スクラム、見積もり、そして詰まった時にいつ声を上げるかを扱います。

読み終わったら記録しておくと、目次で進み具合が分かります。