글 목록

메시지 버스의 하드닝과 방 멤버십 인가 게이트

STOMP의 한계를 넘어 REST 기반 내부 발행으로 보안 경계를 재정의하고, 메시지 버스 운영의 안정성과 실시간 통신의 신뢰성을 동시에 확보한 결정 과정을 다룹니다.

주재범5분 읽기

서론

대규모 실시간 통신 시스템은 종종 두 가지 상충되는 요구사항에 직면한다. 하나는 메시지 유실 없이 무한대에 가까운 트래픽을 견뎌야 하는 운영 안정성이고, 다른 하나는 방마다 다른 접근 권한을 엄격하게 강제하는 보안이다. STOMP 프로토콜은 실시간성에 유리하지만, 복잡한 인증 로직을 연결하기에는 구조적 한계가 명확하다. 특히 내부 서비스 간 통신과 외부 클라이언트의 실시간 요청을 같은 경로로 처리할 때, 보안 경계가 모호해지고 장애 반경이 넓어지는 문제가 발생한다. 이 글은 물류 플랫폼의 메시지 버스 인프라를 설계하며, 운영의 안정성을 확보하고 보안 경계를 명확히 하기 위해 내린 기술적 판단을 서술한다.

한 줄 요약: 메시지 버스의 하드닝으로 운영 안정성을 확보하고, STOMP의 한계를 REST 기반 내부 발행과 방 멤버십 게이트로 재정의하여 보안 경계를 명확히 했다.

제약

시스템의 변경은 기존 아키텍처의 제약 안에서만 가능하다. 이번 설계에서는 다음과 같은 경계 조건을 준수했다.

  • 운영 부담 최소화: 메시지 유실과 중복 전송을 방지하되, 장애 시 전체 시스템이 마비되지 않도록 실패 격리(Fail-open) 전략을 적용해야 했다.
  • 보안 경계 명확화: 외부 클라이언트의 실시간 통신과 내부 서비스의 상태 신호(예: 방 종료)를 분리하여, 한쪽의 장애가 다른 쪽의 보안에 영향을 주지 않도록 했다.
  • 레거시 호환성: 기존 클라이언트와의 호환성을 유지하면서, 새로운 보안 모델(멤버십 인가)을 점진적으로 도입해야 했다.

선택지

보안 경계와 운영 안정성을 확보하기 위해 고려한 대안들은 다음과 같다.

  • STOMP 프로토콜 내 인증 로직 강화
  • 장점: 추가적인 네트워크 홉 없이 실시간 통신을 유지할 수 있다.
  • 단점: 프로토콜 레벨에서 복잡한 인증 로직을 구현하면 코드 복잡도가 급증하고, 장애 시 디버깅이 어렵다. 또한, 내부 서비스 간 통신에도 같은 경로를 사용해야 하므로 보안 경계가 모호해진다.
  • REST 기반 내부 발행 + WebSocket 연결 분리
  • 장점: 내부 서비스 간 통신은 REST를 통해 명확한 인증(X-Internal-Token)을 적용할 수 있고, 외부 클라이언트는 실시간 통신에 집중할 수 있다. 장애 반경을 분리할 수 있다.
  • 단점: 추가적인 네트워크 홉으로 인한 지연이 발생할 수 있으며, 내부 서비스 간 통신의 신뢰성을 보장하기 위한 추가적인 하드닝이 필요하다.
  • 전역 멤버십 인가 게이트 적용
  • 장점: 모든 방에 대해 일관된 보안 정책을 적용할 수 있다.
  • 단점: 다중 테넌트 환경에서 타 테넌트의 방 조회 시 404 오류가 발생하여 시스템 전체가 마비되는 위험이 있다. groupKey 단위로 제한해야 한다.

결정

운영 안정성과 보안 경계를 명확히 하기 위해 메시지 버스의 하드닝REST 기반 내부 발행을 선택했다.

메시지 버스의 하드닝은 운영의 기본을 다지는 작업이다. 메시지 유실과 중복 전송을 방지하기 위해 at-least-once 실행을 구현하고, 실패 시 DLQ로 격리하는 전략을 적용했다. 또한, 메시지 버스의 가용성을 높이기 위해 replica 2 구성과 힙 메모리 최적화를 진행했다. 이러한 하드닝은 시스템의 안정성을 확보하는 데 필수적이다.

보안 경계 재정의는 내부 서비스 간 통신을 REST로 분리하는 결정이다. 기존에는 내부 서비스 간 상태 신호(예: 방 종료)를 Redis에 직접 쓰기だったが, 이는 보안 경계를 모호하게 했다. 이를 해결하기 위해 POST /internal/chat/{groupKey}/{roomId}/close 엔드포인트를 신설하고, X-Internal-Token을 통한 인증을 적용했다. 이로 인해 내부 서비스 간 통신의 인증과 인가가 명확해졌고, 장애 반경도 분리되었다.

방 멤버십 인가 게이트는 STOMP 프로토콜의 한계를 넘어선 보안 구조다. 기존에는 STOMP CONNECT 단계에서 인증만 수행하고, SUBSCRIBE/SEND 단계에서는 멤버십 검증이 없었다. 이를 해결하기 위해 UserInterceptor에서 CONNECT 시 memberId를 세션에 저장하고, SUBSCRIBE/SEND 시 Redis를 통해 멤버십을 검증하도록 개선했다. 다만, 다중 테넌트 환경에서의 404 오류 문제를 방지하기 위해 groupKey 단위로 인가를 한정했다.

핵심 판단: 운영의 안정성은 하드닝으로, 보안의 명확성은 구조적 분리로 확보한다.

결과와 한계

  • 얻은 것: 메시지 유실과 중복 전송이 제거되었고, 내부 서비스 간 통신의 보안 경계가 명확해졌다. 방 멤버십 인가로 인한 IDOR 취약점이 해소되었다.
  • 잃은 것: 내부 서비스 간 통신에 REST를 사용함으로써 추가적인 네트워크 홉으로 인한 지연이 발생했다. 또한, 다중 테넌트 환경에서의 멤버십 인가 로직이 복잡해졌다.
  • 되돌릴 조건: REST 기반 내부 발행의 지연이 실시간 통신의 SLA를 초과하거나, 다중 테넌트 환경에서의 멤버십 인가 로직이 유지보수 비용보다 커질 경우 재고려해야 한다.

다른 시스템에 적용할 때: 메시지 버스의 하드닝은 운영 안정성을 위해 필수적이며, 보안 경계는 구조적 분리를 통해 명확히 해야 한다. 다중 테넌트 환경에서는 인가 로직의 범위를 신중하게 한정해야 한다.

팀에 남긴 규칙 한 줄: 내부 서비스 간 통신은 반드시 REST를 통해 명확한 인증을 적용한다. 이 결정을 다시 봐야 할 조건: 실시간 통신의 SLA를 초과하거나, 다중 테넌트 환경에서의 멤버십 인가 로직이 유지보수 비용보다 커질 경우.

이 글 공유
LinkedInThreadsX