ジェムファイル開発者のためのガイドライン

Gemfile に新しいエントリを追加したり、既存の依存関係をアップグレードしたりする際には、以下のルールに注意してください。

Bundler チェックサムの検証

GitLab 15.5以降では、インストール前にgemのチェックサムがチェックされます。この検証はまだ実験的なものなので、CIに対してのみアクティビティがあります。

ダウンロードしたgemのチェックサムがGemfile.checksum のチェックサムレコードと一致しない場合、セキュリティ上の問題がある可能性があるためBundlerはgemのインストールを続行できないというエラーが表示されます。

このエラーは、Gemfile.checksumを更新せずに更新したり、新しいgemを追加した場合にも表示されます。このエラーを修正するには、Gemfile.checksumを更新します。

BUNDLER_CHECKSUM_VERIFICATION_OPT_IN 環境変数を設定することで、この検証を内部でオプトインできます:

export BUNDLER_CHECKSUM_VERIFICATION_OPT_IN=1
bundle install

この環境変数をfalse に設定すると、この検証を無効にすることもできます:

export BUNDLER_CHECKSUM_VERIFICATION_OPT_IN=false
bundle install

チェックサムファイルの更新

新しいジェムや更新されたジェムに対して行う必要があります。

  1. Gemfile.lock を更新する場合は、Gemfile.checksum も更新してください:

    bundle exec bundler-checksum init
    
  2. Gemfile.checksumの変更を確認し、コミットしてください。

Git リポジトリから取得した gems がありません。

Gitリポジトリから取得したgemは使用できません。すべてのgemはRubyGemsインデックスで利用可能でなければなりません。外部のビルド依存性とビルド時間を最小限に抑えたいからです。これはRuboCopルールCop/GemFetcherによって強制されます。

新しい依存関係をレビューして品質を確認します。

GitLab の品質基準をクリアできないようなサードパーティの依存関係を GitLab に追加すべきではありません。つまり、新しい依存関係は最低限以下の基準を満たす必要があります:

  • 開発者コミュニティがアクティブであること。緊急時に変更リクエストをマージできるよう、最低でもメンテナーが活動中であること。
  • GitLabの可用性やパフォーマンスに影響を与えると思われるイシューはオープンになっていません。
  • プロジェクトは何らかのテスト自動化を用いてテストされています。GitLabが現在使用しているRubyのバージョンを使ってテストスイートをパスしていること。
  • サポートされているすべてのプラットフォームの CI ビルドが、新しい依存関係を使用して成功する必要があります。詳細については、テスト用のパッケージをビルドする方法を参照してください。
  • プロジェクトが C 拡張モジュールを使用している場合は、C または MRI ドメインの専門家に追加レビューを依頼することを検討してください。C 拡張は GitLab の安定性とパフォーマンスに大きな影響を与える可能性があります。

ドメインエキスパートの承認者が必要なジェム

以下の宝石の変更には、ドメインエキスパートのレビューとグループのバックエンドチームメンバーによる承認が必要です。

この表に記載されていないgemについては、変更をレビューするドメインエキスパートを見つけることを推奨しますが、必須ではありません。

ジェムの承認者が必要です。
doorkeeper管理:認証と承認
doorkeeper-openid_connect管理:認証と承認

Appsecレビューのリクエスト

Gemfile に新しい gem を追加したり、Gemfile.lock のバージョンを変更したりする場合は、セキュリティレビューをリクエストすることを強くお勧めします。新しいgemはGitLabにとって余分なセキュリティリスクを追加するものであり、本番環境に出荷する前にこのリスクを評価することが重要です。技術的には、新しいgemを追加してメインのgitlab プロジェクトのブランチにプッシュするだけでも、GitLab.comの認証情報を使ってCIで実行されるため、セキュリティリスクになります。そのため、インストールする前に、このgemが正当なものかどうかを早い段階で評価する必要があります。

レビュアーは、コミュニティ貢献のレビューに関する私たちの推奨事項にも注意し、GemfileGemfile.lock への変更を含むコミュニティ貢献のパイプラインを実行する前に注意すべきです。

ライセンスの遵守

ライセンスコンプライアンスを確保するためのライセンスガイドラインを参照してください。

GitLabが作成したgem

他のアプリケーションで使いたいから、あるいはより広いコミュニティのためになると思うからです。gemにコードを抽出するということは、そのgemが私たちのアプリケーションコードに隠れた依存性を含んでいないことを確認できるということでもあります。

Gemsの開発者向けガイドラインについてはこちらをご覧ください。

Railsのアップグレード

Rails gemとその依存関係をアップグレードする場合は、以下も更新する必要があります:

  • vendoredattr_encrypted gemspec](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/gems/attr_encrypted/attr_encrypted.gemspec)の[activerecord_version も更新してください。
  • qa ディレクトリのGemfile.

また、Railsの現在のバージョンに従うnpmパッケージも更新する必要があります:

  • @rails/ujs
    • 更新後にyarn patch-package @rails/ujs を実行して、ローカルのパッチファイルのバージョンが一致していることを確認してください。
  • @rails/actioncable

脆弱性による依存関係のアップグレード

脆弱性を理由に依存関係をアップグレードする場合、誤ってダウングレードしないように、脆弱性が修正されたgemの最小バージョンをGemfileに固定する必要があります。

例えば、license_finder というgemがthor 依存 thor関係にあり、1.1.1 という脆弱性修正を含むバージョンまで脆弱性が見つかったとします。

Gemfile では、thor を必ず1.1.1 に pin してください。直接の依存関係であるlicense_finder には、すでにバージョンが指定されているはずです。

gem 'license_finder', '~> 6.0'
# Dependency of license_finder with fix for vulnerability
# _link to initial security issue that will become public in time_
gem 'thor', '>= 1.1.1'

ここでは、~> (悲観演算子) ではなく、>= (greater than or equal to) という演算子を使用しています。これにより、license_finder やその他の gem を、thor 1.2 に依存するバージョンにアップグレードすることができます。

同様に、license_finder の脆弱性が 6.0.1 で修正された場合、次のように追加します:

gem 'license_finder', '~> 6.0', '>= 6.0.1'

こうすることで、license_finder 以外の依存関係は、6.0.2 のような新しいバージョンのthor に依存することはできますが、脆弱性のあるバージョン6.0.0 には依存できなくなります。

このようなダウングレードは、thor に依存していながら、そのバージョンが脆弱性に固定されている新しい依存関係を導入した場合に起こり得ます。このような変更は、Gemfile.lock で見逃されがちです。 バージョンを固定すると、解決しなければならない競合が発生します。

間接的な依存関係のアップグレードを避けるために、bundle update --conservative.

依存関係の更新を含むマージリクエストを提出する場合、マージリクエストの説明に2つのバージョン間の Gem diff へのリンクを含めてください。このリンクはrubygems.org にあります。diffend.io にあるバージョン間の比較を生成するには、変更のレビュアーを選択してください。たとえば、これはthor 1.0.0 vs 1.0.1 の gem diff です。GitLabや他のコードホスティングプラットフォームからのリンクは、実際に公開されているコードを反映していない可能性があるため、RubyGemsから直接生成されたリンクを使用してください。