要約

  • RFC 9111は、must-understand を含むレスポンスに no-store も含めるよう勧める。新指令を知らないキャッシュは前者を無視しても、後者によって保存を控えられる。
  • 「理解」は名前や三桁の数値を認識することではない。対象ステータスコードを認識し、そのコードに規定されたキャッシュ関連の動作をすべて実装することを指す。
  • 条件を満たして no-store を無視しても、保存や再利用が自動的に許されるわけではない。メソッド、認証、共有キャッシュ、鮮度などの条件は残り、プライバシーも保証されない。

一つのレスポンス、二つの世代

Cache-Control: must-understand, no-store を受け取る二台のキャッシュを考える。

古い一台は must-understand を実装していない。Cache-Controlの拡張規則に従い、未知の指令を無視する。しかし no-store は知っているため、レスポンスを保存しない。

新しい一台は must-understand を実装している。それでも直ちに保存へ進めるわけではない。レスポンスのステータスコードを認識し、その定義にあるキャッシュ関連要件をすべて実装していることが必要だ。条件を満たしたキャッシュに対して、RFC 9111は随伴する no-store を無視するよう勧める。その後で、残りの保存条件を評価する。

この非対称性が、全世界同時更新を必要としない移行を可能にする。オリジンは経路上の全キャッシュを列挙しなくてよい。旧実装には既知の保守的な指令が届き、新実装はローカルな能力証明に基づいて別の分岐を選ぶ。

ところが手順書が must-understand だけを強調すると、仕組みは魔法の言葉に見えてしまう。未実装のキャッシュは、その言葉に従うのではなく無視するよう求められている。no-store を省けば、旧実装向けの退避路も消える。配備すべき単位は二指令の組であり、許容分岐の根拠はヘッダーの存在ではなく実装された動作である。

認識と理解の間には実装がある

RFC 9111は、キャッシュがステータスコードを「理解した」と言える条件を明示する。コードを認識し、規定されたすべてのキャッシュ関連動作を実装していることである。

三桁を構文解析できる、理由句を表示できる、未知のコードを同じクラスの一般的な応答として扱える、といった能力はより弱い。キャッシュエンジンが固有の保存規則を実行する証拠にはならない。

RFC 6585では、428、429、431、511の各レスポンスをキャッシュに保存してはならない。一方、RFC 7538の308 Permanent Redirectは、メソッド定義や明示的な制御が否定しない限り、既定でキャッシュ可能とされる。二つの文書は、ステータス固有の結果が同一ではないことを示す。

429を正しく画面に表示しながら通常どおり保存する製品は、数値を認識しても、この目的では理解していない。must-understand という文字列の解析だけを確認する試験も同様だ。

監査可能な記録には少なくとも五項目が要る。受信したステータス、認識の有無、そのキャッシュ要件の実装、指令自体の実装、そして例外適用後に残る保存・再利用条件の結果である。「対応済み」という一つのフラグでは、条件を満たした根拠が消える。

古い禁止が新しい動作を安全にする

未知のキャッシュ指令を無視する規則は、拡張によって既存ソフトウェアが壊れるのを防ぐ。RFC 9111は動作を変える拡張について、新旧の指令を併記する形を示す。新指令を知らない実装は古い動作に従い、知っている実装だけが古い要件への修正を適用する。

この場合の古い動作が no-store である。二つの指令は矛盾していない。no-store が安全側の既定値を作り、must-understand がその既定値を変更できる狭い条件を定める。

RFC 9111は両方の箇所でSHOULDを使う。レスポンスは no-store も含めるべきであり、資格を満たすキャッシュはそれを無視すべきだ。無条件のMUSTではないが、気軽な省略を意味しない。異なる設計を採るなら、旧実装がどう安全に振る舞うかを説明できなければならない。

また、規格は悪意あるキャッシュを遠隔操作できない。no-store を無視する侵害済み実装に対し、この組み合わせが秘密保持を強制することはない。

例外は自動的な保存許可ではない

no-store を無視するとは、一つの禁止を取り除くことであって、保存を命令することではない。

RFC 9111第3節の他の条件は残る。リクエストメソッドが保存を許すこと、最終ステータスであること、認証付きレスポンスや共有キャッシュの制約に従うこと、private を尊重すること、明示的な制御かステータス既定の根拠によってキャッシュ可能であることが必要になる。

保存と再利用も別の判断だ。保存された応答を次のリクエストに使うには、適切に一致し、鮮度があるか、検証に成功したか、古いまま提供できる条件が必要だ。must-understand は鮮度を作らず、検証を実行せず、利用者を混同するキャッシュキーも直さない。

ログには「例外を受理」ではなく、参照したステータス定義、能力を裏づけるバージョンと試験、両指令、残る条件、保存の有無、後日の再利用を分けて残すべきである。

登録簿は座標であって認証書ではない

IANAのキャッシュ指令登録簿は must-understandno-store を別々に掲載し、ステータスコード登録簿は各数値の定義文書を示す。共通の名前と参照先を提供する重要な基盤である。

しかし登録簿は個々のバイナリを認証しない。項目が存在することと実装が存在することは別であり、あるステータスの試験結果を将来の別コードへ一般化することもできない。

必要なのは実装側の小さな証拠束だ。エンジンとモジュールの版、参照した定義、試験した要件、その結果を結びつける。must-understand はその能力をプロトコル上で問うための分岐を作るが、証拠そのものは生成しない。

RFC 9111の変更履歴は、新しいレスポンスステータスの意味をキャッシュが理解しなければならないのは、この指令がある場合になったと説明する。オリジンは「今回は固有の規則が重要だ」と示せるが、未知の相手を適格だと宣言することはできない。

プライバシーの封印ではない

RFC 9111は no-store がプライバシーを確保する信頼できる十分な手段ではないと明記する。悪意ある、または侵害されたキャッシュは従わず、通信経路も盗聴され得る。must-understand との併記によって、この限界は消えない。

受信権限、共有キャッシュの利用者分離、転送中の暗号化、保存媒体の保護も別の制御である。ヘッダーを情報分類の印章として使えば、本来の防御が弱くなる。

本稿は製品の対応率、事故、漏えい、保存頻度を測定していない。例は公開仕様から導いた仮想的な経路である。

情報源と証拠の範囲

登録簿とErrataは調査時点のスナップショットである。製品一般の実装状況や適合性を示すものではない。