Webhook を管理する
GDPR 規制に従ってユーザーのプライバシーを向上させるため、Bitbucket やその他の Atlassian Cloud アプリでは個人データへのアクセスの管理方法を統一するためにアプリ API の更新を進めています。これらの API の変更は、Atlassian アプリで今後予定されている改善である、データの表示およびアクセスを許可するユーザーのより詳細な制御をサポートするために必要です。
The short summary is that username endpoints and username fields will stop being available on April 12, 2019, and we’re introducing some new data points that are available immediately to replace them. For more information, visit the API deprecation notice.
Webhook を使うことで、Bitbucket Cloud で特定のイベントが発生したときにセルフホスト型のサーバー (または外部サービス) にリクエストを送信するよう、Bitbucket Cloud を構成できます。webhook の構成要素は次のとおりです。
適用対象 - イベントを生成するリソース。現在、このリソースは Webhook を作成するリポジトリです。
1 つ以上のイベント - デフォルトのイベントはリポジトリ プッシュですが、Webhook をトリガーできるイベントを複数選択できます。
URL – 設定した条件に一致するイベントが発生した場合に、Bitbucket がイベント ペイロードを送信するエンドポイント。
Webhook を機能させるための作業として、Webhook の作成と Webhook のトリガーの 2 段階の手順があります。イベント用の Webhook を作成すると、イベントが発生するたびに、Bitbucket はイベントについてのペイロード リクエストを指定した URL に送信します。そのため、Webhook は通知システムのようなものだと考えることができます。
If you're having problems with a webhook, see Troubleshoot Webhooks.
Forge を使用して Bitbucket Cloud 用アプリを開発したい場合
Check out our Creating an app for Bitbucket Cloud for more details and help building your apps.
Webhook を使用するタイミング
Webhooks を使用して Bitbucket Cloud とアプリケーションを連携できます。次のような例があります:
ユーザーがリポジトリにコミットをプッシュするたびに CI サーバーにビルドを開始するよう通知する
ユーザーがコミットをプッシュしたり、プルリクエストを作成するたびに、アプリケーションで通知を表示する
Webhook のメリット
Webhook を使用しない場合、Bitbucket Cloud でのイベント発生を確認するには、API をポーリングする必要があります。ただし、API のポーリングは利便性が低く非効率な場合があり、エラーも発生しがちです。携帯電話での SMS メッセージの仕組みを考えてみてください。電話が通知を送信するため、5 分ごとにメッセージ アプリを確認して新着情報があるかどうかを確認する必要はありません。同様に、Webhook は通知のように機能するため、API で 1 分おきに同じアクティビティを確認する必要はありません。
Webhook を作成する
Bitbucket Cloud または API から Webhook を作成できます。次の手順を使用して、Bitbucket のリポジトリで Webhook を作成します。リポジトリの管理者のみがリポジトリで Webhook を作成できます。
リポジトリあたり最大 50 件の Webhook を作成できます。
Bitbucket で Webhook を追加したいリポジトリを開きます。
Select Repository settings on the left sidebar.
[設定] ページで、左側のサイドバーの [Webhook] を選択します。
Select the Add webhook button to create a webhook for the repository.
[新しい Webhook の追加] ページで、短い説明を含むタイトルを入力します。
アプリケーションまたはサーバーへの URL を入力します。
(Recommended) Enter the Secret so you can verify the incoming webhook payloads. For more details, see the Secure webhooks section.
(オプション) 保存後に Webhook をアクティブにしたくない場合は、[アクティブ] からチェックマークを外します。
(オプション) 自己署名証明書を使用しているために証明書の検証を無効化したい場合は、[証明書の検証をスキップ] を選択します。
注: 自己署名証明書は本質的に安全でないため、証明書の検証を無効化しないことをお勧めします。自己署名証明書の使用の詳細については、次のセクションをお読みください。
If necessary, update the Triggers field.
By default, the trigger for the webhook is a repository push, as demonstrated by the Repository push field. If you want additional or different actions to trigger the webhook, select Choose from a full list of triggers. You will see a list of all the event types that can trigger the webhook.After you entered all the necessary information for your webhook, select Save.
To create a webhook using the API, you need to know the format of the HTTP request that Bitbucket expects and the format of the HTTP response that Bitbucket returns to your server. Refer to the reference documentation for descriptions and examples of these requests and responses.
You may also need to know the Bitbucket Cloud IP addresses to allowlist.
自己署名証明書を使用する場合
Webhook を作成する際、Bitbucket は証明書の検証をスキップするオプションを提供します。このオプションでは、イベント ペイロード リクエストを Webhook URL に送信する際に、証明書の検証を無効化できます。このオプションは、自己署名の SSL 証明書を使用している HTTPS エンドポイントで Webhook を受信する場合に使用できます。ただし、自己署名証明書は本質的に安全でないため、以下の場合を除いては証明書の検証を無効化しないことをお勧めします。
公共の認証局が署名した有効な SSL 証明書をインストールできない。また、
セキュリティを考慮する必要がない Webhook である
HTTPS エンドポイントを使用すると、送信データは対称キーを使用して暗号化され、対称キー自体は SSL 証明書の公開キーを使用して暗号化されます。ただし、自己署名証明書を使用している場合、証明書は信頼できる証明局の署名を受けていないため、証明書を信頼できるものとみなすことができません。その結果、自己署名証明書を使用して HTTPS エンドポイント経由でデータを送信する場合、意図するサーバーと通信しているかどうかを把握することができません。つまり、証明書が検証されていない場合、不正な第三者がサーバーになりすまして MITM (介入者) 攻撃を実行できてしまうことになります。
可能であれば、証明書の検証を無効化しないことをお勧めします。初回のキー交換の間に双方の身元を確実に確認できる唯一の方法は、信頼できる証明局の SSL 証明書を取得しておくことです。これにより、Bitbucket から送信されたデータが、他の人物ではなく自分の証明書の公開キーを使用して正しく暗号化されることを確認できます。安価な SSL 証明書のオプションについては次をご覧ください。
Let's Encrypt, which offers free SSL certificates
Instant SSL by Comodo, which includes a free 90-day trial
Webhook を保護する
Webhook 配信について
ペイロードを受信するように設定されたセルフホスト型のサーバーは、指定のエンドポイントに送信されるすべての配信をリッスンします。セキュリティ上の理由から、Bitbucket Cloud からの配信のみを処理する必要があります。
セルフホスト型のサーバーで Bitbucket Cloud からの配信のみを処理するようにするには、次のことを行う必要があります。
Webhook のシークレット トークンを作成する。
トークンをセルフホスト型のサーバーに安全に保管する。
受信した Webhook ペイロードをトークンと照合して、Bitbucket Cloud からのものであることを検証します。
シークレット トークンの作成
シークレット トークンを使用して新しい Webhook を作成することも、既存の Webhook にシークレット トークンを追加することもできます。シークレット トークンを作成する場合は、エントロピーの高いランダムなテキスト文字列を選択する必要があります。"Generate secret (シークレットを生成)" ボタンを使用して、シークレットを自動生成することもできます。 シークレットは必ず安全な場所に記録してください。Webhook を保存すると、シークレットの閲覧も取得もできなくなります。
シークレット トークンの更新
Webhook を編集することで、既存の Webhook のシークレット トークンを更新できます。ただし、このシークレットを使用しているインテグレーションはすべて、更新する必要があることに注意してください。
シークレット トークンの安全な保存
シークレット トークンを作成したら、サーバーからアクセスできる安全な場所に保存する必要があります。トークンをアプリケーションにハードコードしたり、リポジトリにプッシュしたりしないでください。
Webhook 配信の検証
Bitbucket Cloud will use your secret token to create a HMAC signature that's sent to you with each payload. The hash signature will appear in each delivery as the value of the X-Hub-Signature header. The value of the header be formatted as method=signature as defined by WebSub. The method can be one of the hashes listed in WebSub. The signature will be the HMAC of the body using the hash specified in method. Right now, Bitbucket will send HMACs using sha256. This might change in the future.
In your code that handles webhook deliveries, you should calculate a HMAC of the body using your secret token and the hash specified in the method. Then, compare the HMAC that Bitbucket Cloud sent with the expected HMAC that you calculated, and ensure that they match. For examples showing how to validate the hashes in various programming languages, see the Examples section.
Webhook ペイロードを検証する際に留意すべき重要な点がいくつかあります。
Bitbucket Cloud は HMAC の 16 進ダイジェストを使用してハッシュを計算します。
HMAC は、Webhook のシークレット トークン、ペイロードの内容、および
methodに記載されているハッシュ アルゴリズムを使用して生成されます。ペイロードは HMAC 生成に 逐語的に 渡されることに注意してください。HMAC 署名を検証する場合、文字列として「生の」コード形式を使用する必要があります。そうしないと、署名が一致しません。HMAC を生成する前に本文に書式設定や美化を実行すると、異なる署名になります。
使用する言語とサーバーの実装で文字エンコーディングを指定する場合は、ペイロードを UTF-8 として処理してください。Webhook ペイロードには Unicode 文字を含めることができます。
プレーン テキストの
==演算子は絶対に使用しないでください。代わりに、secure_compareやcrypto.timingSafeEqualのような方法の使用を検討してください。これらの方法では、文字列の "定数時間" 比較を行うことで、通常の等価演算子に対する特定のタイミング攻撃や、JIT 最適化言語での標準ループを軽減するのに役立ちます。
Webhook ペイロード検証のテスト
次の secret、payload、および method の値を使用して、実装が正しいことを確認できます。
secret:It's a Secret to Everybodypayload:Hello World!method:sha256
実装が正しければ、生成される署名が次の署名値と一致します。
署名:
a4771c39fbe90f317c7824e83ddef3caae9cb3d976c214ace1f2937e133263c9X-Hub-Signature: sha256=a4771c39fbe90f317c7824e83ddef3caae9cb3d976c214ace1f2937e133263c9
例
任意のプログラミング言語を使用して、コードに HMAC 検証を実装できます。以下は、実装がいくつかのプログラミング言語でどのようになるかを示す例です。これらの例では、Bitbucket が sha256 ハッシュを使用して HMAC を送信していると想定していることに注意してください。Bitbucket は将来、HMAC に別のハッシュを使用するようになる可能性があります。その場合、これらのサンプル コードは正しく動作しなくなります。
Java の例
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
final String secret = "It's a Secret to Everybody";
final String payload = "Hello World!";
final String givenSignature = "sha256=a4771c39fbe90f317c7824e83ddef3caae9cb3d976c214ace1f2937e133263c9";
final SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
final Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
final byte[] digest = mac.doFinal(payload.getBytes(StandardCharsets.UTF_8));
final HexFormat hex = HexFormat.of();
final String calculatedSignature = "sha256=" + hex.formatHex(digest);
if (!MessageDigest.isEqual(calculatedSignature.getBytes(), givenSignature.getBytes())) {
System.out.println("Signatures do not match\nExpected signature:" +
calculatedSignature + "\nActual: signature: " + givenSignature);
} else {
System.out.println("Signatures match");
}
}
}Python の例
import hashlib
import hmac
secret = "It's a Secret to Everybody"
payload = "Hello World!"
given_signature = "sha256=a4771c39fbe90f317c7824e83ddef3caae9cb3d976c214ace1f2937e133263c9"
hash_object = hmac.new(
secret.encode("utf-8"),
msg=payload.encode("utf-8"),
digestmod=hashlib.sha256,
)
calculated_signature = "sha256=" + hash_object.hexdigest()
if not hmac.compare_digest(calculated_signature, given_signature):
print(
"Signatures do not match\nExpected signature:"
f" {calculated_signature}\nActual: signature: {given_signature}"
)
else:
print("Signatures match")Node.js例
const {
createHmac,
timingSafeEqual
} = require('node:crypto');
const secret = "It's a Secret to Everybody"
const payload = "{\"hello\":\"world\",\"webhook\":\"secret\"}";
const givenSignature = "sha256=c48e50b1d349b665dd7bf48bd243f22d5a22758c3f86714f0774aac3cab8fc5e"
const hashObject = createHmac('sha256', secret).update(payload);
const calculatedSignature = `sha256=${hashObject.digest('hex')}`;
const signaturesMatch = timingSafeEqual(Buffer.from(calculatedSignature), Buffer.from(givenSignature));
if (!signaturesMatch) {
console.log(`Signatures do not match\nExpected signature: ${calculatedSignature}\nActual: signature: ${givenSignature}`);
} else {
console.log("Signatures match");
}Webhook をトリガーする
Webhook に関連付けられたイベントが発生すると、Bitbucket Cloud は、イベント ペイロードを含むリクエストを Webhook URL に送信します。
If you want your server to check that the payloads it receives are from Bitbucket, you may need to allowlist certain IP addresses. For more specific information, see What are the Bitbucket Cloud IP addresses I should use to configure my corporate firewall?
次のイベント用に Webhook を作成できます。
Refer to the event documentation for descriptions and examples of each event payload.
この内容はお役に立ちましたか?