임시 자격 증명 (Temporary credentials)
임시 자격 증명은 기존 R2 API 토큰에서 파생되는 수명이 짧고 범위가 제한된 S3 자격 증명이에요. 장기 토큰과 마찬가지로 AWS Signature Version 4로 인증하지만, 세션 토큰을 포함하고 자동으로 만료돼요. 세션 토큰은 매 요청마다 X-Amz-Security-Token 헤더로 전송돼요. 모든 S3 호환 클라이언트는 이것을 표준 세션 토큰 자격 증명 필드로 노출해요.
출처: 문서
본문
장기 토큰을 발급하지 않고 접근 권한을 위임할 때 임시 자격 증명을 사용해요. 예를 들어 모바일 클라이언트에 특정 접두어에 대한 읽기 접근을 15분 동안 부여하거나, 단일 객체로 범위가 제한된 요청별 업로드 자격 증명을 발급하는 경우를 생각해 볼 수 있어요.
접근 방식 고르기
R2는 시간 제한 접근을 위한 두 가지 패턴을 지원해요. 두 패턴은 겹치지만 장단점이 달라요:
| 패턴 | 부여 내용 | 적합한 경우 |
|---|---|---|
| 임시 자격 증명(이 페이지) | 버킷과 허용 작업 집합에 범위가 제한되고, 선택적으로 특정 경로로 제한된 여러 S3 작업 | 표준 S3 클라이언트나 SDK로 범위가 제한된 세션에서 여러 작업을 수행하는 호출자 |
| Presigned URL | 단일 객체에 대한 단일 S3 작업 | S3 클라이언트 없이 단일 객체에 직접 HTTP 접근을 부여할 때(예: 브라우저 업로드, 공유 가능한 다운로드 링크) |
임시 자격 증명 생성
임시 자격 증명 API로
임시 자격 증명 API는 상위(parent) API 토큰, 버킷 이름, 선택적 스코프 파라미터를 받아 새 Access Key ID, Secret Access Key, 세션 토큰을 반환해요. Cloudflare가 사용자 대신 세션 토큰을 서명해요.
서명 흐름을 Cloudflare가 관리하길 원할 때 이 방법을 사용해요.
실행 가능한 안내는 임시 자격 증명으로 R2 인증하기를 참고해 주세요.
로컬에서 (클라이언트 측 서명)
상위 API 토큰의 Secret Access Key로 JWT를 서명하고 그것을 세션 토큰으로 사용해서 임시 자격 증명을 로컬에서 생성할 수도 있어요.
이 방법은 다음 경우에 사용해요:
- 수명이 짧은 자격 증명을 많이 발급하면서 API 호출당 지연을 피하고 싶을 때
- Cloudflare API에 접근할 수 없는 환경에서 자격 증명을 발급해야 할 때
- S3 작업으로 자격 증명 범위를 제한하고 싶을 때(작업별 범위 참고) — 현재 이 기능은 로컬 서명에서만 지원돼요.
서명은 세 단계로 진행돼요:
- 버킷과 접근 범위를 식별하는 JWT 페이로드를 만든다.
- 상위 Secret Access Key로 HS256을 사용해 JWT를 서명한다.
- 서명된 JWT의 SHA-256 hex 다이제스트를 계산해서 임시 Secret Access Key를 파생한다. 세션 토큰은
base64("jwt/" + <signed-jwt>)로 인코딩한다.
상위 Access Key ID는 임시 Access Key ID로 재사용돼요.
완전하고 실행 가능한 예시는 임시 자격 증명으로 R2 인증하기에서 볼 수 있어요.
자격 증명의 범위
모든 임시 자격 증명은 단일 버킷과 허용 작업 집합에 묶여 있어요. 선택적으로 버킷 안의 특정 경로로 자격 증명을 더 제한할 수 있어요.
임시 자격 증명은 상위 토큰의 권한을 초과할 수 없어요.
버킷
임시 자격 증명은 이름으로 식별되는 정확히 하나의 버킷에 묶여 있어요. 단일 자격 증명 안에서의 버킷 간 접근은 지원되지 않아요.
허용 작업
scope(API에는 permission으로 전달) 또는 actions로 허용 작업을 지정해요. 둘 중 적어도 하나는 제공해야 해요.
Scope
scope는 미리 정의된 작업 범주예요. 전체 정의는 권한을 참고해 주세요.
| Scope | 허용 내용 |
|---|---|
object-read-only |
버킷의 객체를 읽고 나열해요. |
object-read-write |
버킷의 객체를 읽고, 쓰고, 나열해요. |
admin-read-only |
객체를 읽고 나열하고, 버킷 구성을 보고, 데이터 카탈로그에서 읽어요. |
admin-read-write |
객체를 읽고, 쓰고, 나열하고, 버킷 구성을 편집하고, 데이터 카탈로그를 읽고 써요. |
Actions
actions는 허용되는 S3 작업의 명시적 목록이에요.
예를 들어 actions: ["GetObject", "HeadObject"]는 개별 객체에 대한 읽기를 허용하지만 ListObjectsV2는 거부해요. 더 넓은 object-read-only 스코프는 목록을 허용하지만 말이죠.
참고
actions는 현재 로컬 서명에서만 지원돼요. 임시 자격 증명 API에서의 지원은 곧 제공될 예정이에요.
유효한 작업:
| 범주 | 작업 |
|---|---|
| 읽기 | HeadObject, GetObject, GetBucketLocation, ListObjectsV1, ListObjectsV2, ListMultipartUploads, ListParts |
| 쓰기 | PutObject, DeleteObject, DeleteObjects, CopyObject |
| Multipart | CreateMultipartUpload, UploadPart, UploadPartCopy, AbortMultipartUpload, CompleteMultipartUpload |
경로 (Paths)
버킷 안의 특정 접두어나 객체로 접근을 제한해요. 이 필드를 생략하면 허용 작업에 따라 버킷 전체에 대한 접근이 부여돼요.
임시 자격 증명 API: 요청 본문의 최상위 필드로 prefixes와 objects를 전달해요.
{
"prefixes": ["uploads/user-123/"],
"objects": ["shared/manifest.json"]
}
로컬 서명: JWT 페이로드에 paths.prefixPaths와 paths.objectPaths를 설정해요.
{
"paths": {
"prefixPaths": ["uploads/user-123/"],
"objectPaths": ["shared/manifest.json"]
}
}
prefixes/prefixPaths: 나열된 접두어 중 하나로 시작하는 키.objects/objectPaths: 정확한 객체 키.
임시 자격 증명 사용
세션 토큰을 지원하는 모든 S3 호환 클라이언트는 R2 임시 자격 증명을 받아들여요. 세 값(Access Key ID, Secret Access Key, 세션 토큰)을 모두 클라이언트의 표준 자격 증명 필드로 전달해요.
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",
});
const response = await client.fetch(`${R2_URL}/my-bucket/image.png`);
import boto3
s3 = boto3.client(
service_name="s3",
endpoint_url="https://<ACCOUNT_ID>.r2.cloudflarestorage.com",
aws_access_key_id="<ACCESS_KEY_ID>",
aws_secret_access_key="<SECRET_ACCESS_KEY>",
aws_session_token="<SESSION_TOKEN>",
region_name="auto",
)
대부분의 AWS SDK와 AWS CLI는 기본적으로 다음 환경 변수에서 자격 증명을 읽어요:
AWS_ACCESS_KEY_ID=<ACCESS_KEY_ID>
AWS_SECRET_ACCESS_KEY=<SECRET_ACCESS_KEY>
AWS_SESSION_TOKEN=<SESSION_TOKEN>
보안 고려사항
임시 자격 증명은 bearer 토큰처럼 취급해요. 세 값을 모두 가진 사람은 누구든 자격 증명이 만료될 때까지 허용된 작업을 수행할 수 있어요.
- 가능한 한 좁게 범위를 제한해요. 경로와 권한 스코프를 설정해서 자격 증명이 호출자가 필요한 것만 수행할 수 있게 해요.
- 짧은 TTL을 사용해요.
ttlSeconds를 사용 사례에 맞는 가장 짧은 값으로 설정해요. 15분 동안 유효한 자격 증명은 하루 동안 유효한 것보다 폭발 반경(blast radius)이 작아요. - 임시 자격 증명은 상위를 초과할 수 없어요. 상위 API 토큰을 해지하면 그 토큰에서 파생된 모든 임시 자격 증명도 즉시 작동을 멈춰요.
- 상위 Secret Access Key를 클라이언트에 절대 배포하지 마세요. 로컬 서명은 신뢰할 수 있는 환경(백엔드나 Worker 등)에서 이루어져야 해요.
관련 리소스
임시 자격 증명으로 R2 인증하기
임시 자격 증명 API와 로컬 JWT 서명 모두에 대한 end-to-end 예시예요.
Presigned URL
자격 증명을 발급하지 않고 특정 객체에 대한 단일 작업 접근을 부여해요.
R2 API 토큰
임시 자격 증명이 파생되는 상위 토큰을 만들어요.
오류 코드
R2가 반환하는 인증 및 권한 부여 오류 코드예요.
더 알아보기 (Learn more)
- Presigned URL — 단일 객체에 대한 시간 제한 접근
- R2 API 토큰 — 임시 자격 증명의 상위 토큰 만들기
- 임시 자격 증명으로 R2 인증하기 — 실행 예시