Skip to content

FileStore 완성도·보안 후속 개발 인수인계서 ​

작성일: 2026-09-06
작성자: Manus AI
대상 저장소: hohyun94/FileStore, hohyun94/ProcessCenter, hohyun94/portal-foundation
현재 단계: Stage 2 포탈 통합 및 운영 보안 강화

1. 문서 목적 ​

이 문서는 FileStore와 ProcessCenter의 현재 구현 상태를 설명하고, 후속 개발자가 이어서 처리해야 할 완성도·보안 과제를 정의한다. 각 과제에는 구현 목적, 책임 경계, 권장 순서, 완료 조건을 포함한다.

핵심 책임 경계: ProcessCenter와 같은 소비 포탈은 콘텐츠별 조회·수정·삭제 권한을 결정한다. FileStore는 service-to-service 인증, 저장 정책, 파일 lifecycle, signed URL, soft delete, cleanup, 감사 로그를 담당한다. 권한 없는 포탈 요청은 FileStore 호출 전에 차단되어야 한다.

2. 현재 완료된 범위 ​

2.1 FileStore ​

FileStore에는 다음 기능이 구현되어 있다.

영역현재 상태
저장소Cloudflare R2 및 S3-compatible backend 연동
업로드upload-session과 직접 base64 업로드 지원
lifecyclePENDING_SCAN, ACTIVE, QUARANTINED, DELETED 상태 모델
삭제metadata-only soft delete
정리DELETED 파일의 background cleanup 및 감사 로그
보안service token 인증, consumer/mapping policy 검증
감사requestId, authorization issuer/operation/allowed metadata 보존
업로드 입력 검증위험 파일명, MIME parameter, HTML/JavaScript/SVG, malformed base64 차단
API 오류삭제 또는 미존재 파일 read-url 요청을 404로 처리
검증R2 lifecycle smoke test 및 authorization security smoke test

최근 FileStore 보안 강화 커밋은 다음과 같다.

text
31a615d feat: harden asset upload validation

관련 문서는 다음 파일을 참고한다.

2.2 ProcessCenter ​

ProcessCenter에는 다음 통합이 완료되어 있다.

영역현재 상태
공통 adapterportal-foundation의 FileStore adapter 사용
editor 이미지HTML에 영구 URL 대신 data-asset-id 참조 저장
read URL조회 시 FileStore signed URL로 해석
orphan 파일참조에서 제거된 editor 파일을 soft-delete 대상으로 처리
retry queue삭제 실패 파일의 exponential backoff 재처리
process ACLR 담당자 또는 관리자만 attachment 변경 가능
notice ACLPUBLISHED는 일반 사용자 허용, DRAFT·ARCHIVED는 관리자 전용
보안 smoke test인증·consumer/mapping policy·unknown 파일 negative test

최근 ProcessCenter 관련 커밋은 다음과 같다.

text
ff00361 test: cover process attachment acl and idor boundaries
f81a15b test: enforce notice attachment visibility acl

3. 반드시 이어서 처리할 작업 ​

3.1 PENDING_SCAN 실제 검사 pipeline ​

현재 파일은 업로드 후 PENDING_SCAN 상태가 되지만, 실제 파일 내용 검사와 ACTIVE 전환을 담당하는 scanner pipeline은 후속 작업이다.

권장 흐름은 다음과 같다.

text
upload
→ PENDING_SCAN
→ MIME 및 magic bytes 검사
→ malware/content scanner
→ ACTIVE 또는 QUARANTINED

구현 범위는 다음과 같다.

  1. 파일 signature와 선언된 contentType의 일치 여부를 검사한다.
  2. 확장자 위장 파일을 탐지한다.
  3. ZIP bomb 및 과도한 압축 해제 크기를 제한한다.
  4. PDF 및 Office 문서 검사 정책을 결정한다.
  5. scanner timeout과 scanner 오류를 QUARANTINED 또는 재시도 대상으로 분류한다.
  6. QUARANTINED와 PENDING_SCAN 파일에는 read-url을 발급하지 않는다.
  7. scanner 결과와 실패 사유를 감사 로그에 남긴다.
  8. scanner가 장시간 응답하지 않는 파일을 운영 지표로 노출한다.

완료 조건은 정상 파일이 ACTIVE가 되고, 악성 또는 검사 실패 파일이 QUARANTINED가 되며, 두 상태 모두에 대해 read-url 발급 정책이 테스트로 고정되는 것이다.

3.2 Upload·complete·delete 멱등성 ​

네트워크 재시도와 worker 재실행으로 중복 파일 또는 잘못된 상태 전이가 발생하지 않아야 한다.

다음 시나리오를 테스트한다.

시나리오기대 결과
동일 upload-session 재호출정책에 맞는 deduplication 또는 명시적 새 요청 처리
동일 complete 재호출중복 활성화와 상태 후퇴 없음
다른 checksum의 complete 재호출요청 거부 및 기존 파일 보존
동일 delete 재호출안전한 no-op 또는 동일 DELETED 결과
동일 orphan enqueue 재호출queue 중복 방지
cleanup worker 재실행object 이중 삭제에도 상태 일관성 유지

