Skip to content

E2EE P1 — 켜기·기기 승인(지문 대조)·복구 코드·재봉인·세대 게이트 - #328

Merged
beyondworks merged 2 commits into
mainfrom
feat/e2ee-p1
Aug 29, 2026
Merged

E2EE P1 — 켜기·기기 승인(지문 대조)·복구 코드·재봉인·세대 게이트#328
beyondworks merged 2 commits into
mainfrom
feat/e2ee-p1

Conversation

@beyondworks

Copy link
Copy Markdown
Owner

목적

E2EE 단계 1(옵트인) — P0(#327)의 기기 키쌍·v3 봉투 위에서, 계정이 실제로 "본인만 여는" 상태로 전환하는 실행 코드. 설계 정본 E2EE-DESIGN.md §6~§7.

변경

  • 켜기(enable): 이 기기가 DEK 생성 → 자기 랩·복구 랩을 서버 기록(전부 암호문, 성공 후에만 로컬 확정) → 전 회사 재봉인. 복구 코드 1회 표시·서버 무저장. 플랜 게이트(Pro·체험 — free는 재봉인이 RLS에 막혀 거짓 활성이 되므로 정직 차단). 반쪽 잔재 자가 치유(자기 랩 존재 시 같은 DEK 이어가기).
  • 기기 승인(approve): 지문(SAS) 대조 확인 모달 → DEK 보유 기기가 대상 공개키로 랩 → 새 기기는 claim(cycle 60초 자동 포함)으로 잠김 해제. 복구 코드 폴백(recover, scrypt·관용 정규화·5초 스로틀).
  • v3 전량 봉인 + 세대 게이트: DEK 보유 기기는 파일·매니페스트 전부 v3. 매니페스트 봉인 = 열쇠 없는 기기(구버전 포함)의 회사 단위 안전 보류. 재읽기에서 "받았는데 열 수 없는 봉투 세대"를 만난 사이클은 평문을 되쓰지 않고 보류(검수가 실행으로 증명한 다운그레이드 창 봉쇄 — 네트워크 실패·평문 손상 관용은 유지).
  • 재봉인(reseal): 무변경 파일 포함 1회 강제 push(메타·base 불변 — 타 기기 diff 무영향), 파일 실패 0일 때만 완결(부분 실패 = 마커 잔존 재시도).
  • 기기 제거(revoke): 정직 고지 — "새 열쇠 미배포일 뿐, 이미 받은 기기는 로컬 열쇠+세션 생존 시 계속 열림. 실효 조치 = 세션 차단"(danger 확인 모달). pubkey 최초 등록 후 불변(하이재킹 차단). 열쇠 회전은 후속 트랙.
  • UI: 설정 E2EE 카드(꺼짐/잠김/켜짐), i18n ko/en 전량.

검증

  • 행동 테스트 7종 + 변이 red 3종(sealFor dek 분기·reseal 분기·세대 게이트). 전체 스위트 fail 0 · next build 통과.
  • 분리 보안 검수 2라운드 → APPROVED: HIGH-1(게이트 다운그레이드)·HIGH-2(제거 고지 거짓)를 검수가 실행으로 증명 → 반영 → 검수가 자기 재현 스크립트로 재실행해 닫힘 확인(원격 v3 유지·관용 케이스 오차단 없음·MEDIUM-1 키 교체 서브케이스 안전까지).

롤아웃·미검증(정직 표기)

  • 이 코드는 동승만 하며 켜기 전까지 동작 불변. 실제 켜기는 사용자의 전 기기가 P0+ 버전으로 업데이트된 뒤가 안전(구버전·미승인 기기는 잠김 보류 — 설계된 상태).
  • 미검증: 라이브 Supabase에서의 실제 켜기·승인 왕복(배포 후 실기기 검증 예정), 브라우저 UI 렌더(상주 배포 후 확인), "비밀번호 변경 = 타 세션 무효화" 파생 안내의 auth 동작(검수 미확인 표기 — 문구는 일반 원칙 수준).

🤖 Generated with Claude Code

beyondworks and others added 2 commits August 29, 2026 13:44
권고안 승인분(E2EE-DESIGN.md §6~§7)의 단계 1 실행 코드. DEK 보유가 곧 스위치(디스크 사실 파생).

- 켜기(enable): 이 기기가 DEK 생성 → 자기 랩(wrapped_deks)·복구 랩(recovery_wraps) 서버 기록(전부
  암호문) → 성공 후에만 로컬 DEK 확정(반쪽 활성 방지) → 전 회사 재봉인 마커 + nudge. 복구 코드는
  1회만 반환·서버 무저장. 플랜 게이트(Pro·체험 — free는 재봉인 push가 RLS에 막혀 "켰는데 암호화
  안 됨"이 되므로 사전 정직 차단, #325 HIGH-2 원칙).
- 기기 승인(approve): DEK 보유 기기가 대상 공개키로 랩해 wrapped_deks에 기록. 사용자는 양 화면의
  지문(SAS) 대조 후 승인 — 서버의 공개키 바꿔치기는 지문 불일치로 드러난다. 새 기기는 claim
  (자기 랩 회수·cycle 60초 자동 시도)으로 잠김 해제. 복구 코드 폴백(recover) 포함.
- v3 전량 봉인: DEK 보유 기기의 push는 파일·매니페스트 전부 v3. **매니페스트 봉인이 곧 게이트** —
  열쇠 없는 기기(구버전 포함)는 매니페스트 개봉이 보류로 떨어져 회사 동기화가 통째로 안전 정지
  (파일 단위 오염·오삭제 원천 불가, 기존 "매니페스트 읽기 실패 보류" 경로 재사용).
- 재봉인(reseal): 켠 직후 1회, 무변경 파일도 blob을 v3로 되덮음(메타·base 불변 — 타 기기 diff
  무영향). WS_ROOT 마커(.e2ee-reseal.json, 셸 금고 등재)로 회사별 재시도.
- 기기 제거(revoke): 랩·공개키 행 삭제(재등록 가능). DEK 회전은 후속 — UI가 사실 그대로 고지.
  pubkey 최초 등록 후 불변(ignoreDuplicates — §10.5 하이재킹 차단), keyMismatch 정직 표기.
- UI: 설정 E2EE 카드(꺼짐/잠김/켜짐 3상태, 구버전 확인 체크, 복구 코드 1회 모달, 지문 대조 안내).
  i18n ko/en 전량.
- 테스트 6종(복구 왕복·관용 입력·지문·claim·v3 전환·잠김 보류·재봉인) + 변이 red 2종(sealFor
  dek 분기·reseal 분기).

전체 스위트 fail 0 · next build 통과. 라이브(상주) 검증은 배포 후: 카드 렌더·GET 계약 확인 —
실제 켜기는 전 기기 업데이트 후 유건 판단(구버전 혼재 시 그 기기 동기화가 잠김 상태로 정지).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- HIGH-1(실증됨): 열쇠 없는 기기의 정상 사이클이 재읽기에서 v3 매니페스트를 만나도 catch로 삼키고
  자기 평문 매니페스트를 되써 게이트를 다운그레이드했다. 재읽기를 두 단계로 분리 — 네트워크 실패는
  기존 관용, **받았는데 열 수 없는 봉투 세대(isEnvelopeGeneration)는 사이클 전체 보류**(다음 사이클
  초기 읽기가 정식 잠김 경로로 수렴). 회귀 테스트 = 검수 재현 시나리오 그대로(초기 읽기 1회 평문·
  재읽기 v3 → 보류 + 원격 v3 유지), 게이트 제거 변이 red 실증.
- HIGH-2: 기기 제거 고지가 사실과 반대("새 동기화를 열 수 없게 됩니다")였다 — 행 삭제는 "새 열쇠
  미배포"일 뿐, 이미 열쇠 받은 기기는 로컬 열쇠+세션이 살아있는 한 계속 연다. 문구를 사실대로
  정정하고 실효 조치(세션 차단·비밀번호 변경)를 안내. 제거·승인에 확인 모달(승인 = 지문 대조 확인).
- MEDIUM-1: enable 반쪽 잔재(자기 랩만 기록 후 복구 랩 실패)가 "다른 기기에서 켜짐" 오판으로 영구
  교착 — 판정에서 자기 행 제외 + 자기 랩 존재 시 openDekWrap로 같은 DEK 이어가기(재시도 = 자가 치유).
- MEDIUM-2: 재봉인 완결을 파일 실패 0으로 조건화 — 종전엔 개별 push 실패 파일이 영구 구세대로
  남았다(마커 잔존 → 회사째 재시도).
- LOW: recover 5초 스로틀(scrypt CPU 증폭 방지), TRIAL_DAYS 상수 사용(하드코딩 드리프트 제거).

테스트 7/7(세대 게이트 신설 포함) · 전체 스위트 fail 0 · next build 통과.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@beyondworks
beyondworks merged commit 74f0e7f into main Aug 29, 2026
2 checks passed
@beyondworks
beyondworks deleted the feat/e2ee-p1 branch August 29, 2026 05:14
beyondworks added a commit that referenced this pull request Aug 29, 2026
…터 카드 표시 언어 (#327·#328·#322) (#329)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant