> For the complete documentation index, see [llms.txt](https://help.aikido.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.aikido.dev/docs/docs-ja/sonono/aikido-webhooks.md).

# Aikido Webhook

## Webhooks認証 <a href="#webhooks-authentication" id="webhooks-authentication"></a>

Aikidoから届くwebhookが実際にAikidoから送信されたものであり、そのペイロードが改ざんされていないことを確認するために、Aikidoは共有した秘密鍵で署名されたペイロードのハッシュを使用します。

{% hint style="success" %}
Aikidoは、常に次のIPアドレスからwebhookリクエストを送信します: 52.18.113.172。
{% endhint %}

### Webhookスキーマ <a href="#webhook-schema" id="webhook-schema"></a>

webhookスキーマは [弊社のAPIドキュメント](https://apidocs.aikido.dev/reference/webhooks).

### webhookシークレットの生成 <a href="#generating-a-webhook-secret" id="generating-a-webhook-secret"></a>

1. 次へ移動 [webhooks統合ページ](https://app.aikido.dev/settings/integrations/api/webhooks)
2. 右側のテーブルのすぐ上にある「Add secret」をクリックしてシークレットを作成します。\
   ​

   ![新しいwebhookの登録を促す空のwebhooksダッシュボード。](/files/65f2369f04b1a2a0b5c179ca2b014de69f280753)
3. webhookシークレットが作成されると、webhookシークレットをコピーして安全に保管できるモーダルが表示されます。このシークレットは安全に保管し、コードリポジトリのいずれにもコミットしないことが重要です。

### Webhookの検証 <a href="#verifying-a-webhook" id="verifying-a-webhook"></a>

Aikidoが、設定したイベントに対してwebhookを送信するたびに、イベントのペイロードのハッシュを作成し、作成したばかりのシークレットで署名します。この一意のハッシュは `X-Aikido-Webhook-Signature` リクエストヘッダー経由で含まれます。これにより、webhookとそのペイロードが真正であることを検証できます。

リプレイ攻撃から保護するため、HTTPリクエストを送信する直前の時刻を示すエポックタイムスタンプをwebhookペイロードに含めます。このタイムスタンプは `dispatched_at` プロパティとして含まれ、ペイロードを検証する際に30秒以内でなければなりません。

選択するプログラミング言語に関係なく、受信したwebhookを検証する手順は次のとおりです:

1. ペイロードが有効なJSON文字列であることを確認する
2. から署名を取得する `X-Aikido-Webhook-Signature` リクエストヘッダー
3. リクエストボディをJSON文字列に再度パースする
4. 文字列化されたリクエストボディから `sha256` アルゴリズムを使ってhmacダイジェストを作成し、Aikidoのwebhookシークレットで署名する
5. リクエストヘッダーの署名が、直前に生成したダイジェストと一致することを確認する。
6. 次のことを確認する `dispatched_at` プロパティのエポックタイムスタンプが30秒より古くないこと

以下では、 `express` フレームワークを使用している場合に、ハッシュをどのように検証できるかを示す擬似JavaScriptコードを紹介します。これはミドルウェアとして組み込み、値が有効かどうかを確認するために、さらに検証を行う必要があります。

```
const { createHmac } = require('node:crypto');

const express = require('express');
const bodyParser = require('body-parser');

const PORT = 4000;

const app = express();

app.use(bodyParser.json());

const isIncomingWebhookValid = (payload, signature) => {
	// 環境変数から生のwebhookシークレットを取得する
	const aikidoWebhookSecret = process.env.AIKIDO_WEBHOOK_SECRET;

	// hmacインスタンスを作成する
	const hmac = createHmac('sha256', aikidoWebhookSecret);

	// ペイロードオブジェクトをJSON文字列に変換する
	const rawPayload = JSON.stringify(payload);

	// 文字列化されたペイロードでhmacの内容を更新する
	hmac.update(rawPayload);

	// hmacの内容のダイジェストを計算し、16進値として返す
	const payloadDigest = hmac.digest('hex');

	// ダイジェストが提供された署名と一致しない場合、webhookは無効です
	if (payloadDigest !== signature) return false;

	// 現在のエポックタイムスタンプを取得する
	const currentEpochTimestamp = Math.floor(new Date().getTime() / 1000);
	
	// ペイロードの dispatched_at エポックタイムスタンプが30秒以上前の場合、webhookは無効です
	if ((currentEpochTimestamp - (payload['dispatched_at'] ?? 0)) > 30) return false;

	// webhookはすべてのチェックを通過し、有効です
	return true;
}

app.post('/webhooks/aikido/issue-created', async (req, res) => {
	const isValid = isIncomingWebhookValid(req.body, req.headers['X-Aikido-Webhook-Signature']);
	if (!isValid) {
		throw new Error(`リクエスト署名が無効です`)
	}
    
	// あなたのビジネスコード

    res.status(204);
});

app.listen(PORT, () => {
	console.log(`ポート${port}でサーバーがリスニングしています`);
});
```

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.aikido.dev/docs/docs-ja/sonono/aikido-webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
