Slack 비디오 임베드 활용한 종단 간 암호화

클라이언트 측 실행을 위한 Slack 비디오 블록

Slack의 비디오 블록 내 video_url 필드는 런타임 콘텐츠 검증이 없기 때문에 임의의 클라이언트 측 코드를 실행할 수 있습니다. 비디오 임베드를 위해 설계되었지만, 플랫폼은 제공된 URL이 접근 가능하고 2xx 또는 3xx HTTP 응답 코드를 반환하는지만 확인합니다. 검증이 완료되면 콘텐츠는 단순한 iframe으로 렌더링되어 개발자가 Slack 인터페이스 내에서 직접 맞춤형 웹 애플리케이션을 로드할 수 있게 됩니다.

Slack에서 종단 간 암호화 (E2EE) 구현

비디오 블록의 iframe 기능을 활용하면 암호화 키를 전적으로 클라이언트 측에서만 처리하도록 시스템을 구축할 수 있어, 서버가 복호화된 개인 키를 절대 보지 않게 됩니다. 구현은 브라우저의 Subtle Crypto API와 openpgpjs 라이브러리(Proton이 유지 관리)를 사용해 복잡한 암호 연산을 수행합니다.

E2EE 워크플로우

암호화된 메시지를 보내는 과정은 다음 단계로 이루어집니다:

  1. 시작: 사용자가 /e2ee send 명령을 실행하면 수신자를 선택할 수 있는 Slack 모달이 열립니다.
  2. 슬러그 생성: 서버는 작성자의 암호화된 개인 키와 수신자들의 공개 키를 포함하는 고유 슬러그를 생성하고 이를 KV 데이터베이스에 저장합니다.
  3. 클라이언트 로드: 사용자가 비디오 블록과 상호작용하면 로컬 클라이언트가 해당 슬러그와 연결된 데이터를 로드합니다.
  4. 로컬 복호화: 작성자는 패스프레이즈를 사용해 로컬에서 자신의 개인 키를 복호화합니다.
  5. 로컬 암호화: 작성자는 메시지를 작성하고, 수신자를 위해 암호화하며, 자신의 키로 서명합니다—모두 iframe 내부에서 로컬로 수행됩니다.
  6. 전송: 암호화된 ciphertext만 서버로 전송됩니다.
  7. 전달: 서버는 암호화된 메시지를 포함한 "envelopes"를 수신자에게 전달합니다.

기술적 제약 및 구현 세부 사항

  • TypeScript: 프로젝트는 빠른 반복을 위해 TypeScript로 개발되었습니다.
  • Ephemeral Message 제한: 비디오 블록은 일시적인 메시지에 포함될 수 없으며, 이는 Slack 공식 Block Kit 문서에 명시되지 않은 동작입니다.
  • 데이터 저장: 서버 측 데이터 보유를 최소화하기 위해 슬러그 기반 시스템을 사용해 필요한 암호화 데이터를 클라이언트 측 iframe으로 전달합니다.
  • Node.js 통합: 프로젝트는 최신 Node.js 버전이 제공하는 기본 .env 파일 지원을 활용해 환경 구성을 관리합니다.

프로젝트 제공 및 준수

이 구현의 소스 코드는 github.com/v1ctorio/e2ee-slack에서 확인할 수 있습니다. 작성자는 이 접근 방식이 Slack 비디오 블록의 설계 제약을 엄격히 따르지는 않기 때문에 "해킹"이라고 언급합니다. 이는 Discord의 "Activities"나 Telegram의 "Mini Apps"와 같은 보다 유연하고 완전한 앱 통합의 필요성을 보여주는 개념 증명입니다.

Sources