호스티드에서 러너 자격을 클라우드에 절대 올리지 않음 — 선택권이 아니라 구조로 강제 - #325
Merged
Conversation
유건 지시 2026-08-29: "열쇠를 볼 수 있는 건 사용자 본인이어야 한다 — 선택권이 아니라 무조건."
호스티드(Argo 클라우드) 모드에서는 자격 3종(.secrets.json·connections.json·mcp.json)이 어떤
경로로도 클라우드에 올라가지 않도록 구조적으로 강제한다.
- hostedCredsOff() = 세션 모드(호스티드) 판정. syncCompany 내부에서 noSecrets에 OR로 합류 —
강제를 호출부가 아니라 함수 안에 걸어 새 호출 경로가 생겨도 우회 불가(보관 전파가 opts를
빠뜨렸던 HIGH-1 계열의 원천 차단). 회수·불가시·마커 보호 로직 전부 재사용.
- 서비스 모드(셀프호스트·워커 = 자기 인프라·자기 열쇠, 운영자=본인)는 credSync 토글이 그대로
선택권으로 남는다.
- UI: connections route가 credHosted 내림. SyncCard의 CredSyncRow가 호스티드면 토글 대신
"이 기기에만" 배지 + 정직 문구("운영자 포함 본인 외 아무도 볼 수 없음"). 서비스 모드만 토글.
- i18n: offHelp를 모드 무관 참으로 재교정(자격은 클라우드로 안 감), credHostedNote·
credDeviceOnly 신설, credNote는 셀프호스트 전용으로 한정. 전부 ko/en.
- docs/privacy-sync.md 재작성: 자격=호스티드 미동기(본인만) / 회사 데이터=봉투 암호화로 가되
열쇠는 서버(운영자 복호화 가능, E2EE는 별도 트랙)로 범주 분리.
- 테스트 H1·H2: opts·credSync 무관하게 호스티드는 자격 미push + 과거 사본 자동 회수.
함수 내부 게이트 변이 red 실증(H1·H2 red). 기존 PIN/T1~T7은 서비스 모드 의미론으로 명시.
전체 1005/1005 · next build 통과 · 격리 서버(:3113) 호스티드 UI 실측(토글 소거·"이 기기에만").
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
분리 보안 검수 CHANGES_REQUESTED: 코드 강제(함수 내부 게이트)는 견고하나 문구가 코드보다 앞섰다. 코드가 실제 보장하는 것에 정합화한다(근본 코드 수정은 이월 — 아래). - HIGH-2(free 회수 미실행): 호스티드 무료 계정은 cycle에서 syncCompany가 스킵(freePlan && !restoring)되고 RLS도 자격 쓰기를 거부해, 과거 사본 회수가 실행되지 않는다. 절대 문구 "누구도 볼 수 없습니다"를 "새로 저장되는 자격은 …"으로 한정하고, free 회수 보류 caveat 원복 (이전 PR credOffHelp가 이미 알던 HIGH-2 교훈을 호스티드 문구에서 반복하지 않게). - 워커 경로: 워커(ARGO_TENANT_OWNER)는 hostedCredsOff=false라 자격이 갈 수 있는데 문구가 "새 기기와 동일(자격 미도달)"로 서술했다. 워커 언급 제거 — 워커는 자격 접근이 전제인 위임 모델이라 이 보장 밖(별도 설계 트랙)임을 docs에 명시. - credHostedNote(ko/en)·docs/privacy-sync.md 동기 수정. 코드 변경 없음(문구만). 이월(코드 트랙): (1) 무료 상태에서의 즉시 회수 = RLS에 자격-마커 예외(마이그레이션+라이브 검증 필요), (2) 워커 위임 동의 = E2EE 트랙과 함께. 완전한 "모든 과거 사본까지 무조건 본인만"은 이 둘. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
재검수 APPROVED의 LOW 관찰: '표시가 없어도 회수는 진행됩니다' 첫 문장이 단독으로는 무조건형 이라 다음 소제목이 정정하기 전까지 오해 소지. 첫 문장에 '동기화가 도는 상태(Pro·체험)' 조건을 인라인으로 넣어 문장 단독으로도 정확하게. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merged
beyondworks
added a commit
that referenced
this pull request
Aug 29, 2026
beyondworks
added a commit
that referenced
this pull request
Aug 29, 2026
* feat(e2ee): P1 — 켜기·기기 승인(지문 대조)·복구 코드·재봉인·잠김 게이트 권고안 승인분(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> * fix(e2ee): P1 분리 검수 반영 — 세대 다운그레이드 게이트·제거 고지 정정·부분 실패 자가 치유 - 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> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
지시 (유건 2026-08-29)
직전 #323이 넣은 회사 단위 옵트아웃(credSync 토글)을, 호스티드(Argo 클라우드)에서는 구조적 강제로 승격한다.
변경
hostedCredsOff()=!(loadSyncCreds() && serviceCredsAllowed())— 세션 모드(호스티드) 판정(순수 env, 플랜 조회와 독립).syncCompany함수 내부에const noSecrets = !!opts.noSecrets || hostedCredsOff();— 강제를 호출부가 아니라 함수 안에 걸어 새 호출 경로가 생겨도 우회 불가(자격 증명 클라우드 동기화 — 정직 고지 + 회사 단위 옵트아웃(클라우드 사본 회수) #323 검수가 잡은 HIGH-1 계열 원천 차단). 회수·불가시·마커 보호 로직 전부 재사용.credHosted내림. CredSyncRow가 호스티드면 토글 대신 "이 기기에만" + 정직 문구. 서비스 모드만 토글.검수 반영 (2라운드, 최종 APPROVED)
ARGO_TENANT_OWNER)는 hostedCredsOff=false라 자격이 갈 수 있는데 문구가 "새 기기와 동일"로 서술했다. 워커 언급 제거 — 자격 접근이 전제인 위임 모델이라 이 보장 밖(별도 트랙)임을 docs에 명시.코드가 실제 보장하는 것 (검수 확인)
호스티드에서 자격은 free/pro 무관하게 새로 클라우드에 올라가지 않는다 —
hostedCredsOff()가 플랜과 독립이라, syncCompany가 실행되는 모든 인스턴스에서 자격 3종이 불가시. 과거 사본 회수는 Pro·체험 한정(무료는 보류, Pro·체험 복귀 시 실행).이월 (코드 트랙, 문서에 명시)
검증
전체 1017/1017 · next build · 격리 서버(:3113) 호스티드 UI 실측(토글 소거·"이 기기에만"). 분리 보안 검수 2라운드 APPROVED. 라이브 Supabase RLS 응답은 미검증(SQL 원문·코드 경로 추적 — 자격 없음).
🤖 Generated with Claude Code