
# keenauth_webhook_endpoint

`keenauth_webhook_endpoint` リソースは、ウェブフックエンドポイントを管理します。ウェブフックエンドポイントは、環境のイベントを受信する HTTPS アドレスで、Standard Webhooks で署名されます。プロバイダは署名シークレットを、指定された RSA 公開鍵で暗号化した状態でのみ state に保存します。

```terraform
resource "keenauth_webhook_endpoint" "orders" {
  key         = "orders"
  url         = "https://hooks.example.com/keenauth"
  description = "Order service"
  event_types = ["user.created", "user.updated", "organization.created"]
  event_schema_versions = {
    "user.created" = 1
  }
  public_key = file("${path.module}/webhook-secret-key.pub.pem")

  rotation_trigger          = time_rotating.webhook_secret.id
  previous_secret_ttl_hours = 48
}

resource "time_rotating" "webhook_secret" {
  rotation_days = 90
}

output "orders_webhook_secret_encrypted" {
  value = keenauth_webhook_endpoint.orders.encrypted_signing_secret
}
```

## 引数

- `url` は必須です。`https` のみ使用でき、ポートを指定しない場合またはポート 443 のみ、ユーザー情報とフラグメントは使用できず、IP アドレスではなくホスト名を指定する必要があります（最大 2048 文字）。
- `key` は環境内で一意です（`^[a-z0-9][a-z0-9_-]{0,63}$`）。省略すると、API が `endpoint-<ID の末尾 8 文字>` を自動的に生成します。
- `event_types` はカタログのイベントタイプを一覧にします（最大 100 件）。空のセットはデフォルトで、高頻度の `authentication.*` タイプを除くすべてのタイプを意味します。これらは明示的に指定する必要があります。
- `event_schema_versions` は、イベントタイプをペイロードのスキーマバージョンに対応付けます。各タイプは、そのエンドポイントが受信するタイプである必要があります。
- `payload_mode` は `thin`（デフォルト。ID、変更されたフィールド名、ステータスフィールドのみを含み、個人データは含みません）または `full` です。
- `rate_limit_per_second` は 1 から 1000 までで、デフォルトは 50 です。
- `status` は `enabled`（デフォルト）または `disabled_by_user` です。

すべての引数はその場で変更されます。更新時には、変更されたフィールドのみを JSON Merge Patch として送信し、最後に読み取った ETag を `If-Match` として付与します。最後の読み取り後にエンドポイントが別の場所で変更されていた場合、適用は `412` で失敗し、何も変更されません。その場合は plan を再度実行して、ドリフトを確認してください。

## 署名シークレットは平文で保存されません

API が署名シークレット（`idp_whsec_…`）を返すのは、エンドポイントの作成時とシークレットのローテーション時のみです。`public_key` を指定すると、プロバイダはシークレットを RSA-OAEP（SHA-256、MGF1 SHA-256、空のラベル）で暗号化し、base64 の暗号文のみを `encrypted_signing_secret` に書き込みます。`public_key` を指定しない場合、シークレットは破棄されます。後から `keenauth webhook-endpoints rotate-secret` でローテーションするか、`public_key` を設定してください。平文のシークレットが state、plan ファイル、出力、ログに残ることはありません。

鍵ペアは OpenTofu の外で一度だけ作成し、秘密鍵は構成に含めないようにしてください。

```shell
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out webhook-secret-key.pem
openssl pkey -in webhook-secret-key.pem -pubout -out webhook-secret-key.pub.pem
```

`tofu apply` の後、シークレットを復号して受信側に渡します。

```shell
tofu output -raw orders_webhook_secret_encrypted | base64 -d | \
  openssl pkeyutl -decrypt -inkey webhook-secret-key.pem \
    -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256
```

`public_key` は、PEM 形式の RSA 公開鍵（`PUBLIC KEY` または `RSA PUBLIC KEY`）で、2048 ビット以上である必要があります。秘密鍵や、それより小さい鍵は plan 時に拒否されます。

## ローテーション

シークレットは、`public_key` を設定または変更したとき、および `rotation_trigger` が新しい値に変わったとき（例：`time_rotating` リソースの ID）にローテーションされます。ローテーション後も、古いシークレットは新しいシークレットと並行して `previous_secret_ttl_hours`（0 から 168。API のデフォルトは 24。0 を指定するとすぐに破棄されます）の間、署名に使用され続けます。これにより、受信側はイベントを取りこぼさずに切り替えられます。`previous_secret_expires_at` には、古いシークレットが無効になる時刻が表示されます。`public_key` を削除しても `encrypted_signing_secret` が削除されるだけで、シークレットはローテーションされません。

## 上限とステータス

有効なエンドポイントは、環境ごとのプランの上限に含まれます。上限は Free 3、Startup 20、Business 20、Enterprise 50 です。上限を超えて作成または有効化しようとすると `403 quota_exceeded` で失敗します。別のエンドポイントを無効化または削除するか、プランをアップグレードしてください。

KeenAuth は、失敗が続くエンドポイント（`disabled_by_failure`）や、受信側が `410 Gone` を返すエンドポイント（`disabled_by_receiver`）を無効化します。次の plan では、構成された `status` への変更が表示され、適用するとエンドポイントが再び有効になります。

## インポート

エンドポイントの ID またはキーを指定してインポートします。

```shell
tofu import keenauth_webhook_endpoint.orders orders
```

署名シークレットは読み戻せないため、インポート後は `encrypted_signing_secret` が空になります。構成で `public_key` を設定している場合、次の apply でシークレットがローテーションされ、新しいシークレットが暗号化された状態で配信されます。

テスト送信、リプレイ、配信の再試行は一回限りの操作であり、構成には含めません。これらには `keenauth webhook-endpoints test`、`replay`、`deliveries` を使用してください。
