User-Agent Client Hints への移行:完全な UA 文字列なしでデバイスを計測する
Chrome は User-Agent 文字列を凍結された抜け殻へと縮小しつつあります。プライバシーファーストなアナリティクスが、フィンガープリンティングに頼らず Client Hints でデバイス情報を読み取る方法を解説します。
User-Agent 文字列の緩やかな死
何十年ものあいだ、User-Agent リクエストヘッダーは、どのブラウザーか、どの OS か、モバイルかデスクトップかといった基本的な問いに答えるアナリティクスの働き手でした。同時にそれはフィンガープリンティング上の負債でもありました。Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.0.0.0 Safari/537.36 のような完全な UA 文字列は、正確なバージョン番号とプラットフォームの詳細を漏らし、他のシグナルと組み合わさることで個々の訪問者の特定を助けてしまいます。
Google の User-Agent 削減(User-Agent Reduction)の取り組みは、この文字列を何年もかけて刈り込んできました。現在の Chrome は、プラットフォームバージョンが凍結され、マイナーバージョンのセグメントがゼロに揃えられた縮小版 UA を送信します。Chrome のドキュメントによれば、その狙いは受動的に得られるエントロピーを取り除きつつ、構造化されたオプトインの代替手段を残すことにあります。それが User-Agent Client Hints(UA-CH) です。
2026 年にアナリティクスを作る立場からすると、実務上の帰結は明快です。おおまかなブラウザーファミリーを超える情報をレガシーな UA 文字列のパースで得ることは、ますます当てにならなくなり——そしてますます誤ったアプローチになっていきます。
Client Hints は実際どう動くのか
UA-CH は、デバイス情報を一つの密な文字列ではなく、個別に要求できるヒントへと分解します。低エントロピーのヒントは、既定ですべてのリクエストに付与されます。
Sec-CH-UA— ブランドと主要バージョンのリストSec-CH-UA-Mobile—?0/?1の真偽値Sec-CH-UA-Platform— 例:"macOS"
高エントロピーのヒント(完全なプラットフォームバージョン、アーキテクチャ、モデル、ビット数)は、サーバーが明示的に要求しない限り送られません。サーバーは Accept-CH レスポンスヘッダーで要求し、ブラウザーはその後のリクエストにそれらを含めることがあります。Sec- という接頭辞は、これらのヘッダーがブラウザー管理下にあり、スクリプトからは設定できないことを意味します。これは意味のある完全性の保証です。
この反転はプライバシーにとって重要です。既定の姿勢は最小限の開示です。追加のエントロピーは、すべての訪問者からひそかに収穫されるものではなく、自分のレスポンスヘッダーに記録が残る意図的な行為になります。
この転換のプライバシーファーストな読み方
Monoid はこの境界線の低エントロピー側に意図的にとどまります。アーキテクチャ・モデル・完全なプラットフォームバージョンを引き出すために Accept-CH を送ることは決してなく、受け取ったヒントを組み合わせて安定したデバイス署名を作ることもありません。それはフィンガープリンティング——デバイスの特性から識別子を再構成する行為——であり、まさに UA 削減が防ごうとしたものであり、ePrivacy 指令第 5 条 3 項やブラウザーの反フィンガープリンティング方針が端末機器上の情報へのアクセスとして扱うものだからです。
既定で送られる低エントロピーのヒントは、アナリティクスが問うべき問いには十分です。
Sec-CH-UAから得るブラウザーファミリーとメジャーバージョン。互換性とサポートの計画のために。Sec-CH-UA-Mobileから得るモバイルか非モバイルか。レイアウトと Core Web Vitals のセグメンテーションのために。Sec-CH-UA-Platformから得るプラットフォーム。OS 単位の内訳のために。
決定的に重要なのは、これらが訪問者ごとのキーではなく集計用のディメンションだという点です。数百万人の訪問者が共有する真偽値とプラットフォーム名は、それ単体では意味のある識別力を持ちません。
エッジでヒントを読む
Client Hints は通常のリクエストヘッダーなので、エッジワーカーはクライアント側スクリプトなしで読み取れます。Cloudflare では、低エントロピーのヒントは受信した Request オブジェクトに載って届きます。
export default {
async fetch(request) {
const brands = request.headers.get('Sec-CH-UA') || '';
const isMobile = request.headers.get('Sec-CH-UA-Mobile') === '?1';
const platform = request.headers.get('Sec-CH-UA-Platform') || '';
// 粗いディメンションだけを導出する。複合キーは決して永続化しない。
return new Response('ok');
}
};
ここに「ない」ものに注目してください。Accept-CH の返送はなく、高エントロピーのヒントの要求もなく、組み合わせた値のハッシュ化もありません。Sec-CH-UA の値は構造化リストなので、パースは慎重に——完全一致に依存した脆いパースを防ぐために意図的に混ぜられた「GREASE」ブランドのエントリーが含まれており、これは仕様が TLS から借りた手法です。
パイプラインで変えるべきこと
アナリティクスがいまだに完全な UA 文字列を正規表現で照合しているなら、時間とともに三つのことが壊れます。バージョン番号は .0.0.0 へと流れ、プラットフォームバージョンは凍結し、部分文字列一致に基づくモバイル判定は当てにならなくなります。移行の道筋は明快です。
- UA 文字列のパースよりも、構造化された低エントロピーのヒントを優先する。
- 縮小版 UA 文字列は、古いクライアント向けのフォールバックとしてのみ扱う。
- 「念のため」高エントロピーのヒントを要求したくなる誘惑に抗する——ヒントを一つ増やすたびに、フィンガープリンティングの面積もコンプライアンス上の露出も広がります。
より大きな教訓は、私たちが作るすべてのものと一貫しています。ブラウザーベンダーはウェブプラットフォームから受動的なエントロピーを着実に取り除いています。正しい応答は、新しい API を通じてそれを追いかけることではなく、そもそもそれを必要としない計測を設計することです。
Comments
Loading comments…