1. 암호화된 데이터 검색의 딜레마
Humadroid는 SOC 2 컨트롤 관리 및 보안 문서화를 돕는 플랫폼으로, 민감한 정보는 Rails의 encrypts 지시어를 통해 애플리케이션 계층에서 암호화됩니다. 이는 DB가 유출되어도 평문이 노출되지 않는 강력한 보안을 제공하지만, SQL 수준에서 ILIKE와 같은 검색 쿼리를 사용할 수 없게 만듭니다. 수백 개의 규제 항목 중 특정 내용을 빠르게 찾아야 하는 사용자에게 검색 부재는 심각한 사용성 저하를 초래하며, 이는 감사 준비 과정에서 큰 병목 현상을 일으킵니다.
2. 기술적 대안 검토 및 선택
필자는 다음 네 가지 옵션을 검토했습니다: * 클라이언트 측 검색: 모든 데이터를 브라우저로 가져와 복호화 후 검색하는 방식이나, 데이터 규모 확장 시 성능이 급격히 저하됩니다. * 검색 가능 암호화(Searchable Encryption): 동형 암호화 등 학술적 연구 단계의 기술로, 스타트업이 도입하기에는 라이브러리의 성숙도가 낮고 복잡합니다. * 블라인드 인덱스(Blind Index): HMAC 해시를 사용하며 정확한 일치 검색에는 유용하지만, 부분 일치나 전문 검색에는 부적합합니다. * 복호화 후 별도 인덱싱: 데이터를 복호화하여 토큰화한 뒤 검색 전용 테이블에 저장하는 방식으로, 보안과 성능의 균형을 위해 이 방식을 최종 선택했습니다.
3. 검색 인덱스 아키텍처 설계
검색 시스템은 원본 데이터와 완전히 분리된 별도의 search_index 테이블을 사용합니다.
* 데이터 구조: 다형성 관계(Polymorphic)를 통해 다양한 모델을 참조하며, tsvector 타입을 사용하여 형태소 분석된 토큰을 저장합니다.
* 가중치 시스템: 제목(A), 식별자(A), 구현 노트(B), 설명(C) 등 필드별로 가중치를 부여하여 검색 결과의 정확도를 높였습니다.
* 성능 최적화: 검색 결과 화면을 즉시 렌더링하기 위해 제목(Title)과 URL 경로를 미리 계산하여 저장함으로써 검색 시 원본 레코드를 복호화하는 오버헤드를 제거했습니다.
* Rails Concern 활용: Searchable 모듈을 통해 모델의 라이프사이클(after_commit)에 따라 인덱스를 자동으로 업데이트하며, 특정 컬럼이 변경될 때만 재인덱싱을 수행하여 오버헤드를 최소화합니다.
4. 보안 및 감사(Audit) 대응 전략
보안성을 높이기 위해 다음과 같은 계층적 방어 체계를 구축했습니다:
* 조직별 선택제(Opt-in): 모든 고객에게 강제 적용하는 대신, 관리자가 명시적으로 검색 기능을 활성화해야만 인덱싱이 시작됩니다.
* 즉각적인 데이터 파기: 기능을 비활성화하는 즉시 해당 조직의 모든 인덱스 데이터가 SQL DELETE 문으로 완전히 삭제됩니다.
* 토큰화 저장: 인덱스에는 문장 전체가 아닌 어근(Stem) 단위의 토큰만 저장되므로, 인덱스 정보만으로는 원본 문장을 완벽히 복원할 수 없습니다.
* 다중 보안 계층: 계층별 멀티테넌시 격리, RBAC(역할 기반 접근 제어), 저장 시 암호화(Encryption at Rest), 전송 시 암호화(TLS)를 결합했습니다.
5. 검색 알고리즘: 전문 검색과 퍼지 검색의 결합
단순한 키워드 매칭을 넘어 사용자 경험을 극대화하기 위해 이중 전략을 사용합니다:
1. Full-Text Search: PostgreSQL의 접두사 매치(:*)와 ts_rank_cd를 사용하여 관련성 높은 결과를 먼저 도출합니다.
2. Fuzzy Search: 첫 번째 단계에서 결과가 없을 경우, pg_trgm을 활용한 삼중음자(Trigram) 유사도 검색을 수행하여 오타가 포함된 검색어에도 유연하게 대응합니다.