실제 R2 1단계 통합 검증
목적
이 테스트는 mock 없이 FileStore API와 실제 Cloudflare R2 Backend를 대상으로 다음 전체 흐름을 검증한다.
upload-session → signed PUT → complete(ACTIVE) → read-url 다운로드 → metadata-only soft delete → 삭제된 파일 read-url 거부스크립트는 테스트용 임시 파일을 생성하고, 성공 시 metadata-only soft delete한다. 중간 실패 시에도 생성된 파일을 정리하려고 시도하지만, 현재 DELETE API는 R2 원본 객체를 보존한다.
사전 설정
- FileStore 관리자 UI에서 Cloudflare R2 Backend를 등록한다.
- Backend의
secretRef가 FileStore 서버의 비밀 환경변수 namespace와 일치하는지 확인한다. process-centerconsumer 정책을 등록한다.- 정책에 R2 Backend를 연결하고 write/read를 활성화한다.
text/plainMIME type과 테스트 파일 크기를 허용한다.- 실제 R2 자격증명은 FileStore 서버 환경변수 또는 비밀관리 시스템에만 설정한다.
- 서비스 토큰, 정책 UUID, 조직 식별자를 준비한다. PortalConsole를 사용하는 경우 조직 식별자는
/api/directory/v1/departments응답의data[].id값이며dept_...형식일 수 있다.
실행
cd /home/ubuntu/FileStore
set -a
. .env.r2.integration.local
set +a
node scripts/verify-r2-flow.mjs.env.r2.integration.local은 저장소에 커밋하지 않는다. .env.r2.integration.example을 복사해 로컬 파일을 만든다.
cp .env.r2.integration.example .env.r2.integration.local
chmod 600 .env.r2.integration.localFILE_STORE_R2_TEST_CONFIRM=YES가 없으면 스크립트는 실행되지 않는다. 이 값은 테스트가 실제로 파일을 만들고 삭제한다는 것을 명시적으로 확인하기 위한 안전장치다.
기대 출력
PASS upload-session assetId=...
PASS signed upload
PASS complete status=ACTIVE
PASS read-url download content matches
PASS soft delete
PASS deleted asset read-url
R2 integration flow passed실패 시 확인 순서
| 증상 | 확인 항목 |
|---|---|
HTTP 401 | 서비스 토큰, Bearer 인증, FileStore 서버 설정 |
HTTP 403 | consumer 정책, 서비스 토큰 권한, 정책 활성화 상태 |
HTTP 404 | Base URL, API 경로, assetId, 정책 연결 |
| upload-session 정책 오류 | mapping UUID, consumerId, PortalConsole 조직 식별자, MIME 정책 |
| signed PUT 오류 | R2 credential namespace, Bucket, Endpoint, write 권한 |
| complete 오류 | 실제 전송 바이트 수, SHA-256 checksum |
| read-url 오류 | read 권한, 파일 상태, Backend 연결 |
| 삭제 후 read-url 성공 | FileStore lifecycle 또는 삭제 정책 구현 확인 |
DELETE API는 DELETED 상태와 감사 로그만 기록하며 R2 객체를 즉시 삭제하지 않는다. 원본 객체 삭제는 보존 기간과 legal hold를 확인하는 별도 cleanup job의 책임이다.
cleanup은 관리자 권한(storage:write)으로 다음 API를 호출해 수동 실행할 수 있다.
POST /api/file-store/v1/admin/cleanup
{ "limit": 100, "actorSubject": "filestore-cleanup-admin" }운영 환경에서 주기 실행하려면 FILE_STORE_CLEANUP_INTERVAL_MS를 60,000 이상으로 설정한다. 실행 대상은 DELETED 상태이면서 objectDeletedAt이 없고, 보존 기간이 끝났으며, legalHold=false인 파일뿐이다. 성공 시 CLEANUP_DELETED, 실패 시 CLEANUP_FAILED 감사 이벤트가 기록되고 실패 대상은 다음 실행에서 재시도된다.
실제 R2 자격증명과 서비스 토큰은 출력, 커밋, 브라우저 응답에 포함하지 않는다.