PASETOフッター — kidヒントと認証済みメタデータ
PASETOの任意フッターの仕組み、認証はされるが暗号化されない理由、kidヒントなどの一般的なパターン、フッター解析の落とし穴。
詳細な説明
PASETOの任意のフッターは、しばしば誤解される強力な機能です。これはトークンの4番目の任意セグメント(vN.purpose.payload.footer)で、署名/MACにより認証されますが、v*.local トークンであっても暗号化されることはありません。
なぜ別のフッターか:
フッターは検証器が暗号操作を実行する前に読み取る必要のあるデータを運びます。代表例は kid(鍵ID)ヒントです:署名鍵をローテーションし複数鍵を同時にサポートする必要がある場合、検証器は検証前にどの鍵を使うかを判断しなければなりません。kid を暗号化されたペイロードに入れる方法はv4.localでは機能しません(どの鍵を使うかを教えてくれるkidを読むのに鍵が必要になってしまう)。フッターに置けばこれをエレガントに解決できます。
形式:
フッターはBase64urlエンコードされた生バイトです。慣例的には小さなJSONオブジェクトです:
{ "kid": "key-2026-01" }
しかし任意のバイト列でも構いません — UUID、ドメイン名、サービス識別子、認証されるものなら何でも。
機密性ではなく認証:
フッターはPASETOの事前認証エンコーディング(PAE)に含まれるため、改ざんすると署名/タグが無効になります。しかしフッターは平文で送信されます:ワイヤー形式のトークンを読める人なら誰でもフッターを読めます。秘密をそこに入れてはいけません。ルーティング/ディスパッチ情報を入れます。
暗黙アサーション vs フッター:
PASETO v3/v4は「暗黙アサーション」を追加しました — 発行者と検証者の両方が知っているがワイヤー形式の一部ではない追加バイトです。kidをワイヤーに乗せる必要がない場合(両側とも設定から知っているため)、暗黙アサーションはフッターよりさらに安全です。
よくある落とし穴:
JSONとして書かれていないフッターをJSONパースしようとしないでください — 多くのシステムは平文文字列を使います。フッター由来のkid検索は認証されていても常に未検証入力として扱ってください。攻撃者は古い(しかし有効な)kidを持つ古いトークンをリプレイできます。
ユースケース
マルチテナントAPIが { "tenant": "acme", "kid": "acme-2026-q1" } のようなフッター値を使い、暗号チェック呼び出し前にテナント別検証鍵にディスパッチします。