
# 組織ポリシーの作成または置き換え

`PUT /v1/organizations/{org_id}/policies/{policy_kind}` · 権限 `organizations:write`

1 つのポリシー種別の設定オブジェクト全体を置き換えます。組織ポリシーは、環境の設定よりも厳しくすることしかできません。プランによる制限はサーバー側で適用されます。`session` と `ip_allowlist` の種別、および AAGUID 許可リストには Enterprise プランが必要です（開発環境では利用可能です）。設定内容は管理監査ログに記録されますが、`organization.updated` イベントには含まれません。

## リクエスト

| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| `org_id` | パス | はい | 組織 ID（`org_…`）。 |
| `policy_kind` | パス | はい | ポリシー種別: `authentication_methods`、`mfa`、`phishing_resistant`、`sso_enforcement`、`session`、`ip_allowlist`。それ以外の値を指定すると `404` が返されます。 |
| `If-Match` | ヘッダー | いいえ | ポリシーが存在する場合に必須です（最後に読み取ったときの `ETag`）。ポリシーを作成する場合は省略します。`*` は既存のポリシーに一致します。 |
| `settings` | オブジェクト | はい | 種別ごとの設定オブジェクトです。種別ごとのフィールド: `authentication_methods`: `allowed_connection_ids`（`conn_…`）、`allow_passkey`、`allow_password`。`mfa`: `required_for`（`none`、`admins`、`all`）、`allowed_factors`（`totp`、`webauthn`、`sms`、`email`）、`enrollment_grace_days`（0〜30）。`phishing_resistant`: `required_for`、`aaguid_allowlist`（最大 500 件）。`sso_enforcement`: `mode`（`off`、`org_context`、`verified_domains`）、`connection_ids`（`conn_…`）、`bypass_user_ids`（`usr_…`、最大 2 件）。`session`: `idle_minutes`、`absolute_minutes`、`refresh_idle_days`、`refresh_absolute_days`。`ip_allowlist`: `cidrs`（最大 100 件）、`applies_to`（`admins`、`all`）。 |

リクエストボディ:

```json
{
  "settings": {
    "required_for": "all",
    "allowed_factors": [
      "totp",
      "webauthn"
    ],
    "enrollment_grace_days": 7
  }
}
```

## レスポンス

ポリシーを作成した場合は `201 Created`、置き換えた場合は `200 OK` を返します。ボディはポリシーで、レスポンスには新しい `ETag` が含まれます。

```json
{
  "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
  "policy_kind": "mfa",
  "schema_version": 1,
  "settings": {
    "required_for": "all",
    "allowed_factors": [
      "totp",
      "webauthn"
    ],
    "enrollment_grace_days": 7
  },
  "updated_at": "2026-10-12T09:30:00.123456Z",
  "version": 1
}
```

## エラー

| HTTP | code | 発生条件 |
|---|---|---|
| 400 | `unknown_field` | ボディに、スキーマにないフィールドや読み取り専用のフィールドが含まれています。 |
| 403 | `plan_feature_unavailable` | 種別または AAGUID 許可リストに、より上位のプランが必要です。問題の詳細には `feature` と `required_plan` が含まれます。 |
| 404 | `not_found` | 組織が存在しないか、種別が不明です。 |
| 409 | `domain_not_verified` | `mode` が `verified_domains` の `sso_enforcement` には、組織で検証済みのドメインが必要です。 |
| 409 | `connection_test_required` | `sso_enforcement` を有効にする（`off` から、またはポリシーがない状態から有効にする）には、現在の構成で、`connection_ids` のいずれか 1 つ以上について、過去 24 時間以内に成功したテストサインインが必要です。接続テスト（`POST /v1/connections/{connection_id}:test`）を実行してから、もう一度お試しください。 |
| 409 | `organization_pending_deletion` | 組織はセルフサービス削除の処理を待っています。先に削除を取り消してください。 |
| 412 | `precondition_failed` | `If-Match` が現在のバージョンと一致しない、この種別のポリシーが存在しない状態で送信された、またはこのリクエストの作成中に別のリクエストがポリシーを作成した場合に発生します。ポリシーを再度読み取ってください。 |
| 422 | `validation_failed` | 設定フィールドが不明であるか、無効です。`errors[]` は `/settings/…` を指します。 |
| 422 | `policy_weaker_than_parent` | 設定が環境の設定より弱くなっています。`errors[]` は弱くなったフィールドを指します。 |
| 422 | `at_least_one_method` | `authentication_methods` で、サインイン方法が 1 つも残らない設定になっています。 |
| 428 | `precondition_required` | ポリシーが存在するにもかかわらず、`If-Match` が指定されていません。 |
| 401 | `unauthenticated` | 認証情報がないか、無効であるか、失効しています。 |
| 403 | `insufficient_permissions` | 認証情報に必要な権限がありません。 |
| 429 | `rate_limited` | レート制限を超えました。`Retry-After` で示された期間の後に再試行してください。 |
| 503 | `service_unavailable` | 依存先のサービスが一時的に利用できません。`Retry-After` で示された期間の後に再試行してください。 |

## 例

```bash
curl -X PUT https://api.eu.keenauth.com/v1/organizations/org_01j9xk3m7q8r2s4t6v8w0y2z4a/policies/mfa \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"settings":{"required_for":"all","allowed_factors":["totp","webauthn"]}}'
```
