영상이 어디에 있고 누가 접근할 수 있는가
보안은 “안전하다”는 말보다 저장 위치, 접근 권한, 임시 처리와 외부 전송 범위로 설명합니다.
시행일
파일이 어디에 있는가
고객 저장소를 연결한 영상의 원본과 HLS/DASH 출력물은 선택한 고객 저장소에 기록됩니다. 저장소를 연결하지 않은 무료 계정의 파일은 NULX 관리 저장소에 보관됩니다. NULX는 처리·재생·청구 운영에 필요한 메타데이터를 별도로 보관합니다.
- 고객 저장소의 영상을 관리형 변환할 때 NULX 워커는 범위와 시간이 제한된 서명 URL로 원본을 읽고 임시 작업 공간에서 처리합니다.
- 연결된 고객 저장소의 결과물은 해당 저장소에 다시 기록됩니다. 저장소를 연결하지 않은 계정에는 이 설명이 적용되지 않습니다.
- 모든 트래픽은 HTTPS 전용입니다. HSTS를 하위 도메인 포함 2년으로 설정해, 한 번 접속한 브라우저는 HTTP로 되돌아가지 않습니다.
자격증명과 연결 범위
저장소 자격증명과 전송 서명 키는 Active Record Encryption으로 DB에 암호화 저장되며, 저장 후에는 다시 표시되지 않습니다.
- 설정은 계정 전체 키가 아니라, 고객이 고른 접두사로 제한된 버킷 범위 R2 토큰을 요구합니다.
- 고객이 자기 Cloudflare 계정에서 토큰을 폐기하면 NULX가 그 자격증명으로 새 요청을 할 수 없습니다. 이미 발급된 서명 주소나 캐시된 응답은 각 만료·보관 시간까지 동작할 수 있습니다.
- 연결을 읽기 전용으로 둘 수 있고, 그 경우 NULX는 읽기만 하며 그 안의 객체를 절대 삭제하지 않습니다.
로그인
이메일 일회용 코드가 기본 로그인 경로이고, 설정된 경우 Google 로그인을 함께 씁니다. 대시보드에 공유 비밀번호는 없습니다.
- 코드는 6자리이고 10분 후 만료되며 시도는 최대 5회입니다. 새 코드를 요청하면 이전 코드는 무효가 됩니다.
- 인증 검증용 레코드에는 코드 자체가 아니라 bcrypt 다이제스트만 저장됩니다. 일회용 코드는 이메일 발송 작업에서 일시 처리됩니다.
- 세션은 미사용 14일, 사용 여부와 무관하게 90일이면 종료됩니다.
- 세션 쿠키는 Secure · HttpOnly · SameSite=Lax입니다.
보호된 재생
R2 버킷은 기본이 비공개이고, 공개 재생은 경로나 도메인을 명시적으로 설정해야 가능합니다. 공개하면 안 되는 영상은 만료되는 서명 경로로 제공합니다.
- 서명 재생 URL은 기본 30분간 유효하며, 만료 전에 플레이어가 갱신해 보던 사람이 끊기지 않습니다.
- 서명은 자산 단위로 이루어집니다. 링크가 새더라도 버킷이 노출되는 대신 만료 시점에 동작을 멈춥니다.
- 일반 화면의 Content-Security-Policy는 응답마다 nonce를 사용하고 object-src를 none으로 제한합니다. 플레이어·임베드·공유 화면의 frame-ancestors는 고객이 지정한 허용 도메인을 따르며, 미설정 시 임베드용 운영 기본값을 사용합니다.
자동 자막과 외부 전송
자동 자막은 업로드마다 켜지 않으면 꺼져 있습니다. 켠 경우 영상 파일이 아니라 저비트레이트 오디오 추출본만 Cloudflare Workers AI로 전송됩니다. 자막 번역을 요청하면 자막 텍스트만 미국의 OpenAI로 전송됩니다.
- 업로드 화면이 처리 시작 전에 이 전송을 고지하므로, 조용히 나가는 일이 없습니다.
- 관리형 처리 중에는 NULX 호스팅 인프라가 미디어를 임시 처리합니다. 자동 자막을 켜면 Cloudflare Workers AI가 음성 추출본을 추가로 처리합니다.
영상 삭제
영상을 지우면 휴지통으로 이동하고, 고객 버킷의 객체는 30일 뒤 영구 삭제로 예약됩니다. 실수로 지운 경우 되돌릴 수 있습니다.
- 계정 소유자는 보존 기간을 기다리지 않고 휴지통에서 즉시 영구 삭제할 수 있습니다.
- 읽기 전용 연결에서는 삭제가 NULX에서만 제거하고 버킷의 객체는 의도적으로 남깁니다. 그건 고객만 지울 수 있습니다.
- 다른 자산이 아직 참조하는 객체는 영구 삭제가 건드리지 않습니다.
NULX가 필요로 하는 정확한 권한
기존 버킷을 수동 연결할 때 NULX가 실제로 호출하는 S3 호환 작업입니다. 연결 토큰을 이 범위로 좁힐 수 있으며 읽기 전용 연결은 읽기 항목만 사용합니다. 자동 설정은 별도의 상위 토큰으로 전용 버킷·제한 토큰·재생 설정을 만들고, 실패 롤백이나 고객 요청 정리 때 자신이 만든 리소스를 삭제할 수 있습니다.
- 읽기: GetObject, HeadObject, ListBucket (지정한 프리픽스로 제한).
- 쓰기: PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload, AbortMultipartUpload.
- 삭제: DeleteObject. 읽기·쓰기 연결에서 자산을 삭제할 때만 사용합니다.
- 수동 연결 토큰에 요구하지 않는 것: 계정 단위 작업, 버킷 생성·삭제, IAM이나 토큰 관리. 자동 설정용 상위 토큰의 권한과 영향은 연결 화면에서 별도로 확인합니다.
관리형 인코딩 중에 일어나는 일
고객 저장소를 연결한 영상에서 NULX 워커가 미디어를 다루는 구간을 단계별로 적었습니다. 저장소를 연결하지 않은 계정은 NULX 관리 저장소를 사용합니다.
- 1. 연결된 고객 저장소의 원본은 고객 프리픽스 아래 버킷에 직접 기록됩니다.
- 2. 워커에게 그 객체 하나에 대한 시간 제한 서명 주소가 발급됩니다. 자격증명이 아닙니다.
- 3. 워커가 자체 디스크에서 HLS 화질 단계로 변환합니다.
- 4. 결과물이 고객 프리픽스 아래로 기록되고, 작업이 끝나면 워커의 로컬 사본은 삭제됩니다.
- 5. 연결된 고객 저장소 구성에서 NULX는 작업 메타데이터(길이, 용량, 상태)를 보관하고 별도의 영구 미디어 사본은 두지 않습니다.
API 키
API 키는 테넌트에 대한 기계 접근을 인증합니다. 범위가 제한되고, 즉시 폐기할 수 있으며, 발급 후에는 복구할 수 없습니다.
- SHA-256 다이제스트만 저장합니다. 키는 생성 시 한 번만 표시되고 다시 볼 수 없습니다. 분실하면 폐기하고 새로 발급하세요.
- 키마다 범위를 명시합니다(assets, playback, billing, storage, webhooks, api_keys). 모든 권한을 가진 단일 토큰이 아닙니다.
- 생성 시 만료일을 지정할 수 있고, 폐기는 즉시 적용됩니다.
- 발급과 폐기는 감사 기록에 남습니다.
감사 기록과 신고
보안 관련 사건을 기록합니다. 로그인, API 키 발급·폐기, 플랜 변경, 저장소 연결 변경, 운영자 작업이 포함됩니다.
- 취약점 의심 사례는 contact@nulx.dev로 신고해 주세요. 연락처는 /.well-known/security.txt에도 공개돼 있습니다.
- NULX는 현재 SOC 2나 ISO 27001 인증을 보유하고 있지 않으며, 보유한다고 주장하지 않습니다. 이 페이지는 실제로 적용 중인 통제만 설명합니다.
고객 데이터에 접근하거나 서비스를 방해하지 말고, 발견 시각·재현 순서·영향 범위를 함께 보내 주세요. contact@nulx.dev /.well-known/security.txt