
# 署名キーをローテーションする

`POST /v1/signing-keys:rotate` · 権限 `signing-keys:write`

自動スケジュールとは別に、今すぐ署名キーのローテーションを実行します。

- `mode: immediate`: 通常のローテーション手順がただちに実行されます。事前に公開されていた`next`キーが署名を開始し、古い`active`キーは7日間`retired`の状態で残り、新しい`next`キーが公開されます。`next` が有効なキーと異なるアルゴリズムを使用しており（アルゴリズム変更）、7日以内に公開されたものである場合、呼び出しは`409 next_key_too_young`で失敗します。
- `mode: emergency`（キー漏えいの疑い）: 古い`active`キーは取り消され、JWKS から**即座に**削除されます。`next` が有効になり、新しい`next`が生成されます。`revoke_next: true` では `next` も取り消され、新たに生成された未公開のキーが有効化されます。`revoke_sessions: true` では、環境内のすべてのセッションおよびリフレッシュトークンのファミリーも取り消されるため、ユーザーは再度サインインする必要があります。`reason` が必須です。

## フェデレーションキー

`use` では、環境のフェデレーションキーのいずれかを指定することもできます。指定可能なのは、`saml_sp_signing` および `saml_sp_encryption`（SP メタデータに公開される SAML サービスプロバイダーの署名用および暗号化用キー）、または `oidc_rp_signing`（エンタープライズ OIDC 接続の `private_key_jwt` キー。`/sso/jwks.json` で公開）です。これらのキーは常に RSA-3072 で、1年ごとに自動的にローテーションされます。新しい `next` キーは引き継ぎの30日前に公開され、古いキーは引き継ぎ後も30日間公開されたままです。

- `mode: immediate` を指定すると、事前に公開されていた`next`キーが今すぐ有効になります。古いキーはさらに30日間公開されたままになります（`retired_kids` に表示されます）。公開済みの`next`キーがない場合、呼び出しは`409 conflict`で失敗します。`next` キーが7日以内に公開されたものである場合は、`409 next_key_too_young`で失敗します。
- `mode: emergency` を指定すると、有効なキーがメタデータまたは JWKS から**即座に**削除され、その秘密鍵が破棄されます（`revoked_kids`）。公開済みの`next`キーが有効になります。公開済みのキーがない場合、または `revoke_next: true` を指定した場合は、新たに生成された未公開のキーが有効になります。メタデータや JWKS を URL から読み込んでいる ID プロバイダは、次回の更新時に変更を取り込みます。メタデータや証明書を手動でアップロードしている ID プロバイダは、新しい証明書をアップロードするまでサインインを拒否します。この場合、影響を受ける接続ごとに `connection.sp_certificate_rotation_started` Webhook イベントが送信されます。

フェデレーションキーの場合、レスポンスの`next_kid`は`null`となり、`removed_kids`は空になります。また、`revoke_sessions` は許可されません。環境で SAML や`private_key_jwt` を一度も使用していない場合、ローテーション対象のキーが存在しないため、呼び出しは`409 conflict`で失敗します。

### 接続キー

SAML 接続には、環境のキーではなく専用の SP キーを設定できます。それらをローテーションするには、`use: saml_sp_signing` または `saml_sp_encryption` と併せて `connection_id`（`conn_…`）を追加します。モード、権限、ルールは同じですが、変更されるのはその接続のキーセットのみです。環境のキーと他の接続のキーはそのまま残り、`connection.sp_certificate_rotation_started` イベントはその接続に対してのみ送信されます。監査レコードの対象は環境として記録され、接続は`metadata.connection_id` に記録されます。不明な接続、または別の環境の接続を指定すると、`404 not_found`で失敗します。環境のキーを使用している接続を指定すると、`409 connection_keys_not_dedicated`で失敗します（`connection_id` を指定せずに環境のキーをローテーションしてください）。`connection_id` を指定しない場合は、環境のキーセットがローテーションされます。

緊急モードでは、`signing-keys:write` に加えて、認証情報に明示的に付与された `signing-keys:emergency` 権限が必要です。この権限を持つ制限付きキーまたは M2M クライアントだけが呼び出せます。フルアクセスのシークレットキー（`idp_sk_…`）は、緊急モードでは`403 insufficient_permissions`になります。

新しいトークン署名キーは、環境ポリシーのアルゴリズムを使用します（[ポリシーを取得](/docs/api/management/signing-keys/get-policy)）。トークン署名キーのローテーションが成功すると、`signing_key.rotated` または `signing_key.revoked` Webhook イベントが送信されます。すべてのローテーションは管理監査レコードに記録されます。このエンドポイントは「キーとシークレットの発行」のレート制限ファミリーに属します。`Idempotency-Key` を送信してください。ネットワークエラーの後にリトライすると、2回ローテーションするのではなく、最初の結果が返されます。

## リクエスト

JSON ボディ（未知のフィールドは`400 unknown_field`で拒否されます）:

| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| `Idempotency-Key` | ヘッダー | いいえ | 推奨。`A-Z a-z 0-9 _ -` の 16〜64 文字。 |
| `mode` | 文字列 | はい | `immediate` または `emergency`。 |
| `use` | 文字列 | いいえ | ローテーションするキー。既定値は`token_signing`（アクセストークンおよび ID トークンの署名キー）です。フェデレーションキーは`saml_sp_signing`、`saml_sp_encryption`、`oidc_rp_signing` です（[フェデレーションキー](#フェデレーションキー) を参照）。 |
| `revoke_sessions` | 真偽値 | いいえ | 緊急モードおよび`token_signing` のみ。すべてのセッションとリフレッシュトークンも取り消します。既定値は`false`。 |
| `revoke_next` | 真偽値 | いいえ | 緊急モードのみ。公開済みの`next`キーも取り消します。既定値は`false`。 |
| `reason` | 文字列 | 緊急モード: はい | 緊急モードのみ。印字可能な ASCII 文字 1〜512 文字（例: インシデント番号）。シークレットや個人データは含めないでください。 |
| `connection_id` | 文字列 | いいえ | `saml_sp_signing` および`saml_sp_encryption` のみ。専用の SP キーを持つ SAML 接続（`conn_…`）。環境のキーの代わりに、その接続のキーセットがローテーションされます（[接続キー](#接続キー) を参照）。 |

`mode: immediate` を指定した場合、`revoke_sessions: true`、`revoke_next: true`、または `reason` を送信すると`422`で失敗します（`not_allowed`）。`connection_id` を`token_signing` または`oidc_rp_signing` と併用すると、同様に失敗します。

## レスポンス

`200 OK` でローテーションの結果が返されます。`activated_kid` は今後署名を行うキーで、`next_kid` は新たに公開された`next`キーです（フェデレーションキーの場合は`null`）。`retired_kids` は署名を停止したものの公開されたままのキーです（トークン署名キーは7日間、フェデレーションキーは30日間）。`revoked_kids` は緊急ローテーションによって JWKS から削除されたキーです。`removed_kids` は7日間の期間が終了して廃止されたキーで、同じ手順で JWKS から削除されています。

```json
{
  "mode": "immediate",
  "use": "token_signing",
  "activated_kid": "ypeBEsobvcr6wjGzmiPcTaeG7_gUfE5yuYB3ha_uSLs",
  "next_kid": "GKw-c0PwFokMUQ6T-TUmEWnZ4_VlQ2Qpgw-vCTT0-OQ",
  "retired_kids": ["PiPoFgA5WUoziU9lZOGxNIu9egCI1CxKy3PurtWcAJ0"],
  "revoked_kids": [],
  "removed_kids": ["Ln0sA6lQeuJl7PW1NWiFpTOTogKdJBOUmXJloaJa78Y"],
  "revoke_sessions": false
}
```

## エラー

| HTTP | code | 条件 |
|---|---|---|
| 400 | `unknown_field` | ボディに未知のフィールドが含まれています。 |
| 400 | `malformed_request` | ボディが有効な JSON ではない、または `Idempotency-Key` ヘッダーが不正であるか重複しています。 |
| 403 | `insufficient_permissions` | 認証情報に`signing-keys:write`がない、または明示的に付与された`signing-keys:emergency`なしで緊急モードが要求されました。 |
| 404 | `not_found` | `connection_id` がこの環境の SAML 接続を指定していません。 |
| 409 | `connection_keys_not_dedicated` | `connection_id` が、環境の SP キーを使用している接続を指定しています。 |
| 409 | `next_key_too_young` | アルゴリズム変更が保留中で、`next` キーが7日以内に公開されている、または（フェデレーションキー、`immediate`）`next` キーが7日以内に公開されています。 |
| 409 | `conflict` | 環境に公開済みの`next`キーがない、フェデレーション`use` の有効なキーがない、または前のフェデレーションキーがまだ30日間の重複期間内にあります。 |
| 415 | `unsupported_media_type` | Content-Type が`application/json` ではありません。 |
| 422 | `validation_failed` | フィールドが欠落しているか無効です。ポインタはそのフィールドを示します（例: `/reason`）。 |
| 422 | `idempotency_key_reuse` | `Idempotency-Key` は、別のボディで既に使用されています。 |
| 501 | `not_implemented` | この操作は、このデプロイメントではまだ利用できません。 |
| 401 | `unauthenticated` | 認証情報が見つからない、無効、または取り消されています。 |
| 429 | `rate_limited` | レート制限を超えました。`Retry-After` 期間の後に再試行してください。 |
| 503 | `service_unavailable` | 依存先が一時的に利用できません。`Retry-After` 期間の後に再試行してください。 |

## 例

通常のローテーション:

```bash
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mode":"immediate"}'
```

`signing-keys:write` と`signing-keys:emergency` を付与した制限付きキーによる緊急ローテーション:

```bash
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
  -H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mode":"emergency","revoke_sessions":true,"reason":"INC-2041 key exposure"}'
```

SAML SP 署名キーの緊急ローテーション。公開済みの`next`キーも取り消します:

```bash
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
  -H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mode":"emergency","use":"saml_sp_signing","revoke_next":true,"reason":"INC-2042 SP key exposure"}'
```

1つの接続の専用 SAML SP 署名キーの緊急ローテーション:

```bash
curl -X POST "https://api.eu.keenauth.com/v1/signing-keys:rotate" \
  -H "Authorization: Bearer $KEENAUTH_EMERGENCY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mode":"emergency","use":"saml_sp_signing","connection_id":"conn_01h2xcejqtf2nbrexx3vqjhp41","reason":"INC-2043 connection key exposure"}'
```
