Skip to content

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

一時認証情報で R2 に認証する

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

次の例では、Temporary Credentials API とローカルのクライアント側署名の両方で R2 の 一時認証情報 を生成し、得られた認証情報を S3 クライアントで使う方法を示します。

前提条件

  • 委譲する予定の権限以上を持つ親の R2 API トークン。親の認証情報をクライアントに同梱しないでください。
  • Cloudflare の アカウント ID
  • セッショントークンに対応する S3 クライアント。以降の例では aws4fetch を使います。

Temporary Credentials API で生成する

信頼できるサーバーから Temporary Credentials API を呼び出し、返された認証情報を任意の S3 クライアントで使います。

curl https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/r2/temp-access-credentials \
  --header "Authorization: Bearer <PARENT_API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "bucket": "my-bucket",
    "parentAccessKeyId": "<PARENT_ACCESS_KEY_ID>",
    "permission": "object-read-only",
    "ttlSeconds": 900,
    "objects": ["reports/2026-q1.pdf"]
  }'

レスポンスは、認証情報を result オブジェクトで包みます。

{
  "result": {
    "accessKeyId": "<accessKeyId>",
    "secretAccessKey": "<secretAccessKey>",
    "sessionToken": "<sessionToken>"
  },
  "errors": [],
  "messages": [],
  "success": true
}

ローカルで生成する(クライアント側署名)

この例では、JWT の署名に jose、署名付きリクエストの発行に aws4fetch を使います。

npm i jose aws4fetch

次のヘルパーは、親のシークレットアクセスキーで JWT に署名し、一時的なシークレットアクセスキーとセッショントークンを導出します。

temp-credentials.tsts
import { SignJWT } from "jose";

type R2Scope =
  | "object-read-only"
  | "object-read-write"
  | "admin-read-only"
  | "admin-read-write";

export interface TempCredentialOptions {
  scope: R2Scope;
  // Optional: narrow the credential to specific S3 operations.
  actions?: string[];
  // Time-to-live in seconds. Defaults to 1 hour.
  ttlSeconds?: number;
  // Optional: restrict access to specific prefixes or objects.
  paths?: { prefixPaths?: string[]; objectPaths?: string[] };
}

export async function createTempCredentials(
  endpoint: string,
  accountId: string,
  parentAccessKeyId: string,
  parentSecretAccessKey: string,
  bucket: string,
  opts: TempCredentialOptions,
): Promise<{
  accessKeyId: string;
  secretAccessKey: string;
  sessionToken: string;
}> {
  const ttl = opts.ttlSeconds ?? 3600;

  const claims: Record<string, unknown> = {
    bucket,
    scope: opts.scope,
  };

  if (opts.actions !== undefined && opts.actions.length > 0) {
    claims.actions = opts.actions;
  }

  if (opts.paths !== undefined) {
    claims.paths = {
      prefixPaths: opts.paths.prefixPaths ?? [],
      objectPaths: opts.paths.objectPaths ?? [],
    };
  }

  // Sign the JWT with the parent secret access key. R2 validates this signature.
  const jwt = await new SignJWT(claims)
    .setProtectedHeader({ alg: "HS256", typ: "JWT" })
    .setSubject(accountId)
    .setIssuer(parentAccessKeyId)
    .setAudience(new URL(endpoint).host)
    .setIssuedAt()
    .setExpirationTime(`${ttl}s`)
    .sign(new TextEncoder().encode(parentSecretAccessKey));

  // The temporary secret access key is the SHA-256 hex digest of the signed JWT.
  const digest = await crypto.subtle.digest(
    "SHA-256",
    new TextEncoder().encode(jwt),
  );
  const secretAccessKey = Array.from(new Uint8Array(digest))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");

  return {
    // Reuse the parent access key ID as the temporary access key ID.
    accessKeyId: parentAccessKeyId,
    secretAccessKey,
    // The session token is base64("jwt/" + signed JWT).
    sessionToken: btoa(`jwt/${jwt}`),
  };
}

次の例は、15 分間有効で、data/ プレフィックス配下の GetObjectHeadObject だけが可能な認証情報を返します。

import { createTempCredentials } from "./temp-credentials";

const R2_URL = `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`;

const creds = await createTempCredentials(
  R2_URL,
  ACCOUNT_ID,
  PARENT_ACCESS_KEY_ID,
  PARENT_SECRET_ACCESS_KEY,
  "my-bucket",
  {
    scope: "object-read-only",
    actions: ["GetObject", "HeadObject"],
    ttlSeconds: 900,
    paths: { prefixPaths: ["data/"] },
  },
);

認証情報を使う

一時認証情報を取得したあとの使い方は、生成方法に関係なく同じです。3 つの値を S3 クライアントに渡し、リクエストを発行します。次の例では、data/ プレフィックスにスコープした認証情報を使い、許可されるリクエストと拒否されるリクエストを示します。

import { AwsClient } from "aws4fetch";

const R2_URL = `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`;

const client = new AwsClient({
  accessKeyId: ACCESS_KEY_ID,
  secretAccessKey: SECRET_ACCESS_KEY,
  sessionToken: SESSION_TOKEN,
  service: "s3",
});

// Allowed: object under the data/ prefix.
const ok = await client.fetch(`${R2_URL}/my-bucket/data/file.bin`);
console.log(ok.status); // 200

// Rejected with 403 AccessDenied because the object is outside the data/ prefix.
const denied = await client.fetch(`${R2_URL}/my-bucket/other/file.bin`);
console.log(denied.status); // 403

関連リソース

役に立ちましたか?