설정 저장소
설정 저장소는 기기 간 CLI 설정의 영지식 암호화 동기화를 제공합니다. 설정은 클라이언트 측에서 콘텐츠 암호화 키(CEK)로 암호화되므로 서버는 평문 데이터를 절대 볼 수 없습니다.
잠금 해제 방법 (키 슬롯)
저장소당 CEK는 하나이며, LUKS 키 슬롯과 유사하게 각 잠금 해제 방법마다 독립적으로 래핑됩니다. 슬롯 중 하나만 있어도 동일한 키를 열 수 있으며, 데이터를 다시 암호화하지 않고도 슬롯을 추가하거나 제거할 수 있습니다.
| 방법 | 설명 | 참고 |
|---|---|---|
| 패스키 | PRF 확장을 지원하는 WebAuthn 패스키 | 가장 강력한 옵션이며 하드웨어 기반 |
| 마스터 비밀번호 | 직접 정한 비밀번호를 PBKDF2-SHA256(60만 회 반복)으로 스트레칭 | PRF 지원 하드웨어 없이도 사용 가능하며, 헤드리스 CLI 등록도 지원 |
| 복구 코드 | RC1-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX 형식으로 생성되는 코드 | 생성 시 단 한 번만 표시되므로 안전한 곳에 보관 |
모든 방법은 동일한 파이프라인을 거칩니다. 슬롯이 시크릿을 생성하면 이를 서버가 보유한 시크릿과 결합해 CEK의 래핑을 해제합니다. 어느 한쪽만으로는 충분하지 않으므로 세 방법 모두 영지식 속성을 유지하며, 슬롯 시크릿은 서버에 전달되지 않습니다.
슬롯은 포털의 설정 저장소 페이지에서 관리합니다. 하드웨어 전용 잠금 해제를 원하는 조직은 패스키 필수 정책을 활성화할 수 있으며, 이 정책은 저장소 전체에서 패스키가 아닌 슬롯을 거부하고 취소합니다.
잠금 해제는 기기별로 이루어집니다. 새 기기에서 한 번만 잠금을 해제하면 이후 일상적인 CLI 작업(push/pull)은 패스키를 터치하거나 비밀번호를 입력하지 않아도 작동합니다.
사전 요건
- 계정에서 2단계 인증 활성화
- 패스키 방법의 경우: FIDO2 보안 키(예: YubiKey), iCloud Keychain, Google 비밀번호 관리자, 1Password, Dashlane 등 PRF를 지원하는 패스키 제공자
- 브라우저: Chrome 133+, Edge 133+, Firefox 130+, 또는 Safari 17+
PRF 요건은 패스키 슬롯에만 적용됩니다. 마스터 비밀번호와 복구 코드 방법은 지원되는 모든 브라우저에서 작동합니다.
설정 방법
- 사이드바에서 설정 저장소로 이동한 후 설정 저장소 설정을 클릭하세요.
- 요건 체크리스트가 브라우저, 2FA, 세션 상태를 확인합니다.
- 설정 시작을 클릭하세요. 패스키 슬롯의 경우 보안 키를 두 번 터치해야 합니다.
- 첫 번째 터치: 패스키 등록
- 두 번째 터치: PRF를 통한 암호화 키 파생
- 설정 완료, 패스키 시크릿이 OS 키링에 저장됩니다.
설정을 마친 후에는 설정 저장소 페이지에서 마스터 비밀번호 또는 복구 코드 슬롯을 추가해 두세요. 그러면 인증 수단을 분실하거나 지원되지 않는 인증자를 사용하더라도 잠기지 않습니다.
PRF 제공자 호환성
| 제공자 | PRF 지원 | 플랫폼 |
|---|---|---|
| YubiKey / FIDO2 보안 키 | ✅ | Windows 11, macOS, Linux |
| iCloud Keychain | ✅ | macOS 15+, iOS 18+ |
| Google 비밀번호 관리자 | ✅ | Android |
| 1Password | ✅ | Android, iOS |
| Dashlane | ✅ | 크로스 플랫폼 |
| Bitwarden 확장 | ❌ | 개발 중 |
| Windows Hello | ❌ | 미지원 |
헤드리스 CLI 등록
브라우저가 없는 머신(서버, CI 러너, 실행기 데몬 등)도 마스터 비밀번호 방법으로 기존 저장소에 등록할 수 있습니다.
rdc config remote enable --password
요건:
- 포털을 통해 이미 프로비저닝된 마스터 비밀번호 슬롯 (프로비저닝 과정에서는 브라우저가 키를 보유하므로 이 단계 자체는 헤드리스로 수행할 수 없습니다)
- 호출을 인증할
config:enroll범위를 가진 API 토큰
등록은 읽기 작업입니다. CLI는 슬롯의 공개 KDF 매개변수와 래핑된 키를 가져와 로컬에서 비밀번호 시크릿을 파생시키고, 기기에서 CEK의 래핑을 해제합니다. 이를 통해 해당 기기는 설정을 복호화하고 동기화할 수 있게 되며, 저장소 자체를 변경하지는 않습니다.
활성화와 오프라인 읽기
rdc config remote enable은 활성 설정을 저장소에 연결합니다. 저장소가 비어 있으면 활성화 시 현재 로컬 설정으로 저장소를 초기화합니다: 로컬 리소스가 저장소의 첫 번째 버전으로 푸시된 후 다시 풀되어 라운드트립이 제대로 이루어졌는지 확인합니다. 저장소에 이미 내용이 있으면 활성화는 덮어쓰는 대신 기존 내용과 조정합니다(실제로 내용이 어긋난 경우 --force를 전달하지 않으면 중단됩니다).
활성화 후에는 설정이 완전한 읽기 캐시를 유지하며, 로컬 설정과 동일한 방식으로 저장 시 암호화되므로 계정 서버에 연결할 수 없을 때도 저장소를 계속 사용할 수 있습니다.
- 읽기는 오프라인에서도 동작합니다. 캐시된 내용은 캐시된 버전과 타임스탬프(
cachedVersion/cachedAt)가 표시된 오래됨 경고와 함께 stderr로 제공됩니다. - 쓰기는 서버가 필요하며, 실패 시 안전하게 차단됩니다. 오프라인 쓰기 대기열은 없습니다: 서버에 연결할 수 없는 쓰기는 오류를 내며 해당 서버 이름을 알려줍니다. 쓰기 명령이 성공했다면 그 변경 사항은 반드시 서버에 반영되어 있습니다.
- 두 기기에서의 동시 편집은 리소스 버킷 단위의 풀-리플레이-리푸시로 해결되므로, 다른 곳에서의 동시 편집이 내 변경 사항을 덮어쓰지 않습니다.
키 순환
저장소의 CEK를 순환하면 새로운 세대로 다시 래핑됩니다.
- 복구 코드는 순환 시 항상 무효화되므로, 순환 후 새 코드를 생성하여 보관하세요
- 마스터 비밀번호 슬롯은 순환 마법사에서 비밀번호를 다시 입력한 경우에만 유지됩니다
- 이전 세대에 남겨진 슬롯은 알 수 없는 복호화 오류로 실패하는 대신 오래된 슬롯(stale)으로 표시됩니다
구성원 관리
설정 저장소는 조직 단위로 범위가 지정됩니다. 구성원은 웹 포털을 통해 관리됩니다.
- 구성원 보기: 설정 저장소 → 구성원
- 구성원 추가: 현재 CLI를 통해서만 가능 (웹 UI 계획 중)
- 구성원 제거: 구성원 페이지의 제거 버튼 클릭 (2FA + 재인증 필요)
마지막 활성 구성원을 제거하거나 자기 자신을 제거하는 것을 방지하는 안전 장치가 있습니다.
저장소 내 설정은 팀 단위로도 범위가 지정되지만, 이 범위 지정은 서버 측 접근 제어이며 암호학적 격리가 아닙니다: 조직 전체에 걸쳐 하나의 CEK가 모든 팀의 설정을 암호화하며, 어떤 팀을 구성원이 읽을 수 있는지는 서버가 강제합니다.
보안
- 영지식: 서버는 복호화할 수 없는 삼중 암호화 데이터를 저장합니다.
- 분할 키: 복호화는 슬롯 시크릿(클라이언트)과 서버 시크릿(서버) 모두 필요합니다.
- 순환 토큰: 각 API 호출은 새 토큰을 사용합니다. 이전 토큰은 자동 파기됩니다.
- IP 바인딩: 토큰은 첫 사용 시 IP에 바인딩됩니다.
- 즉각적인 취소: 제거된 구성원은 30초 내에 접근 권한을 잃습니다.
문제 해결
| 오류 | 원인 | 해결 방법 |
|---|---|---|
| PRF 미지원 | 인증자에 PRF 확장 없음 | YubiKey, iCloud Keychain, 1Password, Dashlane을 사용하거나 마스터 비밀번호 슬롯을 추가하세요 |
| X25519 미지원 | 브라우저 버전이 너무 오래됨 | Chrome 133+, Edge 133+, Firefox 130+, 또는 Safari 17+로 업데이트 |
| 이미 설정됨 | 조직에 저장소 이미 존재 | /account/config-storage에서 관리 |
| 설정 저장소 미설정 | 서버에 블롭 스토리지 없음 | 관리자에게 R2/RustFS 설정 문의 |
| 토큰 만료 | 24시간 동안 활동 없음 | 설정 저장소 명령어를 실행하여 갱신 |
| 마지막 구성원 제거 불가 | 저장소가 영구적으로 잠길 수 있음 | 먼저 다른 구성원을 추가하세요 |
| 오래된 슬롯 | 슬롯이 마지막 키 순환 이전에 생성됨 | 슬롯을 다시 추가하세요 (복구 코드는 순환할 때마다 재생성해야 합니다) |