FadeKey: 제로 지식·자동 소멸 비밀 공유 엔진

발행: (2026년 6월 7일 AM 06:57 GMT+9)
7 분 소요
원문: Dev.to

출처: Dev.to

FadeKey: 영지식(zero‑knowledge) 및 자동 소멸 비밀 공유 엔진의 표지 이미지

Julian Geiger Nunes

GitHub “Finish‑Up‑A‑Thon” 챌린지 제출

이 글은 GitHub Finish‑Up‑A‑Thon 챌린지 제출물입니다.

제가 만든 것

FadeKey는 영지식(zero‑knowledge) 기반 자동 소멸 비밀 공유 엔진입니다. 브라우저에서 AES‑GCM으로 완전히 암호화되며, 복호화 키는 URL 해시 조각(#key=...)에만 존재합니다. 브라우저는 HTTP 요청에 해시 조각을 포함하지 않기 때문에 서버는 키도 평문도 절대 보지 못합니다.

프로젝트는 두 개의 독립된 구성 요소로 나뉩니다:

  • 공개 오픈소스 코어: 자체 호스팅 및 파이프라인/CLI 자동화를 위한 무상태 Fastify API와 SDK 패키지.

  • 비공개 SaaS 대시보드: 사용자 계정, Postgres 데이터베이스 동기화, 영구 감사 로그, Stripe 구독 관리 기능을 갖춘 상용 Nuxt 4 웹 앱.

데모

실제 사이트 (비공개 SaaS): https://fadekey.app/

GitHub 저장소 (오픈소스 코어): https://github.com/fadekey-app/fadekey.api

복귀 스토리

보안 결함이 심각하고 기능이 미완성이며 상태가 새는 미완성 프로토타입을 되살렸습니다. 전·후 과정을 살펴보세요.

1. 활성 폐기 (SDK & API 코어)

  • 전: 비밀은 TTL이나 조회 제한으로만 만료될 수 있었습니다. 백엔드에는 삭제 엔드포인트가 없었고, @fadekey/sdk에는 revoke()가 들어갈 자리만 빈 placeholder가 있었습니다.
  • 후: Fastify API에 소유자 검증을 포함한 안전한 DELETE /api/items/:id 라우트를 구현했고, SDK 패키지에 대응하는 revoke(id) 메서드를 추가했습니다.

2. QR 코드 영지식 준수 (UX/보안)

  • 전: 프로토타입은 외부 공개 API를 이용해 QR 코드를 생성하도록 제안했습니다. 하지만 #key 해시가 포함된 전체 비밀 URL을 제3자 서버에 전송하는 것은 영지식 원칙에 위배됩니다.
  • 후: qrcode 라이브러리를 사용해 브라우저에서 100 % 로컬로 QR 코드를 렌더링하도록 전환해, 복호화 키가 절대 클라이언트를 떠나지 않게 했습니다.

3. 로컬‑투‑클라우드 환경설정 동기화

  • 전: 페이지를 새로 고치면 사용자는 테마(다크/라이트)와 로케일(en/es/pt‑BR) 설정을 잃었고, 등록된 사용자에게 이 설정을 영구 저장할 방법이 없었습니다.
  • 후: 이중 영속성 시스템을 구축했습니다. 익명 사용자는 쿠키/localStorage에 설정을 저장하고, 인증된 사용자는 새로운 PATCH /api/auth/preferences 엔드포인트를 통해 선택 사항을 PostgreSQL 데이터베이스에 자동 동기화합니다.

4. 중요한 Nuxt SSR 세션 누수 (대규모 버그 수정)

  • 전: 인증 상태가 전역 반응형 싱글톤에 보관되었습니다. 서버‑사이드 렌더링(SSR) 중 이 객체가 공유돼 한 사용자의 세션/토큰이 완전히 다른 방문자의 요청에 노출되어 보안 위험과 하이드레이션 오류가 발생했습니다.
  • 후: 인증 composable을 요청 격리된 Nuxt useState 래퍼에 저장하도록 리팩터링해, 각 클라이언트마다 메모리가 샌드박스되도록 보장했습니다.

5. 전환 마무리 및 리다이렉션 보호

  • 전: 로그아웃 시 대시보드 페이지가 빈 값과 0을 즉시 표시한 뒤 리다이렉트되었습니다. 리다이렉션 과정에서 활성 언어 접두사(pt‑BR 등)가 사라져 /pt‑BR/app/dashboard/ 로 잘못 이동했습니다.
  • 후: signOut()에서 라우터 네비게이션이 완료될 때까지 상태 파괴를 연기했으며, router.afterEach에서 nextTick + 150 ms 지연을 두어 DOM이 마운트될 시간을 확보했습니다. 모든 리다이렉트를 localePath()로 감싸 언어 일관성을 유지했습니다.

GitHub Copilot 사용 경험

GitHub Copilot은 이번 스프린트 동안 핵심 파트너 역할을 했으며, 특히 다음 영역에서 큰 도움이 되었습니다.

  • SSR 안전성을 위한 인증 리팩터링: Copilot은 Nuxt에서 초기 모듈‑레벨 싱글톤 상태가 위험함을 인식하고, 요청‑스코프 useState 훅으로 마이그레이션하는 코드를 초안으로 제공했습니다.

  • Vitest 테스트와 Testcontainers: 백엔드 통합 테스트 작성을 가속화해, Docker Testcontainers를 이용해 모의 Postgres와 Redis 인스턴스를 자동 생성하고, 레이트‑리밋 및 할당량 롤백 시나리오를 검증했습니다.

  • 클라이언트‑사이드 암호화 파이프라인: Copilot은 Web Crypto API 호출을 구조화하고, PBKDF2를 사용해 비밀번호 해시를 올바르게 파생시키는 코드를 작성하도록 도와, 동기식 차단 없이 안전한 암호화를 구현했습니다.

0 조회
Back to Blog

관련 글

더 보기 »

모바일 한여름 열풍

!Cover image for Mobile Midsommer Madnesshttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploa...