要約

  • draft-ietf-jmap-object-history-00 は Foo/get で過去版と削除済み版を取得可能にするが、短時間の更新を一つにまとめ、版を任意の順序で間引き、容量不足時に履歴を通知なく捨てることも認めている。
  • 返されたスナップショットは復旧に役立つ。しかし、誰が、どの要求を、どの権限で実行し、その後何が起きたかは示さない。hasMoreHistory: false さえ完全性の証明にはならない。

アドレス帳から消した電話番号を昨日の状態に戻せる。削除直前のメールを表示できる。これは実用的な能力だ。操作ミスを元に戻し、クライアントごとに別のバックアップ方式を作る必要を減らす。

ところが、同じオブジェクト ID、版番号、置換時刻が並ぶ画面は、仕様が約束していない確実性まで感じさせる。そこには変更者も、操作を送ったクライアントも、適用された認可規則も、その後の処理結果も記録されていない。

9月15日にワーキンググループ名で提出された JMAP Object History の重要な境界はここにある。過去の状態を問い合わせ可能にする提案であり、復旧用の保存領域を監査台帳へ変える提案ではない。

返されるのは保存状態であって、出来事ではない

JMAP の中核は、オブジェクト型ごとに Foo/get、Foo/changes、Foo/set、Foo/query、Foo/queryChanges というメソッド群を持つ。現行状態の同期は既に設計の一部であり、Foo/changes は状態間で変わった ID を知らせる。ただし変更前の値そのものは返さない。

新しい urn:ietf:params:jmap:object-history capability は Foo/get を拡張する。includeReplaced: true なら現行オブジェクトと一緒に置換済みの版を含め、includeDestroyed: true なら存在しなくなったオブジェクトも要求できる。両方を指定すれば、サーバーに残る削除済みオブジェクトの全版を返せる。

各版のオブジェクト ID は同じである。objectHistory.version は一つの応答内で版を並べ、objectHistory.replaced は更新または削除によってその表現が置き換わった時刻を示す。null なら現行版だ。

これらは状態の座標であって、イベントの来歴ではない。置換時刻はその版が作られた時刻ではない。版番号はトランザクション ID ではない。実行者、セッション、端末、要求本文、認可ポリシー、承認、動機、通知、外部結果のいずれも特定しない。

隣り合う二つのスナップショットから値の差は計算できる。しかし、その差が一回の原子的な操作によって生じたとは証明できない。

抜けた途中版は、最初から存在しなかったかもしれない

提案は、短時間に続いた複数の更新を一つの版としてまとめることを明示的に許す。電話番号を短時間に三度直しても、履歴に残るのはその前と後だけかもしれない。個々の操作ごとに記録が作られるわけではない。

古い版を削除する順序もサーバーが決められる。版番号に穴があっても正しく、クライアントは履歴が連続または完全だと仮定してはならない。欠落には少なくとも二つの理由がある。独立した版が作られなかったか、作られた後に消されたかだ。応答だけでは区別できない。

番号の安定性も限定的である。サーバーは一貫した番号を返すべきだが、クライアントは要求をまたいでそれに依存してはならない。主目的は同一応答内で一つのオブジェクトの版を順序づけることだ。永続的な監査イベント ID として使えば、仕様が保証を避けた性質を勝手に補うことになる。

この柔軟性は保存コストを抑える。一方で「残っている履歴」と「起きたことの全て」を同じものとして扱えなくする。

hasMoreHistory は取得の手掛かりであり、完全性証明ではない

historyLimit は総エントリー数を制限し、最近の版から返すよう指定する。要求した ID のどれかで上限に達すると、hasMoreHistory: true はさらに古い保存版がその時点で存在することを示す。複数オブジェクトの応答では、どの ID に続きがあるかは分からず、個別に問い合わせる必要がある。

true は一時的だ。次の要求までに古いエントリーが削除され得ると草案は警告する。ある瞬間の取得可能性を表すだけで、データを予約してはいない。

false はさらに弱い。通常は要求した ID の保存履歴を全て返したという意味だが、追加履歴の有無を効率よく判定できない場合、実際には残っていても false を返せる。全変更が記録されたとも、削除が一度もなかったとも、残存する全表現を発見したとも意味しない。

画面が false を「完全な監査履歴」と表示すれば、プロトコルの意味を逆転させる。正確な説明は「この応答では追加の保存履歴が報告されなかった」である。

null の保持期間は永久保存ではない

capability を告知するアカウントは maxHistoryDuration を公開する。数値なら、置換後その秒数を超えた版は廃棄されている可能性がある。null は時間に基づく上限を設けていないという意味だ。

永続性の保証ではない。セキュリティ節は保存容量の圧迫を認め、上限に達したとき履歴を黙って廃棄できるとする。時間は保持制御の一つであり、総容量は別の制御だ。履歴インターフェースを対応済みとしていても、過去版を一つも保管しないオブジェクト型もあり得る。その場合も現行オブジェクトには objectHistory が付き、全てを版1として返せる。

したがって capability が証明するのは問い合わせ口の存在であって、証拠保管の最低量ではない。調達やコンプライアンスは、最低保持期間、削除通知、エクスポート、完全性、リーガルホールドを別に定義する必要がある。

復旧と説明責任には別々の受領証が要る

復旧用途にはよく適した形だ。クライアントは Email/changes で削除された ID を知り、それを Email/get に渡して includeDestroyed を要求し、削除直前の内容を表示できる。削除済みオブジェクトを現行扱いせずに、利用者の復元を助けられる。

しかし、責任を確定するには足りない。必要なのは、認証済みの実行者とセッション、送信元クライアントと端末、正確な変更要求、条件付き状態トークン、適用された認可ポリシーの版と判断、サーバーが受理したトランザクション、変更前後のハッシュ、永続イベント ID、通知配信、観測結果を結ぶ受領証である。

Object History は変更前または変更後の表現を提供できる。それ以外の欄は埋めない。所有者から実行者を推測するのは危険だ。状態が変わったことから権限を推測すれば、適用ポリシーが抜ける。保存値から外部効果を推測すれば、制御面での受理と実行・観測を混同する。

説明責任が必要なら、復旧スナップショットを追記専用の監査面と結合すべきだ。一つの保存領域に相反する二つの契約を装わせてはならない。

過去版への権利は現在の権利だけでは決まらない

履歴は認可にも難題を持ち込む。現在のオブジェクトを読めない利用者に、その履歴を読ませてはならない。さらに権限が時期によって変わった場合、その要求者が当時読む権利を持っていた版だけを返す必要がある。

この規則は、新たに権限を得た人が権限取得前の値を見ることを防ぐ。同時に、サーバーは過去の認可文脈を十分に保持しなければならない。現在のアクセス制御リストだけでは正しい判断を再現できないことがある。

JMAP Sharing は、主体、意図された共有権限、実効アクセスを既に分けている。Object History は時間軸を加える。旧版を読む権利は現在の shareWith マップではなく、過去の権利にも依存する。版が返されたことはサーバーが開示を決めた証拠ではあるが、別途記録がなければ、その認可判断の完全な説明にはならない。

正しい履歴が意図的に不完全な場合もある

古いオブジェクトは、利用者や管理者が消そうとした情報を残し得る。連絡先から削除した電話番号が履歴には見える。このため草案は、プライバシーや法令対応のため、特定オブジェクトの履歴を管理者が消せる機能を推奨する。

これは隠すべき欠陥ではない。復旧、説明責任、消去、保存コストは異なる方向へ働く。データ区分ごとに、どの目的を優先するか、誰が消去を承認できるか、改ざん耐性のある消去受領証を残すか、内容消去後もどの独立監査事実を保持するかを決める必要がある。

削除を前提にした仕組みの上で「不変の履歴」をうたうのは危険だ。法科学的台帳でないから復旧も止めるという判断も誤りだ。保存領域を分け、その境界を公開するべきである。

ワーキンググループ採択は運用開始ではない

9月の文書は3月の個人草案とほぼ同じで、プロトコル本文に新しい実装証拠は加わっていない。意味のある差は、JMAP ワーキンググループ名の文書になったことだ。

Datatracker は WG Document、段階を I-D Exists としている。担当 Area Director、shepherd、telechat は記載されていない。概要欄の intended status は空白だが、草案本文のヘッダーは Standards Track とする。現時点では Internet-Draft であって RFC ではなく、凍結した資料は特定サービスの稼働実装や保持方針を立証しない。

この成熟度の境界も運用上重要だ。レジストリの登録は実装間の語彙をそろえる。どの版が記録され、統合され、削除されたか、誰が認可され、復旧が成功したかを示すのは、動いている系の証拠だけである。

出典