docs: 백업 키는 메인 계정의 백업 전용 API 인증키로 — 사용자 결정 · 위험 · 서브 계정은 좁히는 길로

사용자가 서브 계정을 만들지 않고 메인 계정의 API 인증키로 가기로 했다(2026-11-03).
README · ops.env 예시에 만드는 곳(My Account › 계정 및 보안 관리 › 보안 관리 › 접근 관리 —
계정마다 2개, 기본 키와 섞지 않게 새로)과, 그 키가 계정의 모든 API 를 연다는 위험을 함께 적었다.
서브 계정 차례는 범위를 줄이는 길로 남겼다. 체크리스트(템플릿 공용)의 권장은 그대로 둔다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-03 02:16:39 +09:00
parent 9b530da6e1
commit 3f8ba0081a
2 changed files with 10 additions and 7 deletions
+8 -5
View File
@@ -288,7 +288,7 @@ node --env-file=.env.development mail/scripts/setup.mjs
- **계정 보안(12단계)** — `.env.production` 의 `MAIL_WEBHOOK_SECRET`(엔진 웹훅의 서명 키 — `openssl rand -hex 24` 로 만든 값, 사람이 지은 값은 쓰지 않는다).
운영 필수다 — 아래 2)의 `up` **전에** 넣는다(없으면 백엔드가 env 검사에서 멈춰 웹메일 전체가 서고, setup 도 멈춘다).
직원에게 미리 알린다 — 2단계 인증을 켜면 아웃룩 · 휴대폰 메일 앱은 앱 비밀번호로 다시 연결해야 한다 ([계정 보안](#계정-보안-12단계--인프라))
- **전환 준비(13단계)** — 이미 떠 있는 서버는 [13단계 전부터 운영 중인 서버](#13단계-전부터-운영-중인-서버)의 차례대로(첫 setup 은 `--recovery`). 첫 직원을 옮기기 **전에** 백업과 15분 점검을 켠다: NCP Object Storage 비공개 버킷 · Object Storage 만 쓰는 하위 계정 키 · restic 비밀번호(비밀번호 관리자에 따로 보관),
- **전환 준비(13단계)** — 이미 떠 있는 서버는 [13단계 전부터 운영 중인 서버](#13단계-전부터-운영-중인-서버)의 차례대로(첫 setup 은 `--recovery`). 첫 직원을 옮기기 **전에** 백업과 15분 점검을 켠다: NCP Object Storage 비공개 버킷 · 백업 전용 API 인증키(아래 "백업 › 설치" — 메인 계정 키를 고른 까닭과 위험) · restic 비밀번호(비밀번호 관리자에 따로 보관),
Healthchecks.io 점검 둘 · UptimeRobot 감시 셋 ([백업](#백업) · [감시](#감시-13단계)).
`.env.production` 의 `DB_IMAGE` 를 예시와 같은 값(판 · digest 고정 — 옛 파일은 `postgres:15-alpine`)으로 바꾼다 — 다음 `up -d` 에서 db 가 다시 만들어진다(몇 초 · 데이터는 볼륨 그대로, 같은 메이저 15 라 덤프 · 복원은 필요 없다).
frontend 는 `MAIL_DOMAIN` · `MAIL_HOSTNAME` 으로 [메일 프로그램 자동 설정](#메일-프로그램-자동-설정) 응답을 만든다 — 이미 있는 값이라 새로 넣을 것은 없다
@@ -1770,10 +1770,13 @@ systemctl list-timers 'arasystem-*'
```
- **NCP Object Storage** — 콘솔에서 한국 리전에 버킷을 만든다(공개 안 함 · 수명 주기 삭제 규칙 없음 — 지우기는 restic 이 한다).
**버킷에는 따로 키가 없다** — API 인증키(Access Key ID · Secret Key)는 Object Storage 만 쓰는 **서브 계정**의 것을 쓴다(메인 계정 키는 서버 · 결제까지 연다):
콘솔 › Sub Account › Sub Accounts › 서브 계정 생성(접근 유형은 **API Gateway 접근만** — 콘솔 로그인 없음) → 그 계정의 **정책** 탭에 관리형 `NCP_OBJECT_STORAGE_MANAGER` 하나
(`…_VIEWER` 는 읽기만이라 백업이 안 된다) → **Access Key** 탭에서 추가 — **Secret Key 는 만들 때만 보인다**, 그 자리에서 비밀번호 관리자(restic 비밀번호와 같은 항목)에 둔다 → ops.env 의 `AWS_ACCESS_KEY_ID` · `AWS_SECRET_ACCESS_KEY`.
NCP 문서에는 키를 버킷 하나로 좁히는 방법이 없다(2026-11-03 — 사용자 정의 정책도 버킷을 고르는 칸이 문서에 없다) — 이 키로 같은 계정의 버킷이 모두 열리므로 다른 버킷을 두지 않는다(시험 버킷은 쓸모가 끝나면 지운다).
**버킷에는 따로 키가 없다** — 계정의 API 인증키(Access Key ID · Secret Key)를 쓴다. **서버 B 는 메인 계정의 API 인증키를 백업 전용으로 새로 만들어 쓴다**(2026-11-03 사용자 결정 — 서브 계정은 만들지 않는다):
콘솔 오른쪽 위 My Account › 계정 및 보안 관리(다시 로그인) › 보안 관리 › 접근 관리 › API 인증키 관리 › [신규 API 인증키 생성] — 계정마다 2개까지라, 처음부터 있던 기본 키는 쓰지 않는다
(그 키를 쓰는 다른 곳과 섞이지 않게 — 문제가 생기면 이 키만 사용 중지할 수 있다) → 두 값을 비밀번호 관리자(restic 비밀번호와 같은 항목)에 → ops.env 의 `AWS_ACCESS_KEY_ID` · `AWS_SECRET_ACCESS_KEY`.
⚠️ **메인 계정 키는 Object Storage 만이 아니라 그 NCP 계정의 모든 API 를 연다**(서버 A · B, 네트워크 · ACG, 스토리지 …) — 이 키가 놓이는 서버 B 의 root 가 뚫리면 계정 전체가 넘어간다. 받아들이고 고른 길이다.
범위를 줄이려면 서브 계정으로 바꾼다 — Sub Account › Sub Accounts › 서브 계정 생성(접근 유형 **API Gateway 접근만**) → 정책 탭에 관리형 `NCP_OBJECT_STORAGE_MANAGER` 하나(`…_VIEWER` 는 읽기만이라 백업이 안 된다)
→ Access Key 탭에서 추가(**Secret Key 는 만들 때만 보인다**). 그래도 버킷 하나로는 좁히지 못한다(NCP 문서에 그 방법이 없다 — 2026-11-03) — 같은 계정에 다른 버킷을 두지 않는다(시험 버킷은 쓸모가 끝나면 지운다).
키를 바꿀 때는 새 키를 ops.env 에 넣고 백업이 한 번 된 것을 본 뒤 옛 키를 사용 중지 → 삭제(사용 중지한 키만 지울 수 있다).
만들 때의 다른 칸은 기본값 그대로 — **잠금 해제**(보존 기간을 걸면 restic 이 지난 백업을 지우지 못해 prune 이 실패한다) · **암호화(KMS) 해제**(restic 이 이미 암호화한다. 한 번 켜면 끌 수 없다) · 타 계정 권한 없음.
"공개"는 버킷의 폴더 · 파일 목록을 누구에게나 연다 — restic 은 키로 서명해 들어가므로 필요 없다(NCP 가이드 "버킷 관리", 2026-11-03 확인).
`RESTIC_REPOSITORY=s3:https://kr.object.ncloudstorage.com/<버킷>/arasystem`, `RESTIC_OPTIONS='-o s3.region=kr-standard -o s3.bucket-lookup=path'` —