> 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

## Webhook認証 <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スキーマは以下で確認できます [こちらのapidocs](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」をクリックしてシークレットを作成します。\n​

   ![新しいWebhookの登録を促す、空のwebhooksダッシュボード。](/files/65f2369f04b1a2a0b5c179ca2b014de69f280753)
3. 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. 文字列化したリクエストボディから、以下を使ってHMACダイジェストを作成する `sha256` アルゴリズムで、AikidoからのWebhookシークレットで署名する
5. リクエストヘッダーの署名が、今生成したダイジェストと一致することを確認する。
6. 次を確認する: `dispatched_at` プロパティのエポックタイムスタンプが30秒より古くないこと

以下に、expressを使用する際にハッシュを検証する方法を示す疑似JavaScriptコードを共有します。 `express` フレームワーク。これはミドルウェアとして含めるべきであり、値が有効かどうかを確認するために、追加の検証を行う必要があります。

```
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.
