S3를 사용하는 CloudFront
S3에 저장된 LibreChat 파일을 위한 CDN 계층으로 Amazon CloudFront를 구성하세요(안정적인 미디어 링크, 서명된 쿠키, 서명된 다운로드 URL 포함).
CloudFront를 사용하면 LibreChat이 S3에 파일을 보관하면서도 안정적인 CDN URL을 통해 이미지, 아바타, 다운로드 파일을 제공할 수 있습니다. 이는 만료되는 S3 사전 서명(presigned) 이미지 URL에 사용자를 노출하지 않으면서 S3의 내구성을 활용하고자 할 때 권장되는 AWS 설정입니다.
CloudFront를 사용해야 하는 경우
다음과 같은 경우 CloudFront를 사용하세요:
- UI 전반에서 지속적으로 렌더링되는 안정적인 아바타 및 이미지 URL
- S3 버킷 앞단의 글로벌 엣지 캐싱
- 비공개 인라인 이미지 및 아바타를 위한 서명된 쿠키(Signed cookies)
- 다운로드를 위한 백엔드 인증 서명된 URL (Backend-authorized signed URLs)
- 파일 삭제 시 선택적 캐시 무효화
S3는 여전히 필요합니다
cloudfront 파일 전략은 객체를 S3에 저장하고 CloudFront URL을 반환합니다. 먼저 S3 환경 변수를 구성한 다음, librechat.yaml에 cloudfront 블록을 추가하세요.
요구 사항
- 비공개 S3 버킷
- S3 버킷을 오리진으로 사용하는 CloudFront 배포
- CloudFront가 S3에서 읽을 수 있도록 하는 Origin Access Control (OAC) 또는 이에 상응하는 오리진 액세스 정책
AWS_REGION및AWS_BUCKET_NAMEAWS_ACCESS_KEY_ID및AWS_SECRET_ACCESS_KEY(배포 환경에서 IRSA와 같은 AWS 자격 증명 공급자를 사용하는 경우는 제외)- 서명된 쿠키(signed cookies) 또는 서명된 다운로드 URL(signed download URLs)을 사용할 때의
CLOUDFRONT_KEY_PAIR_ID및CLOUDFRONT_PRIVATE_KEY
환경 변수
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION=us-east-1
AWS_BUCKET_NAME=your_bucket_name
# Required for signed cookies and signed CloudFront download URLs
CLOUDFRONT_KEY_PAIR_ID=K1234567890ABC
CLOUDFRONT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"CLOUDFRONT_PRIVATE_KEY에는 전체 PEM 개인 키가 포함되어야 합니다. .env 파일에서는 이를 따옴표로 묶고 줄 바꿈을 유지하거나, 플랫폼의 보안 비밀 관리자(secret manager)를 통해 주입하십시오.
기본 구성
이미지와 아바타에는 CloudFront를 사용하고 문서는 S3 서명된 URL로 유지하려면 fileStrategies를 사용하세요:
version: 1.3.11
fileStrategies:
avatar: 'cloudfront'
image: 'cloudfront'
document: 's3'
cloudfront:
domain: 'https://cdn.example.com'
imageSigning: 'none'
urlExpiry: 3600모든 파일 유형에 CloudFront를 사용해야 하는 경우 fileStrategy를 사용하세요:
fileStrategy: 'cloudfront'
cloudfront:
domain: 'https://cdn.example.com'Signed Cookies
서명된 쿠키(Signed cookies)는 비공개 인라인 이미지 및 아바타를 위한 보안 모드입니다. 이를 통해 LibreChat은 메시지와 기록 내에서 안정적인 CloudFront URL을 유지하면서, 단기 쿠키를 통해 접근 권한을 부여할 수 있습니다.
fileStrategies:
avatar: 'cloudfront'
image: 'cloudfront'
document: 's3'
cloudfront:
domain: 'https://cdn.example.com'
imageSigning: 'cookies'
cookieDomain: '.example.com'
cookieExpiry: 1800
urlExpiry: 3600
requireSignedAccess: true도메인 요구 사항
서명된 쿠키(signed cookies)의 경우, LibreChat API와 CloudFront 호스트 이름은 동일한 상위 도메인을 공유해야 합니다:
- API:
https://api.example.com - CloudFront CNAME:
https://cdn.example.com cookieDomain: ".example.com"
cookieDomain은 점(.)으로 시작해야 합니다. 브라우저는 관련 없는 도메인으로 CloudFront 쿠키를 전송하지 않습니다.
쿠키가 보호하는 것
LibreChat은 서명된 쿠키의 범위를 인라인 미디어 경로로 제한합니다:
/i/...사용자로 범위가 지정된 비공개 업로드 또는 생성된 이미지/a/...아바타 에셋,tenantId가 존재할 경우 테넌트(tenant)로 범위가 지정됨
문서, 일반 업로드 및 코드 출력물은 해당 인라인 미디어 경로 외부에 유지됩니다. 다운로드는 백엔드에 의해 승인되며 서명된 CloudFront URL로 반환됩니다.
쿠키 새로고침
signed-cookie 모드가 활성화되면, LibreChat은 시작 구성에서 쿠키 새로 고침 endpoint를 알립니다:
POST /api/auth/cloudfront/refresh인증된 세션은 인증 흐름, 토큰 갱신 및 CloudFront 이미지 재시도 경로 중에 쿠키를 새로 고칩니다. 새로 고침 응답에는 쿠키 수명과 권장되는 새로 고침 시점이 포함됩니다.
서명된 다운로드
LibreChat은 승인된 다운로드를 위해 서명된 CloudFront URL을 사용합니다. urlExpiry 설정은 해당 URL의 유효 기간을 초 단위로 제어합니다:
cloudfront:
domain: 'https://cdn.example.com'
imageSigning: 'cookies'
cookieDomain: '.example.com'
urlExpiry: 3600직접 다운로드 파일 이름 및 콘텐츠 유형(content-type) 재정의를 위해, CloudFront 캐시/원본 요청 정책을 구성하여 다음 쿼리 문자열을 S3로 전달하세요:
response-content-dispositionresponse-content-type
다운로드 경로의 경우, 다음을 포함한 응답 헤더 정책을 첨부하세요:
X-Content-Type-Options: nosniffdefault-src 'none'와 같은 제한적인 Content Security Policy
캐시 무효화 (Cache Invalidation)
기본적으로 LibreChat은 S3 객체를 삭제하며 CloudFront 무효화(invalidation)를 생성하지 않습니다. 삭제된 파일이 엣지 캐시에서 즉시 사라져야 하는 경우 무효화를 활성화하세요:
cloudfront:
domain: 'https://cdn.example.com'
distributionId: 'E1234ABCD'
invalidateOnDelete: trueinvalidateOnDelete가 true일 때 distributionId가 필요합니다. LibreChat이 사용하는 AWS 자격 증명에는 cloudfront:CreateInvalidation 권한도 필요합니다.
다중 리전 객체 경로 (Multi-Region Object Paths)
includeRegionInPath는 새로 생성된 객체 키에 스토리지 리전을 추가합니다:
cloudfront:
domain: 'https://cdn.example.com'
storageRegion: 'us-east-2'
includeRegionInPath: true활성화되면 새 키에는 지역 인식 경로 세그먼트가 포함됩니다. 예:
/i/r/us-east-2/t/tenantId/images/userId/file.png
/a/r/us-east-2/t/tenantId/avatars/userId/avatar.png
/r/us-east-2/t/tenantId/images/userId/file.pdf이는 새로 생성된 키에만 영향을 미칩니다. 기존 파일은 이동되지 않습니다. LibreChat은 사용자를 위해 CloudFront 오리진, Route 53 또는 리전 라우팅을 구성하지 않습니다.
CloudFront 차단 참조
| Key | Type | Description | Example |
|---|---|---|---|
| domain | string | CloudFront 배포 도메인 또는 CNAME. 필수 항목입니다. | domain: "https://cdn.example.com" |
| distributionId | string | 캐시 무효화에 사용되는 Distribution ID입니다. | distributionId: "E1234ABCD" |
| invalidateOnDelete | boolean | 파일이 삭제될 때 CloudFront 무효화(invalidation)를 생성합니다. 기본값: false. | invalidateOnDelete: false |
| imageSigning | string | 인라인 미디어 액세스 모드입니다. 공개 CloudFront 액세스에는 `"none"`을, 서명된 쿠키에는 `"cookies"`를 사용하세요. `"url"`은 예약되어 있으며 이미지에 대해서는 구현되지 않았습니다. | imageSigning: "cookies" |
| cookieDomain | string | 서명된 쿠키를 위한 공유 상위 도메인입니다. `imageSigning`이 `"cookies"`일 때 필요합니다. | cookieDomain: ".example.com" |
| cookieExpiry | number | 서명된 쿠키의 유지 시간(초 단위). 기본값: 1800. 최댓값: 604800. | cookieExpiry: 1800 |
| urlExpiry | number | 서명된 다운로드 URL의 유효 시간(초). 기본값: 3600. | urlExpiry: 3600 |
| storageRegion | string | 지역 인식 객체 경로를 위한 선택적 지역 레이블입니다. | storageRegion: "us-east-2" |
| includeRegionInPath | boolean | 새로 생성된 객체 키에 `storageRegion`을 포함합니다. 기본값: false. | includeRegionInPath: false |
| requireSignedAccess | boolean | 서명된 쿠키 CloudFront 액세스를 초기화할 수 없는 경우 시작을 실패합니다. 기본값: false. | requireSignedAccess: true |
권장 AWS 권한
S3 버킷에는 최소 권한 IAM 정책을 사용하세요. invalidateOnDelete가 활성화된 경우에만 CloudFront 무효화(invalidation) 권한을 추가하세요.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::my-librechat-bucket", "arn:aws:s3:::my-librechat-bucket/*"]
},
{
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::123456789012:distribution/E1234ABCD"
}
]
}문제 해결
- 시작 로그
CloudFront domain is required:cloudfront.domain을(를) 추가하세요. - 시작 로그
S3 must be initialized: 먼저 S3 환경 변수를 구성하세요. - 서명된 쿠키가 설정되지 않음:
imageSigning: "cookies",cookieDomain,CLOUDFRONT_KEY_PAIR_ID및CLOUDFRONT_PRIVATE_KEY를 확인하세요. - 브라우저에서 여전히 이미지를 불러올 수 없는 경우: API 및 CDN 호스트 이름이 구성된 상위 도메인을 공유하는지, 그리고
Secure및SameSite=None설정으로 쿠키가 허용되는지 확인하세요. - 다운로드 시 파일 이름/콘텐츠 유형 무시: CloudFront 캐시/원본 요청 정책을 업데이트하여 응답 재정의 쿼리 문자열을 전달하도록 설정하세요.
이 가이드는 어떤가요?