要約
ifUnchangedByは、対象オブジェクトの選んだプロパティがメソッド開始時にも期待どおりかを確認し、無関係な変更による競合を避ける。- 条件成立は状態の証拠であり、削除や更新を命じる人の権限ではない。
atomic:trueも一つのFoo/setの全成否を守るだけで、外部システムの結果までは含まない。
共有メールボックスで、整理用クライアントが古い未読メールを削除しようとした。別の端末で誰かが先に読んでいたなら、削除を止めたい。JMAP Mail では未読状態は $seen キーワードが存在しない形で表せるため、クライアントは keywords/$seen:null を条件にできる。
条件が成立すれば削除は進み、既読に変わっていれば stateMismatch で方法全体が拒否される。この仕組みは競合制御として筋が通っている。だが共有メールボックスには、さらに別の問いがある。整理用サービスには本当に削除を決める権限があったのか。法的保全、監査、担当者の引き継ぎ、利用者の意思はどう扱われるのか。
状態を正しく読むことと、その状態を根拠に行動を命じることは同じではない。
JMAP Conditional Set の現行文書は draft-ietf-jmap-conditional-00 で、2026 年 9 月 15 日付、2027 年 3 月 19 日失効予定である。調査時点では JMAP ワーキンググループの活動中 Internet-Draft で、Standards Track を意図し、承認されれば RFC 8620 を更新する。最終 RFC、実装認定、普及率の資料ではない。
型全体の変化と一つの判断を分ける
JMAP Core の ifInState は、アカウント内のオブジェクト型全体に対する状態文字列を比較する。同じ型のどのオブジェクトが変わっても値が変わり得る。新着メールや別端末の操作が多い環境では、対象メールに関係のない変更でも書き込みが拒否される。
草案の ifUnchangedBy は、オブジェクト ID と PatchObject の組で、必要な事実だけを条件にする。サーバーは、現在のオブジェクトにその PatchObject を適用しても何も変わらないかを判定する。各ポインターの値が一致し、null はプロパティ不在を主張する。比較対象は Foo/get が返す表現である。
これにより、未読という一事実だけを削除前提にできる。別のラベルや無関係なメタデータが変わっても、意図的に競合としない。しかし成功応答の意味も一事実に限定される。「メール全体が変わっていない」ではなく、「評価時点で $seen が存在しなかった」である。
監査記録が「条件付き削除成功」としか残さなければ、選択したポインターが消える。すると後から、内容、保全フラグ、共有状態まで確認済みだったかのように見える。狭い証拠を狭いまま保存することが重要だ。
全オブジェクト比較が必要なら、すべての変更で必ず更新されるサーバー管理トークンを条件に使える。ただし、そのトークンを更新しない管理経路が一つでもあれば、完全性の主張は崩れる。記号の存在ではなく、全書き込み経路を拘束する運用が証拠強度を決める。
読めること、試せること、変えられること
条件には、クライアントが変更できないサーバー設定プロパティも使える。内容 ID、サイズ、変更時刻のような値を前提にできるのは有用である。ただしクライアントがそのプロパティを読む権限を持つ場合に限る。
読めない値について成功か失敗かだけを返せば、攻撃者は候補を繰り返し試して秘密を推測できる。草案は、そのような条件を評価せず forbidden にするよう求める。条件機構を値の探索装置にしないためだ。
一方、読み取り権限があるからといって、削除権限が生まれるわけでもない。条件が一致した後でも、方法は書き込み権限不足で失敗し得る。認証されたサービスアカウントに広い技術権限があっても、組織内で削除を決める委任が適切とは限らない。
Heng Lu の議論にある「参加や記録は証拠であって権限ではない」という境界は、ここにも当てはまる。プロトコルが状態を精密に表せても、その状態から組織の意思を自動生成してはならない。
条件は方法全体を止める
ifUnchangedBy の条件が一つでも成立しなければ、サーバーは方法レベルの stateMismatch を返し、その Foo/set 内の作成、更新、削除を一切行わない。型の状態文字列も変えない。失敗した ID は示してよいが、現在値は返さない。
独立した結果が必要なら、クライアントは複数のメソッド呼び出しに分け、それぞれに条件を置く。これは単なる実装詳細ではない。一つにまとめれば一件の不一致が全件を止める。分ければ一部だけが先に見える可能性を受け入れる。
どちらが正しいかは、削除対象同士の関係や回復可能性を知るアプリケーションが決める。共通プロトコルは選択肢を提供できるが、損失の所有者にはなれない。
原子性は開始条件ではなくコミット条件
草案は別に atomic:true を定義する。JMAP Core では、一つの Foo/set 内で作成、更新、削除が個別に成功または失敗し得る。原子モードでは、要求した変更がすべて有効になるか、一つも有効にならないかのどちらかになる。
制約は途中状態ではなく、全変更を適用した結果の集合に対して評価される。二つのファイル名交換では、片方だけ先に変更すると重複になるが、最終集合には重複がない。このような「全体なら正しい」変更を表現できる。
一部が不正なパッチ、権限不足、一意性違反などで失敗すれば、atomicFailure となり何もコミットされない。条件不一致は、原子性を併用していても stateMismatch のままである。出発点が違ったのか、提案した変更集合が成立しなかったのかを区別できる。
サーバーが特定の方法を原子的に実行できない場合は cannotApplyAtomically を返し、部分実行へ黙って落としてはならない。クライアントは部分結果を許容できると判断した場合だけ、atomic を外して再要求できる。
その再要求は同じ操作の再送ではない。保証を弱くする新しい決定である。高影響の削除を可用性対策として自動的に非原子化すれば、最も危険な瞬間に不変条件が消える。
サーバー内の成功と利用者の結果
原子的な応答の境界は、そのサーバーの Foo/set である。検索索引、通知、キャッシュ、別の配送処理、オフライン端末まで同じトランザクションに含まれるとは限らない。
メール削除がコミットされても、オフライン端末にはコピーが残り得る。共有解除がコミットされても、別システムが発行済み資格を失効するまで時間がかかる。名前交換が成功しても、パスキャッシュが旧関係を表示するかもしれない。
したがって、証拠列は、認証主体、業務上の委任、選択した条件、方法応答、コミット後の読み戻し、各消費者が見た世代、利用者結果を分けるべきである。最初の緑色応答に「削除完了」と名付けると、後段を観察しないまま結論だけが強くなる。
実装試験では成功経路より境界を壊してみる。未選択プロパティだけを変え、狭い条件が成立することを確認する。選択プロパティを変え、方法全体が無変更であることを確認する。見えないプロパティには forbidden を要求する。原子変更の一部だけを失敗させ、他の変更も現れないことを確認する。成功後は外部消費者を意図的に遅らせ、どの証跡が不足するかを見る。
未読だったという事実は、競合制御には十分かもしれない。削除の正当性には十分とは限らない。プロトコルの精密さを守る最善の方法は、プロトコルが答えなかった問いを成功応答に背負わせないことである。
出典
- https://www.ietf.org/archive/id/draft-ietf-jmap-conditional-00.txt
- https://www.ietf.org/archive/id/draft-ietf-jmap-conditional-00.html
- https://www.ietf.org/archive/id/draft-ietf-jmap-conditional-00.xml
- https://datatracker.ietf.org/doc/draft-ietf-jmap-conditional/
- https://datatracker.ietf.org/doc/draft-ietf-jmap-conditional/history/
- https://datatracker.ietf.org/doc/draft-ietf-jmap-conditional/references/
- https://datatracker.ietf.org/api/v1/doc/document/draft-ietf-jmap-conditional/
- https://www.ietf.org/archive/id/draft-gondwana-jmap-conditional-00.txt
- https://www.ietf.org/archive/id/draft-ietf-jmap-filenode-14.txt
- https://www.rfc-editor.org/rfc/rfc8620.txt
- https://www.rfc-editor.org/rfc/rfc8620.html
- https://www.rfc-editor.org/rfc/rfc8620.json
- https://www.rfc-editor.org/rfc/rfc4918.txt
- https://www.rfc-editor.org/rfc/rfc9110.txt
- https://www.rfc-editor.org/rfc/rfc6902.txt
- https://www.rfc-editor.org/rfc/rfc8621.txt
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
