Errors、rate limit、retry、冪等性#
この文書では、Management API / Public Authentication API の Problem Details、OIDC error、rate limit、write の再送方法を説明する。
Problem Details#
Management API と Public Authentication API のエラーは RFC 9457 Problem Details を application/problem+json として返す。標準 member に加えて code と request_id を拡張 field として含める。成功・失敗を問わず応答には X-Request-Id header が付く。
{
"type": "https://docs.example-auth.com/errors/invalid-request",
"title": "Bad Request",
"status": 400,
"detail": "<入力エラーの説明>",
"code": "invalid_request",
"request_id": "req_<request-id>"
}
code は機械判定用の安定した key であり、detail、title、type URI の末尾文字列を分岐条件にしない。detail は診断用で、省略される場合がある。request_id をサポート問い合わせとログ照合に使う。
type は URI 識別子である。処理の分岐には code を使う。
OAuth error#
OIDC /oauth2/token の OAuth error は Problem Details ではなく、OAuth 2.0 JSON response として返る。
{
"error": "invalid_client"
}
error_description は省略可能で、応答には X-Request-Id header が付く。契約上の error code は次のとおりである。
| Code | 意味 |
|---|---|
invalid_request |
token / authorize request の形式不正 |
invalid_client |
Client 認証失敗 |
invalid_grant |
code、redirect URI、PKCE verifier、または refresh token が無効 |
unsupported_grant_type |
未対応の grant |
invalid_scope |
不許可 scope |
access_denied |
認可拒否 |
server_error |
サーバー側エラー |
temporarily_unavailable |
一時的な利用不可 |
/oauth2/authorize の malformed request は JSON の invalid_request として返る。他の authorize failure が Hosted Login の /error?reason=... へ遷移する場合もある。OAuth error response を常に Client の redirect URI へ返す前提にしない。
Rate limit#
Rate limit は Environment / Client / IP / email / challenge / credential / Management API key / Workspace などの key scope で分離する。既定値は次のとおりである。
| Endpoint / scope | Limit |
|---|---|
| OTP start / IP | 10 回 / 10 分 |
| OTP start / email | 5 回 / 30 分 |
| OTP verify / challenge | 5 回まで |
| Passkey options / IP | 30 回 / 分 |
| Passkey verify / credential | 10 回 / 分 |
| Social start / IP | 30 回 / 10 分 |
| Token endpoint / Client | 120 回 / 分 |
| Management API / key | 600 回 / 分 |
| User search / Workspace | 120 回 / 分 |
超過時は HTTP 429 を返す。Retry-After は待機秒数を表す。時間窓の limit では窓の秒数、challenge ごとの累積回数 limit では 0 となる。rate-limit Problem Details の code は rate_limited であり、X-Request-Id も返る。middleware が返す 429 には同じ値を retry_after_seconds extension にも含める。OTP start の service-level error response は extension を含めない場合があるため、header を正とする。RateLimit-Limit / RateLimit-Remaining は返さない。
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 0
X-Request-Id: req_<request-id>
{
"type": "https://docs.example-auth.com/errors/rate-limited",
"title": "Too Many Requests",
"status": 429,
"code": "rate_limited",
"request_id": "req_<request-id>",
"retry_after_seconds": 0
}
Retry-After に従って待つ。OTP verify の challenge 上限は累積 limit なので、時間を置いても同じ challenge を再利用できない。
Retry#
Problem Details に retry 可否を示す field はない。HTTP 429 は Retry-After を使う。HTTP 5xx は一時障害の可能性があるが、処理が再実行安全な場合だけ bounded backoff で retry する。入力不正、Client 認証失敗、invalid_grant などの 4xx は同じ要求を繰り返しても解消しない。
OIDC authorization code は一度だけ交換できる。Token endpoint 呼び出しの結果が不明な場合に同じ code を無制限に retry せず、新しい認可フローを開始する。BFF の @auth-platform/server は一時的な refresh failure で local session を直ちに破棄せず、invalid_grant では session を破棄する。
| Error | Retry 方針 |
|---|---|
OAuth server_error / temporarily_unavailable |
Server SDK は transient error として扱う。bounded backoff を使い、BFF refresh 中に session を即破棄しない。 |
Management API idempotency_store_unavailable (503) |
同じ Idempotency-Key と同じ body で write を retry する。 |
Public Authentication API user_unavailable (503) |
一時障害である。再認証せず、bounded backoff で retry する。 |
invalid_grant、入力 validation error、invalid_client |
同じ要求を retry しない。Authorization code 交換の結果が不明なら、SDK の結果に従い、必要に応じて新しい認可フローを開始する。 |
Management API write の Idempotency-Key#
POST / PATCH / DELETE に Idempotency-Key header を付けられる。空でない 255 文字以下の値を使う。記録は Workspace と route と key の組み合わせで分離される。初回 response が保存された後、同じ method・path/query・canonical JSON body の再送では保存済み response を返し、write handler を再実行しない。同じ key を異なる要求に使うと 409 idempotency_key_conflict の Problem Details を返す。5xx response は retry 可能性を残すため保存対象にしない。
Idempotency-Key: create-client-<unique-operation-id>
同じ論理操作を timeout 後に再送する場合は、同じ key と同じ request body を使う。JSON object の property 順序だけが異なる場合、canonicalization により conflict にはならない。method、path/query、body が異なる要求には新しい key を発行する。