このガイドでは、Cloudflare が運用するデプロイからトークンを取得する手順を説明します。この時点で、次のコンポーネントはすでに共同で構築・プロビジョニング済みです。このガイドで、デプロイがトークンを発行し、引き換えられることをエンドツーエンドで確認します。
Privacy Pass は現時点ではセルフサーブ製品ではありません。本番デプロイは Cloudflare とのマネージドな取り組みです。セットアップなしで Privacy Pass の動作だけを見たい場合は、はじめに を参照してください。
アクセスの申請と Issuer 設定の受け取りは お問い合わせ ↗ ください。
Cloudflare がプロビジョニングするもの:
- Issuer エンドポイント(ここでは
https://your-issuer.example.comとします)。公開され、RFC 9578 に準拠した Issuer が動きます。 /.well-known/private-token-issuer-directoryの公開ディレクトリエンドポイント。/token-requestエンドポイント。
自分で運用するか、用意しておくもの:
- 動作する Attester。クレームを検証し、Client の検証後にブラインド化したトークンリクエストを Issuer へプロキシするサービスです。Cloudflare の Issuer デプロイでは、Client が Issuer に直接接続することはありません。役割を分けるため、通常は Attester を自分で運用しますが、構築は Cloudflare が支援できます。Cloudflare Workers 向けの実装は cloudflare/privacypass-attester ↗ を参照してください。
- Origin(Client がアクセスしようとしている Web サービス、アプリケーション、またはウェブサイト)。Issuer の公開鍵に対してトークンを検証するよう設定します(またはエッジでの Cloudflare による引き換え)。
- Attester が Issuer への認証に使う mTLS クライアント証明書。
- 発行プロトコルを実行するための クライアントライブラリ。ライブラリの選択肢には TypeScript、Go、Rust があります。
使っているスタック向けの Privacy Pass ライブラリで Client を実装します。
- TypeScript — @cloudflare/privacypass-ts ↗
- Go — cloudflare/pat-go ↗(リファレンス実装。実験および相互運用向け)
- Rust — raphaelrobert/privacypass ↗(独立した監査は未実施)
各 Issuer は、標準のディレクトリエンドポイントで設定を公開します。このエンドポイントは公開されているため、取得して Issuer に到達できることと公開鍵を確認できます。
curl https://your-issuer.example.com/.well-known/private-token-issuer-directoryレスポンスには、token-request エンドポイントと Issuer の公開鍵が並びます。トークンタイプ 2 は Blind RSA です。
{
"issuer-request-uri": "/token-request",
"token-keys": [
{
"token-type": 2,
"token-key": "<base64url-encoded public key>",
"not-before": 1700000000
}
]
}Origin は、引き換えられたトークンをこれらの鍵で検証します。
このデプロイでは、Client は Issuer に直接接続しません。トークンの取得は、4 つの役割をまたぐラウンドトリップです。
- Origin が
WWW-Authenticateチャレンジを返します。 - Client が 自分の Attester とアテステーションを完了し、ブラインド化したトークンリクエストを送ります。
- Attester が Client を検証し、Issuer へ認証したうえで(例: mTLS)、リクエストを Issuer の
/token-requestエンドポイントへプロキシします。 - Issuer がブラインド化したリクエストに署名して返します。Client はアンブラインドして最終トークンを復元し、Origin で引き換えます。
Origin Client Attester Issuer
│ │ │ │
│- TokenChallenge ─>│ │ │
│ │<=== Attestation ==>│ │
│ │ │── TokenRequest ─>│
│ │ │<─ TokenResponse ─│
│ │<── TokenResponse ──│ │
│<─ Request+Token -─│ [finalize token] │ │
│────- 200 OK ────->│ │ │この例では TypeScript ライブラリを使い、Client がブラインド化したトークンリクエストを組み立て、自分の Attester へ送ります。Attester が Issuer へプロキシし、署名済みレスポンスを返します。
import { publicVerif } from '@cloudflare/privacypass-ts';
const { BlindRSAMode, Client } = publicVerif;
// Declare your own sendToAttester transport — see the note below.
declare function sendToAttester(tokenRequest: Uint8Array): Promise<Uint8Array>;
// `tokenChallenge` comes from the Origin's WWW-Authenticate header.
// `issuerPublicKey` is the issuer's public key bytes (from the directory in Step 1).
const client = new Client(BlindRSAMode.PSS);
const tokenRequest = await client.createTokenRequest(tokenChallenge, issuerPublicKey);
// Send the blinded request to your Attester. It verifies the client, proxies the
// request to the issuer, and returns the issuer's signed token response.
const tokenResponseBytes = await sendToAttester(tokenRequest.serialize());
// Deserialize and unblind to recover the finalized token.
const tokenResponse = client.deserializeTokenResponse(tokenResponseBytes);
const token = await client.finalize(tokenResponse);Client は、トークンを Authorization ヘッダーで Origin に送り、引き換えます。Origin(またはエッジの Cloudflare。デプロイモデル を参照)は Issuer の公開鍵で署名を検証し、200 OK を返します。
発行と引き換えがエンドツーエンドで動いていることは、次の 2 つの合図で確認できます。
- ディレクトリエンドポイントが Issuer の
token-keysを返す。 - 引き換えられたトークンが Issuer の公開鍵で検証され、Origin が
200 OKを返す。
ディレクトリエンドポイントに到達できるかは、Privacy Pass デモツール ↗ で Issuer のディレクトリを取得して確認できます。
- Privacy Pass Protocol — 4 つの役割、発行と引き換えの流れ、トークンを作るブラインド署名。
- デプロイモデル — 各役割の運用者とデプロイモデル。
- cloudflare/privacypass-attester ↗ — Attester のリファレンス実装(Turnstile アテステーション、トークンリクエストを Issuer へプロキシ)。
- cloudflare/privacypass-issuer ↗ — Issuer のリファレンス実装(Workers、鍵のローテーション)。