要約

  • HTTPのVaryは、オリジンによる表現の選択に影響した可能性があるリクエストフィールドを示す。キャッシュが再検証なしで保存済み応答を使うには、その指定フィールドを照合しなければならない。
  • Varyは、実装されたキャッシュキー、アプリケーションが使う全選択条件、テナントや認可の分離、実際に配信された表現のダイジェストを証明するものではない。

共通のURIからテナント別の設定を配る架空のサービスを考える。テナントAがリソースを要求すると、オリジンはA向けのブランド情報と Vary: Accept-Encoding を返す。保証ダッシュボードは有効なVaryを見て、キャッシュ分離を正常と判定する。その後、同じコンテンツ符号化を選んだテナントBに、エッジキャッシュがAのバイト列を返してしまう。

ここでVaryが壊れたわけではない。Varyは、その応答についてオリジンが宣言した選択軸を表した。問題は、限定された宣言を、それが約束していない広い境界の証明に読み替えたことにある。

Varyが実際に表すもの

RFC 9110はVaryを、メソッドと対象URI以外で、オリジンサーバーの応答内容選択に影響した可能性があるリクエスト部分を記述する応答フィールドと定義する。値にフィールド名が並ぶ場合、それらが選択フィールドになる。つまり、これは一つの応答に対するオリジン側の選択入力の宣言である。

目的は二つある。第一に、指定フィールドが後続リクエストと一致しない限り、またはオリジンが再利用を検証しない限り、キャッシュによる再利用を認めない。第二に、利用者側へコンテンツネゴシエーションが行われ、別の値なら別の表現が返り得ると知らせる。どちらも、後で応答を保存・配信するキャッシュからの実測情報ではない。

ワイルドカードは境界をさらに明確にする。Vary: * は、クライアントのネットワークアドレスなど、名前を挙げたフィールド以外の要素が選択に影響した可能性を示す。受信者は後続リクエストへの適合性をフィールドだけでは判断できず、オリジンへ転送する必要がある。プロキシはこのワイルドカードを生成してはならない。これは不確実性の宣言であり、万能な分離スイッチではない。

実際のキャッシュキーは別の事実

RFC 9111は、保存済み応答を選ぶためにキャッシュが使う情報をキャッシュキーと呼ぶ。最低限、リクエストメソッドと対象URIが含まれる。キャッシュはVaryで指定されたフィールドや、それ以外の情報を追加できる。

保存済み応答にVaryがある場合、元の保存を生んだリクエストと指定フィールドがすべて一致しなければ、再検証なしで再利用してはならない。正規化はフィールド仕様上、意味が同じ場合にだけ許される。元のリクエストで指定フィールドが存在しなかったなら、後続リクエストでも存在しない場合だけ一致する。Vary: * を含む保存済み応答は常に不一致となる。

これは強い照合規則だが、四つの運用上の問いには答えない。配備されたキャッシュは本当にフィールドを解釈・適用したか。中間装置は削除や書き換えをしなかったか。アプリケーションは、認証後に解決されるテナント情報など、宣言していない入力で内容を選ばなかったか。配信されたオブジェクトは、キャッシュが選んだと考えた変種と同一か。Varyは関連証拠だが、単独の回答ではない。

分離は見えない軸にも依存する

アプリケーションは、認証済みアカウント、テナント対応、機能コホート、ポリシー世代、法域、エッジ設定の版によって表現を変えることがある。一部はリクエストフィールドに現れ、別のものはサーバー側状態から決まる。メッセージ外の要素が選択に影響する場合、RFC 9110は Vary: * を許すが、これは再利用可能な私的パーティションを記述するのではなく、通常の再利用を止める。

したがって、Varyが存在することや、言語と符号化だけが並ぶことからテナント分離を推測できない。構文的に正しいフィールドでも、実際の選択ロジックには不足し得る。逆に、キャッシュがVaryに現れないプライバシー用の追加分割を行うこともある。応答だけからはどちらも分からない。

これは鮮度とも別問題である。新鮮な変種でもキーの軸が足りなければ誤った変種になり得る。古くても正しい区画に収まっていることはある。再検証はHTTPの検証子に基づく再利用を確認できるが、正しいテナント区画に入ったことまでは示さない。鮮度、検証、認可、変種選択は関連するが同一ではない。

主張を支える証拠

配備が表現を正しく隔離したと主張するには、プロトコル上の宣言とキャッシュの実動作を結ぶ。キャッシュの個体またはコホートと設定版、メソッドとURI、キャッシュが受け取った正確なVary、各指定フィールドの正規化値と欠落状態、アプリケーションの全選択軸、判断時のテナントと認可、ヒット・ミス・再検証の判断、保存オブジェクトの識別子、配信バイトのダイジェストを残す。

ここでいう「変種選択レシート」は、証拠を結ぶための編集上の提案であり、IETFが定義するプロトコル要素ではない。狭い標準信号を広い運用保証に拡大しないためのものだ。観測点も必要である。オリジン、中間キャッシュ、配信エッジでは見えるフィールドと適用設定が異なり得るからだ。

Varyは、その範囲を守るからこそ有用である。宣言されたネゴシエーションを可視化し、準拠キャッシュに具体的な照合義務を与える。宣言を実装、分離、結果の証明として扱った瞬間に保証上の誤りが始まる。予定した選択軸はヘッダーで示せる。正しい表現が正しい境界内に残ったことは、設定と配信の結合証拠でしか示せない。

出典