
# 一括パスワードリセットジョブを作成する

`POST /v1/jobs/password-resets` · 権限 `user-credentials:write`

漏えいの疑いがあるときや、弱いインポート済みハッシュ形式からユーザーを移行するときなどに、1 つの非同期ジョブで多数のユーザーに新しいパスワードの設定を強制します。レスポンスはジョブをすぐに返し、ユーザーのフラグ付けはバックグラウンドで行われます。ジョブの進行は [一括パスワードリセットジョブを取得する](/docs/api/management/jobs/get-password-reset) で確認してください。単一のユーザーには [ユーザーにパスワードのリセットを強制する](/docs/api/management/users/force-password-reset) を使用してください。

ユーザーは次の 2 つの方法のいずれかで選択します（両方は指定できません）:

- `user_ids`: 最大 100,000 件のユーザー ID です。重複する ID は 1 件として数えられます。この環境のユーザーではない ID と、パスワードのないユーザーは `not_found` として数えられます。
- `hash_algos`: これらのアルゴリズムのいずれかでパスワードが保存されており、ジョブ作成前に最後に変更されたすべてのユーザーです（例: `["md5", "phpass"]`）。ジョブ作成後に設定されたパスワードは選択されません。

`connection_id` フィルターはまだ利用できません。これを送信したリクエストは `422 validation_failed`（`/connection_id` に `not_supported`）で拒否されます。

`mode` を選択します:

- `on_login`: 選択された各ユーザーは、次回パスワードでのサインインに成功した後に新しいパスワードを設定しなければなりません。
- `lazy_then_bulk_reset`: 期限（`deadline_days`、1〜365、既定値は 30）までは同じです。期限になると、まだパスワードを変更していない選択済みの全ユーザーのパスワードハッシュが削除され、確認済みのプライマリメールアドレスにパスワードリセットメールが送信されます（確認済みのメールアドレスがないユーザーは、自分でリセットを要求できます）。`deadline_days` はこのモードでのみ受け付けられます。

`Idempotency-Key` は必須です。同じ認証情報、キー、リクエストであれば、同じジョブが返されます（`Idempotent-Replayed: true` 付き）。同じキーで異なるリクエストを送ると、`422 idempotency_key_reuse` で拒否されます。環境で未完了のジョブは最大 20 件です。lazy ジョブは期限まで未完了のままです。ジョブの作成は管理の監査ログ（`password_reset_job.created`）に記録され、`password_reset.scheduled` イベントを発行します。

## リクエスト

| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| `mode` | 文字列 | はい | `on_login` または `lazy_then_bulk_reset`。 |
| `user_ids` | 文字列の配列 | どちらか一方 | 1〜100,000 件のユーザー ID（`usr_…`）。 |
| `hash_algos` | 文字列の配列 | どちらか一方 | 保存されているハッシュアルゴリズム: `argon2id`, `argon2i`, `bcrypt`, `scrypt`, `firebase_scrypt`, `pbkdf2_sha1`, `pbkdf2_sha256`, `pbkdf2_sha512`, `django_pbkdf2_sha256`, `django_bcrypt_sha256`, `phpass`, `ldap_ssha`, `ldap_ssha256`, `sha512_crypt`, `hmac_sha256`, `salted_sha256`, `salted_sha512`, `md5`。 |
| `deadline_days` | 整数 | いいえ | `lazy_then_bulk_reset` のみ: 1〜365、既定値は 30。 |

## レスポンス

ジョブを含む `202 Accepted`。

```json
{
  "id": "job_01h455vb4pex5vsknk084sn02q",
  "mode": "lazy_then_bulk_reset",
  "filter": "hash_algo",
  "hash_algos": ["md5", "phpass"],
  "status": "marking",
  "deadline_at": "2026-02-14T09:30:00Z",
  "total": 0,
  "marked": 0,
  "not_found": 0,
  "passwords_deleted": 0,
  "emailed": 0,
  "created_at": "2026-01-15T09:30:00Z"
}
```

## エラー

すべてのエラーは、安定した `code` を含む `application/problem+json` ボディです。

| HTTP | `code` | 発生条件 |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | `Idempotency-Key` ヘッダーがないか形式が不正、ボディが有効な JSON ではない、または未知のフィールドがあります。 |
| 401 | `unauthenticated` | API キーがないか、無効か、失効しています。 |
| 403 | `insufficient_permissions` | キーに `user-credentials:write` 権限がありません。 |
| 409 | `conflict` | この環境にはすでに 20 件の未完了ジョブがあります。 |
| 413 | `payload_too_large` | ボディが 4 MiB を超えています。 |
| 422 | `validation_failed` | フィールドがないか無効です。`errors[].pointer` が該当するフィールドを示します。 |
| 422 | `idempotency_key_reuse` | `Idempotency-Key` が別のリクエストで使用されています。 |
| 429 | `rate_limited` | レート制限を超えました。`Retry-After` に従ってください。 |
| 503 | `service_unavailable` | 依存先のサービスが一時的に利用できません。後で再試行してください。 |

## 例

```bash
curl -X POST https://api.eu.keenauth.com/v1/jobs/password-resets \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"mode": "lazy_then_bulk_reset", "hash_algos": ["md5", "phpass"], "deadline_days": 30}'
```

CLI: `keenauth jobs password-resets create --mode lazy_then_bulk_reset --hash-algos md5,phpass --deadline-days 30 --yes`
