배경
영상 재생 URL(S3UrlPresigner.presign())은 X-Amz-Expires=7일로 서명되지만, 배포 환경(EC2)에서 약 1시간 뒤 403 ExpiredToken이 발생함. 로컬에서는 재현되지 않음.
원인
S3Config.java의 s3Presigner 빈이 DefaultCredentialsProvider.create()를 사용 (S3Config.java:29). 이 체인은 로컬에서는 ~/.aws/credentials의 영구 IAM 키(AKIA...)를 쓰지만, EC2 배포 환경에서는 인스턴스 프로파일(IAM 역할)의 임시 STS 자격증명(ASIA... + session token, 수명 ~1시간)으로 귀결되는 것으로 보임.
AWS SigV4 사양상 presigned URL의 실효 만료는 min(X-Amz-Expires, 서명에 쓰인 자격증명의 만료시각)이라, session token이 만료되면 X-Amz-Expires=7일 설정과 무관하게 URL이 즉시 무효화됨 — 업로드 직후엔 정상, ~1시간 뒤부터 403.
코드베이스 전체에 정적 AWS 키 주입이 없고(StaticCredentialsProvider는 테스트에만 존재), CD 워크플로우(cd.yml)의 secrets 목록에도 AWS 키가 없어 이 가설과 정황이 일치함.
수정 방향
s3Presigner 빈에만 전용 영구 IAM 키를 StaticCredentialsProvider로 주입 (다른 S3 빈 s3Client는 기존 DefaultCredentialsProvider 유지)
- 신규 IAM 사용자/키 발급 필요 (presign 권한만 최소 부여) — 인프라 작업 별도 필요
application.yaml / application-secret.yaml에 키 설정 추가, GitHub Secrets + CD .env 주입 추가
영향 범위
S3Config.java만 수정. S3UrlPresigner를 공유하는 커뮤니티/프로필/영상 어댑터 전부에 적용됨(별도 코드 변경 불필요).
작업 항목
배경
영상 재생 URL(
S3UrlPresigner.presign())은X-Amz-Expires=7일로 서명되지만, 배포 환경(EC2)에서 약 1시간 뒤403 ExpiredToken이 발생함. 로컬에서는 재현되지 않음.원인
S3Config.java의s3Presigner빈이DefaultCredentialsProvider.create()를 사용 (S3Config.java:29). 이 체인은 로컬에서는~/.aws/credentials의 영구 IAM 키(AKIA...)를 쓰지만, EC2 배포 환경에서는 인스턴스 프로파일(IAM 역할)의 임시 STS 자격증명(ASIA... + session token, 수명 ~1시간)으로 귀결되는 것으로 보임.AWS SigV4 사양상 presigned URL의 실효 만료는
min(X-Amz-Expires, 서명에 쓰인 자격증명의 만료시각)이라, session token이 만료되면X-Amz-Expires=7일설정과 무관하게 URL이 즉시 무효화됨 — 업로드 직후엔 정상, ~1시간 뒤부터 403.코드베이스 전체에 정적 AWS 키 주입이 없고(
StaticCredentialsProvider는 테스트에만 존재), CD 워크플로우(cd.yml)의 secrets 목록에도 AWS 키가 없어 이 가설과 정황이 일치함.수정 방향
s3Presigner빈에만 전용 영구 IAM 키를StaticCredentialsProvider로 주입 (다른 S3 빈s3Client는 기존DefaultCredentialsProvider유지)application.yaml/application-secret.yaml에 키 설정 추가, GitHub Secrets + CD.env주입 추가영향 범위
S3Config.java만 수정.S3UrlPresigner를 공유하는 커뮤니티/프로필/영상 어댑터 전부에 적용됨(별도 코드 변경 불필요).작업 항목
S3Config.java:s3Presigner빈에StaticCredentialsProvider적용application.yaml/application-secret.yaml에 키 설정 추가cd.yml/.env주입 추가S3VideoPlaybackUrlAdapterTest패턴 참고)