原文タイトル: Using webhooks
Webhookは、Overeが他のアプリケーションとリアルタイムでシームレスに連携できる強力なツールです。基本的に、Webhookはシステム内で特定のイベントが発生したときに、指定したURLへ自動的に通知やデータを送信する仕組みです。更新を絶えずポーリングする代わりに、Webhookを使えば、セキュリティ侵害やトリガーされたアラート、対応が必要なユーザーアクティビティなど、重要なことが起こったときに即座に通知を受け取ることができます。
複雑なITインフラを管理しているユーザーや、他のシステムとの緊密な連携を維持する必要があるユーザーにとって、Webhookは非常に役立ちます。Webhookを使えば、インシデント対応ツールのトリガー、チャットアプリケーションでのチームへの通知、ダッシュボードの自動更新など、既存のワークフローとOvereを接続できます。本章では、Webhookを設定する手順をご案内し、重要なイベントに先んじて対応し、環境のセキュリティと効率性を維持できるよう支援します。
Webhookは組織レベルで設定できます。つまり、その組織配下で管理されているすべてのサイトに対して、Overeが通知をプッシュするエンドポイントを指定できます。
Webhookは Organization Config > Notifications > Webhooks の専用セクションで設定できます。

Webhookを登録するには、以下の手順を行います。
Overe組織からプッシュされるメッセージの受信を停止したい場合は、Webhook管理画面に戻り、設定済みのURIの横にある Clear URI ボタンをクリックすることで停止できます。

操作が成功したかどうかを知らせる結果メッセージが表示されます。
双方が名乗っているとおりの相手であること、そして通知を処理する目的で設定されていることを保証するために、Overeでは以下の仕組みを導入しています。
このチャレンジは、Webhookの登録時にOvereが指定されたHTTPエンドポイントへ送信する文字列です。
Overeが発行するリクエスト
POST https://<endpoint_url>?subscription_challenge=<secret_string>その結果として、エンドポイントはクエリパラメータとして提供されたシークレット文字列を返す必要があります。これにより、Overeはこの設定を期待していたこと、そしてこれらの通知を処理するためにサービスが設定されていることを確認できます。
期待される結果
Content-Type: application/json<br>==============================<br>Body:<br>{<br> "subscriptionChallenge": "<string_from_the_query_parameter>"<br>}エンドポイントが正しく設定されていれば、受信メッセージを処理する準備が整っているはずです。
Overeが発行したリクエストのみを処理していることを確実にするため、すべてのリクエストには署名が含まれており、それらを正当な通知とみなす前に検証する必要があります。
エンドポイントに発行される各リクエストには、以下が含まれます。
POST https://<endpoint_url><br>============================<br>Body: <br> { /* notification body */ }<br>============================<br>Headers:<br> Date: <unix-timestamp-seconds-of-the-send-time> <br> X-Overe-Signature: <notification-signature> それらの署名値は、リクエストボディの内容と Date タイムスタンプを「.」区切りで連結した値に対して、Overeの公開鍵を使って検証する必要があります。
Value to verify against: <body>.<timestamp>メッセージの検証に必要なOvereの公開鍵は、有効なエンドポイントが登録された後、Overe Portalの「Webhooks管理」セクションの Current Configuration パネルで確認できます。

以下は、署名を検証するために cryptography.ioパッケージ を使用するPythonコードです。
import datetime<br>import base64<br><br>from cryptography.hazmat.primitives.asymmetric import padding, rsa<br>from cryptography.exceptions import InvalidSignature<br>from cryptography.hazmat.backends import default_backend<br>from cryptography.hazmat.primitives import hashes, serialization<br><br>def signature_is_valid(signature: str, body: str, date: str, public_key: str) -> bool:<br> timestamp = datetime.datetime.fromisoformat(date)<br> unix_timestamp = int(timestamp.timestamp())<br><br> signed_body = f"{body}.{unix_timestamp}"<br> decoded_signature = base64.b64decode(signature)<br><br> pubkey = cast(<br> rsa.RSAPublicKey,<br> serialization.load_pem_public_key(<br> public_key.encode(), backend=default_backend()<br> ),<br> )<br> try:<br> pubkey.verify(<br> decoded_signature,<br> signed_body.encode(),<br> padding.PSS(<br> mgf=padding.MGF1(hashes.SHA256()),<br> salt_length=padding.PSS.MAX_LENGTH,<br> ),<br> hashes.SHA256(),<br> )<br> return True<br> except InvalidSignature:<br> return False イベント通知リクエストは CloudEvents仕様 に準拠します。リクエストは、イベントデータを含むJSONペイロードを伴うPOSTリクエストです。ペイロードは以下のように構成されています。
{<br> "specversion":"1.0",<br> "id": "unique-event-guid",<br> "source": "overe.io",<br> "type": "webhook.notifications.AnomalyDetected.v1",<br> "time": "<iso-timestamp-utc>",<br> "data": { <br> "message": "<textual message>",<br> "data": { /* data format specific to the particular event type. */ }<br> }<br>}現在、想定されるイベントタイプは以下のとおりです。