正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。
ドキュメントに関する現在のご利用体験についてお聞かせください。アンケートにご協力ください。

Webhook

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

Webhookは、リアルタイム通知によってGitLabを他のツールやシステムに接続します。GitLabで重要なイベントが発生すると、Webhookはその情報を外部アプリケーションに直接送信します。マージリクエスト、コードプッシュ、イシューの更新に反応して自動化ワークフローをビルドします。

Webhookを使用すると、変更発生時にチームが連携の取れた状態を維持できます。

  • GitLabイシューが変更されると、外部イシュートラッカーが自動的に更新されます。
  • チャットアプリケーションが、パイプラインの完了をチームメンバーに通知します。
  • コードがmainブランチに到達すると、カスタムスクリプトがアプリケーションをデプロイします。
  • モニタリングシステムが、組織全体での開発アクティビティを追跡します。

Webhookイベント

Webhookは、GitLabのさまざまなイベントによってトリガーできます。例:

  • リポジトリへのコードプッシュ。
  • イシューへのコメントの投稿。
  • マージリクエストの作成。

Webhookの制限

GitLab.comは、次のWebhookの制限を適用します。

  • プロジェクトまたはグループごとのWebhookの最大数。
  • 1分あたりのWebhook呼び出し数。
  • Webhookのタイムアウト期間。

GitLab Self-Managedでは、管理者がこれらの制限を変更できます。

プッシュイベントの制限

GitLabは、複数の変更を含むプッシュイベントに対するWebhookのトリガーを制限します:

  • デフォルトの制限: プッシュごとに3つのブランチまたはタグ。
  • 超過した場合の動作: プッシュイベント全体に対してWebhookはトリガーされません。
  • 適用対象: プロジェクトWebhookとシステムフックの両方。
  • 設定: GitLab Self-Managedの管理者は、アプリケーション設定APIを通じてpush_event_hooks_limit設定を変更できます。

複数のタグやブランチを同時に頻繁にプッシュする必要があり、Webhook通知が必要な場合は、GitLabの管理者に連絡してこの制限を増やしてもらってください。

グループWebhook

  • プラン: Premium、Ultimate

グループWebhookは、グループとそのサブグループ内のすべてのプロジェクトのイベントに関する通知を送信するカスタムHTTPコールバックです。

グループWebhookイベントの種類

次のイベントをリッスンするようにグループWebhookを設定できます。

  • グループおよびサブグループ内のプロジェクトで発生するすべてのイベント
  • グループメンバーイベント、プロジェクトイベント、サブグループイベントを含む、グループ固有のイベント

プロジェクトとグループの両方のWebhook

グループとそのグループ内のプロジェクトの両方で同一のWebhookを設定すると、そのプロジェクト内のイベントに対して両方のWebhookがトリガーされます。これにより、GitLab組織のさまざまなレベルで柔軟なイベント処理が可能になります。

Webhookを設定する

GitLabでWebhookを作成、設定して、プロジェクトのワークフローと統合します。これらの機能を使用して、特定の要件を満たすWebhookを設定します。

Webhookを作成する

新しいWebhookには、シークレットトークンの代わりに署名トークンを使用します。署名トークンは、ペイロードのHMAC-SHA256署名を計算するため、お使いのエンドポイントはリクエストの真正性と整合性の両方を検証することができます。シークレットトークンは、ヘッダーにプレーンテキスト値を提供するだけであり、保証は弱くなります。新しいWebhookにはシークレットトークンの使用は推奨されません。

プロジェクトまたはグループ内のイベントに関する通知を送信するWebhookを作成します。

前提条件:

  • プロジェクトWebhookの場合、プロジェクトのメンテナーまたはオーナーロールが必要です。
  • グループWebhookの場合、グループのオーナーロールを持っている必要があります。

Webhookを作成するには、次の手順に従います。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトまたはグループを見つけます。
  2. 左サイドバーで、設定 > Webhooksを選択します。
  3. 新しいWebhookを追加を選択します。
  4. URLに、WebhookエンドポイントのURLを入力します。特殊文字にはパーセントエンコードを使用します。
  5. (オプション)Webhookの名前と説明を入力します。
  6. (オプション)リクエスト認証を設定します。より強力なセキュリティのために署名トークンを使用します:
    • 署名トークン: 署名トークンを生成を選択します。トークンは一度しか表示されないため、今すぐコピーして保存してください。お使いのWebhookエンドポイントは、このトークンを使用してHMAC-SHA256署名を検証できます。
    • シークレットトークン: シークレットトークンフィールドにトークンを入力します。このトークンはX-Gitlab-Token HTTPヘッダーでプレーンテキストとして送信され、署名トークンよりもセキュリティ保証が弱くなります。新しいWebhookには、代わりに署名トークンを使用します。
  7. トリガーセクションで、Webhookをトリガーするイベントを選択します。
  8. (オプション)SSL検証を無効にするには、SSLの検証を有効にするチェックボックスをオフにします。
  9. Webhookを追加を選択します。

署名トークン

署名トークンを使用して、WebhookのペイロードがGitLabから送信され、改ざんされていないことを検証することができます。シークレットトークンとは異なり、署名トークンはペイロードのHMAC-SHA256署名を計算するために使用されます。これは、受信者が受信したペイロードの真正性と整合性の両方を個別に検証することができることを意味します。

GitLabのWebhook配信は、Standard Webhooksの仕様に従っています。すべてのWebhookリクエストには、webhook-idとwebhook-timestampのヘッダーが含まれます。署名トークンが設定されている場合、GitLabはHMAC-SHA256署名とともにwebhook-signatureヘッダーも含まれます。各署名はv1,{base64_signature}の形式です。ヘッダーには、スペースで区切られた複数の署名が含まれる場合があります。GitLabは現在1つの署名を送信しますが、これは将来変更される可能性があります。署名は{message_id}.{timestamp}.{body}の文字列に基づいて計算されます。ここで:

  • {message_id}はwebhook-idヘッダーの値です。
  • {timestamp}はwebhook-timestampヘッダーの値です。
  • {body}はraw JSONリクエストボディです。

署名を検証する

Webhookエンドポイントで署名を検証するには:

  1. webhook-id、webhook-timestamp、およびwebhook-signatureヘッダーの値を取得する。
  2. webhook-signatureの値をスペースで分割して署名リストを取得します。
  3. メッセージ文字列"{message_id}.{timestamp}.{body}"を構築します。
  4. 署名トークンをデコードします: whsec_プレフィックスを削除し、残りをbase64デコードします。
  5. デコードされたキーを使用してHMAC-SHA256ダイジェストを計算します。
  6. ダイジェストをbase64としてエンコードし、v1,をプレフィックスとして付加します。
  7. 計算された署名が署名リスト内のいずれかのエントリと一致するかどうかを確認します。タイミング攻撃を防ぐために定時間比較を使用します。

Rubyでの例:

ruby
require 'base64'
require 'openssl'

def valid_signature?(signing_token, message_id, timestamp, body, received_signatures)
  raw_key = Base64.strict_decode64(signing_token.delete_prefix('whsec_'))
  message = "#{message_id}.#{timestamp}.#{body}"
  digest = OpenSSL::HMAC.digest('sha256', raw_key, message)
  expected = "v1,#{Base64.strict_encode64(digest)}"