Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Worker を設定する

最終更新 Markdown で表示Agent セットアップ

Worker を使って、ID プロバイダーの最新の公開鍵を JWT 検証の設定に自動で反映します。

前提条件

手順

JWKs エンドポイントを手動で照会し、想定どおりの場所と形式で JWKs があることを確認します。次に、JWKs の更新を自動化する Worker と、API Shield の設定更新に使う API キーを格納する Worker Secret を作成します。その後、Worker をスケジュールして JWKs を自動更新できます。

JWKs エンドポイントを手動で照会する

ID プロバイダーの URL を確認し、curljq で鍵を取得します。URL は発行者の鍵以外も返すことがあるため、jq でレスポンスを絞り込み、鍵だけを返すことをおすすめします。JWKs に keys オブジェクトがない場合は、掲載している Worker のサンプルコードを更新する必要があります。

JWKs エンドポイントを照会するsh
curl https://<your-team-name>.cloudflareaccess.com/cdn-cgi/access/certs -s | jq .keys
[
  {
    "kid": "ca96ae653935dbfb49b4e19de600cc5f9d5c63e3ac2dbee406ed4bf0ae100cce",
    "kty": "RSA",
    "alg": "RS256",
    "use": "sig",
    "e": "AQAB",
    "n": "9dG9Ph4ffncvEA9FO9pVMfJ1dh_5mtuyiIE4ap9ScrufVPq1I34St_dhcFavKiytK7Id7gTlgQgaouoJ0I5OJ_bytgX-B7oOUQHO-nJOAMycORXN8ZNaMBPKg9nBLL_BFY0YX5HggqrkXkZjJ--R4JpB30ENS8A6hxmEJ__yGMZTE2LHZoiYj9iyGNu3s3JflAoRlmziI8LsFXwyFAJUWRZq4SkSfyrRJ89pXPxIqBn9uYBtnxWzUpWG3xKZu0JAbi9YiwFCJrSe_CarvpARoWsOldtrty5yT1yJ1PZlImlF-yuEwjOoZxeib4WSidABZH0O3pbDACo8MfxR5rghHQ"
  },
  {
    "kid": "1e590a6dcd60e3e2306c21eca19144c59d591531267a3ebde8d521f40894329d",
    "kty": "RSA",
    "alg": "RS256",
    "use": "sig",
    "e": "AQAB",
    "n": "6uj6PgDq-bPsdFjiQ6M3yaxMxBUnnYj20xtLciHNafqrygAjnZKjl8LfCO_mtZ7jxfJNCARsz0L3sF9LAtARZqcsUvYLUlNDzflwNTe8woCT7yw0Ml2ZV5BWDbc3izEQnvjlBDGWv9p5jv-D-YNExtIzZKsRKyoy7hSu5FhyxmPfiAXo8b67f0dNy8V8HZfQJ5i9VGyK4Z5xKM-FjHOrC2uIbhzUE6wDe_0M23RTCxj7ZxzXUzZzc-_EBjmZDAI3tI2zBYymO55_gw8zHrNsZ4-32YvNTjBAiTLsjvKlsvNtPTN8q3saoZJWQMSiMi8dRalgA6pUDgcNs5lB9E7tWw"
  }
]