필요하면 idempotencyKey 또는 requestId 기반 unique constraint를 추가한다. 특히 upload-session에서 같은 요청이 중복 파일을 생성하지 않는지 먼저 결정해야 한다.

완료 조건은 중복 요청에 대한 정책이 문서화되고, service unit test와 PostgreSQL integration test가 모두 통과하는 것이다.

3.3 Signed URL 보안 강화 ​

signed URL 발급 정책을 다음 기준으로 재검토한다.

  • URL TTL을 용도별로 짧게 제한한다.
  • PENDING_SCAN, QUARANTINED, DELETED 상태의 read-url 발급을 차단한다.
  • signed URL 자체를 감사 로그에 저장하지 않는다.
  • 웹편집기 이미지와 일반 첨부파일의 Content-Disposition 정책을 분리한다.
  • 일반 첨부파일은 기본적으로 attachment 응답을 사용한다.
  • inline 표시가 필요한 이미지 형식은 허용 목록으로 관리한다.
  • 응답 파일명에 CR/LF 및 path separator가 포함되지 않도록 한다.
  • 저장된 파일의 contentType을 포탈 요청이 임의로 덮어쓰지 못하게 한다.

완료 조건은 상태별 read-url 테스트, TTL 테스트, content disposition 테스트, 삭제·격리 파일 차단 테스트가 존재하는 것이다.

3.4 공통 FileStore API contract test ​

현재 ProcessCenter와 FileStore의 adapter 테스트가 여러 저장소에 분산되어 있다. 향후 소비 포탈이 추가되면 동일한 계약을 재사용할 수 있도록 portal-foundation에 공통 contract fixture를 추가한다.

최소 계약 항목은 다음과 같다.

  • authorizationOperation 값은 read, write, delete 중 하나이다.
  • upload-session 응답은 data.asset과 upload locator를 제공한다.
  • complete 응답은 data 아래 활성화된 파일을 제공한다.
  • read-url 응답은 data.locator를 제공한다.
  • 삭제된 파일의 read-url은 404를 반환한다.
  • policy 불일치는 400을 반환한다.
  • 인증 실패는 401을 반환한다.
  • requestId와 authorization metadata가 감사 이벤트에 보존된다.
  • service token은 브라우저 번들 또는 클라이언트 응답에 포함되지 않는다.

완료 조건은 FileStore staging을 대상으로 adapter contract test를 실행할 수 있고, ProcessCenter가 그 fixture를 사용하는 것이다.

3.5 포탈 ACL·IDOR 경계 확대 ​

ProcessNode와 Notice의 기본 attachment ACL 테스트는 추가되어 있다. 다음 교차 조합을 보완한다.

  • 다른 ProcessNode의 파일 ID 조회
  • 다른 Notice의 attachment ID 사용
  • Notice ID와 attachment ID의 교차 조합
  • 다른 consumer의 파일 ID 사용
  • 포탈 관계 row가 삭제된 뒤 남은 파일 접근
  • 포탈 DB에는 존재하지만 FileStore에는 없는 파일
  • FileStore에는 존재하지만 포탈 ACL 관계가 없는 파일

모든 권한 실패의 필수 기대값은 다음과 같다.

text
ProcessCenter ACL 실패
→ FORBIDDEN 또는 NOT_FOUND
→ FileStore 호출 0회

Notice 정책은 현재 PUBLISHED를 일반 사용자 공개로 보고, DRAFT 및 ARCHIVED를 관리자 전용으로 처리한다. 조직별 공지 visibility가 추가되면 notice_posts에 명시적 visibility 또는 organization scope를 추가하고 ACL을 확장한다.

3.6 Retry queue 및 cleanup 운영 보안 ​

retry queue와 cleanup worker는 다음 장애·공격 시나리오를 검증해야 한다.

  • 동일 파일에 대한 retry enqueue 폭주
  • lease 만료 뒤 중복 worker 실행
  • DEAD 상태의 무제한 재처리
  • legal hold 우회 삭제
  • retention 기간 전 cleanup 시도
  • 관리자 수동 retry endpoint의 일반 사용자 호출
  • worker 재시작 중 상태 유실
  • actorSubject와 requestId 없는 수동 처리

관리자 수동 retry에는 관리자 role 검사, 재시도 횟수 상한, 처리 사유, DEAD 상태 재활성화 감사 로그가 필요하다.

완료 조건은 lease recovery, duplicate enqueue, legal hold, retention, 관리자 권한, DEAD state를 대상으로 하는 integration test가 통과하는 것이다.

3.7 보안 관측성과 감사 로그 ​

운영 장애와 보안 사건을 추적할 수 있도록 다음 지표를 추가한다.

영역권장 지표
Upload성공, 실패, 크기 초과, MIME 차단
Completechecksum 불일치, 객체 크기 불일치
Read발급 성공, 발급 실패, 상태별 거부
Deletesoft delete, legal hold 거부, retention 거부
Scan성공, quarantine, timeout, 재시도
Cleanup삭제 성공, 실패, skipped, DEAD
Security인증 실패, policy mismatch, ACL 거부, IDOR 차단

감사 이벤트는 가능한 경우 다음 값을 함께 보존한다.

text
requestId
consumerId
assetId
actorSubject
authorizationIssuer
authorizationOperation
result
failureReason

signed URL 원문과 service token은 감사 로그에 저장하지 않는다.

4. ProcessCenter 전체 테스트의 현재 상태 ​

2026-09-06 전체 테스트 실행에서는 FileStore와 Notice ACL 관련 테스트가 통과했다. 다만 기존 TaskFlowMap.test.tsx에서 3건의 실패가 발생했다.

테스트 파일상태실패 내용
server/fileStoreClient.test.ts통과6 tests
server/noticesRouter.test.ts통과4 tests
server/processRouter.test.ts통과13 tests
client/src/components/TaskFlowMap.test.tsx실패17개 중 3개 실패

확인된 실패는 다음과 같다.

  1. workflow-inbound-source-handle-70 test id를 찾지 못한다.
  2. ↓ 승인 텍스트를 찾지 못한다.
  3. 기대값은 조치였으나 실제 렌더링 값은 조치→승인이다.

pnpm check는 별도로 실행했으며 통과했다. 이 실패들은 현재 FileStore 변경과 직접 관련이 없지만, CI를 녹색으로 만들기 위해 별도 수정이 필요하다.

5. 권장 개발 순서 ​

다음 순서로 진행하면 보안 위험을 먼저 줄이고 구현 변경의 범위를 통제할 수 있다.

순서작업이유
1PENDING_SCAN scanner pipeline악성 콘텐츠의 실제 차단을 완성한다.
2upload·complete·delete 멱등성중복 파일과 잘못된 상태 전이를 방지한다.
3signed URL TTL·응답 정책URL 유출과 위험한 inline 응답을 줄인다.
4공통 API contract test포탈 추가 시 계약 회귀를 막는다.
5retry·cleanup 운영 보안장애와 반복 삭제의 안전성을 높인다.
6보안 지표 및 감사 로그운영 중 원인 분석과 탐지를 가능하게 한다.
7TaskFlowMap 기존 테스트 수정전체 CI 안정성을 회복한다.

6. 개발 시 지켜야 할 원칙 ​

  1. 브라우저에는 FILE_STORE_SERVICE_TOKEN을 절대 노출하지 않는다.
  2. 포탈 ACL을 FileStore의 consumer policy로 대체하지 않는다.
  3. FileStore는 포탈의 콘텐츠 권한을 추론하지 않는다.
  4. 파일 ID만으로 포탈 콘텐츠 접근 권한을 허용하지 않는다.
  5. 삭제는 기본적으로 metadata-only soft delete로 처리한다.
  6. legal hold와 retention 정책을 cleanup보다 우선 적용한다.
  7. 모든 서버 간 요청에는 requestId와 actor metadata를 연결한다.
  8. 위험 파일 형식을 허용할 때는 명시적인 sanitization 또는 변환 단계를 먼저 추가한다.
  9. 실패한 삭제는 데이터베이스에 retry 상태를 남기고 무한 재시도를 방지한다.
  10. 새 소비 포탈을 추가할 때는 공통 adapter와 contract test를 우선 사용한다.

7. 첫 작업 시작 전 확인 목록 ​

후속 개발자는 구현 전에 다음을 확인한다.

  • FileStore staging URL과 service token이 배포 환경에 주입되어 있는가.
  • PostgreSQL migration이 최신 상태인가.
  • R2 backend의 HEAD, DELETE, signed URL 동작이 정상인가.
  • FILE_STORE_ENABLED와 FILE_STORE_CONSUMER_ID가 ProcessCenter에 설정되어 있는가.
  • portal-foundation의 adapter 및 editor-core vendor 버전이 ProcessCenter와 일치하는가.
  • scanner를 동기 처리할지 비동기 worker로 처리할지 결정했는가.
  • Notice 공개 범위가 전체 인증 사용자 기준인지 조직 기준인지 확정했는가.
  • signed URL TTL과 Content-Disposition 정책이 용도별로 정의되었는가.

8. 최종 완료 기준 ​

FileStore 완성도 작업은 다음 조건을 모두 만족할 때 완료로 본다.

  • 악성 또는 검사 실패 파일이 ACTIVE가 되지 않는다.
  • 어떤 상태에서도 권한 없는 signed URL이 발급되지 않는다.
  • 동일 요청 재시도로 중복 파일이 생성되지 않는다.
  • 포탈 ACL 실패 시 FileStore 호출이 발생하지 않는다.
  • retry 및 cleanup worker가 lease·legal hold·retention을 준수한다.
  • requestId 기반 감사 추적이 가능하다.
  • 공통 API contract test가 FileStore와 포탈 adapter 양쪽에서 통과한다.
  • ProcessCenter 전체 CI 테스트가 통과한다.

References ​