Worker を設定する

  1. 新しい Worker を作成 します。

  2. 既存のコードをすべて置き換える形で、下記のサンプルコードを新しい Worker にコピーして貼り付けます。

  3. 現在のゾーン ID を、ご自身のゾーン ID に置き換えます。

  4. 現在のトークン検証設定 ID を、ご自身のトークン検証設定に置き換えます。

  5. 現在の ID プロバイダー URL を、ご自身の ID プロバイダーの鍵 URL に置き換えます。

  6. JWKs URL が keys 以外の JSON オブジェクトで鍵を返す場合は、fetchCredentials() 関数を更新して鍵データだけを返すようにします。

  7. Create > Deploy を選択します。

  8. Worker の設定で Variables を開き、作成した API トークンの値を持つ環境変数 CF_API_TOKEN を追加します。

  9. Worker の Triggers で、Worker に cron トリガー を割り当てます。常に最新の鍵を保ち、ID プロバイダーが即座に鍵をローテーションしてもダウンタイムを最小限にするため、短い間隔での更新をおすすめします。

    JavaScript のサンプルコードjs
    /**
    * Update Token Validation Credentials
    *
    * This example shows how a Cloudflare Workers cron trigger can be used to
    * automatically rotate a JWKs for a Token Configuration.
    *
    * To configure this Worker:
    *
    *   1. Replace `token_config_id` with the ID of the Token Config to update
    *   2. Replace `zone_id` with your Zone ID
    *   3. Replace `url` with a publicly accessible URL with the JWKs you want to use
    *   4. Create a new API Token with "Zone.API Gateway Edit" permissions and add it as a secret with the name `CF_API_TOKEN` (see https://developers.cloudflare.com/workers/configuration/secrets/)
    *
    * This worker also handles GET and POST requests:
    *   - GET will fetch and show the credentials from the provided URL (`GET https://random-worker-name-c134.example.workers.dev/`)
    *   - POST triggers an update and returns the Cloudflare API response of that update (`POST https://random-worker-name-c134.example.workers.dev/`)
    *
    * Use these to test that the Worker is properly configured.
    *
    * After setting up the worker, you can create a cron trigger to run it periodically.
    * For more information on cron triggers, refer to https://developers.cloudflare.com/workers/configuration/cron-triggers/
    *
    * Learn more about Workers at https://developers.cloudflare.com/workers/
    */
    
    var zone_id = "760549bc17c54280d6e6ae256c3dd6ae";
    var token_config_id = "91007e72-8f17-46b7-a223-5e57bd333b78";
    var url = "https://cfdata.cloudflareaccess.com/cdn-cgi/access/certs"; // JWKs
    
    /**
    * fetchCredentials fetches new Token Configuration credentials using the URL defined above.
    * This returns a JSON string with the credentials.
    *
    * Use this function to fetch and parse credentials.
    *
    * @returns {string} credentials
    */
    async function fetchCredentials() {
    	var requestOptions = {
    		method: "GET",
    		redirect: "follow",
    	};
    	const keys = await fetch(url, requestOptions)
    		.then((e) => e.json())
    		.then((e) => e.keys);
    	return JSON.stringify({ keys: keys });
    }
    
    /**
    * updateCredentials updates Token Configuration credentials using the Cloudflare API.
    * Credentials are fetched using fetchCredentials, which also does any required processing.
    *
    * @param {string} bearer Cloudflare API Bearer token with "Zone.API Gateway Edit" permissions
    * @returns {string} Cloudflare API response from the update request
    */
    async function updateCredentials(bearer) {
    	// Cloudflare API endpoint for credentials update
    	const url = `https://api.cloudflare.com/client/v4/zones/${zone_id}/token_validation/config/${token_config_id}/credentials`;
    	const init = {
    		body: await fetchCredentials(),
    		method: "PUT",
    		headers: {
    			Authorization: `Bearer ${bearer}`,
    			"content-type": "application/json;charset=UTF-8",
    		},
    	};
    	const response = await fetch(url, init);
    	return response.text();
    }
    
    // Export a default object containing event handlers
    export default {
    	/**
    	* fetch handles requests made directly to the Worker.
    	*
    	*/
    	async fetch(request, env, ctx) {
    		let responseBody = "";
    		if (request.method === "GET") {
    			responseBody = await fetchCredentials();
    		} else if (request.method === "POST") {
    			responseBody = await updateCredentials(env.CF_API_TOKEN);
    		}
    		return new Response(responseBody, {
    			headers: { "content-type": "application/json;charset=UTF-8" },
    		});
    	},
    
    	/**
    	* scheduled is the handler for cron triggers.
    	*
    	* For details, refer to https://developers.cloudflare.com/workers/configuration/cron-triggers/
    	*
    	*/
    	async scheduled(request, env, ctx) {
    		ctx.waitUntil(updateCredentials(env.CF_API_TOKEN));
    	},
    };

役に立ちましたか?