Technical & Security Whitepaper

신뢰는 기능이 아니라
아키텍처에서 나옵니다.

클리닉톡은 환자의 민감한 의료 문의와 병원의 운영 데이터를 다룹니다. 본 문서는 클리닉톡이 데이터 격리·접근 통제·개인정보 보호·의료법 준수를 어떻게 코드와 인프라 계층에서 구조적으로 다루는지를 기술적으로 설명합니다.

대상 · 병원 의사결정자 및 보안 검토 담당자 범위 · 데이터 격리 · 남용 방어 · PII · 안정성 최종 갱신 · 2026

방어는 한 겹이 아니라, 여러 계층으로 중첩됩니다.

클리닉톡은 단일 병원이 아니라 다수의 병원이 하나의 인프라를 공유하는 멀티테넌트(multi-tenant) SaaS입니다. 이 구조에서 가장 중요한 것은 다른 병원의 데이터가 노출되지 않도록 여러 계층에서 방어하는 것입니다.

클리닉톡은 이를 운영 정책이나 사람의 주의에 의존하지 않습니다. 대신 데이터베이스(인프라) 계층애플리케이션(코드) 계층 양쪽에 독립적인 방어선을 두어, 어느 한쪽에 실수가 있어도 다른 한쪽이 차단하도록 설계했습니다. 아래 네 가지가 그 핵심 가드레일입니다.

본 백서는 도입 검토를 위한 기술 설명 자료이며, 실제 운영 환경에서는 백업·접근권한·로그 정책을 병원별 운영 상황에 맞춰 함께 점검합니다.

GUARDRAIL 01

멀티테넌트 데이터 다층 격리

Multi-tenant Isolation

모든 병원 데이터(문의 내역·설정·FAQ)는 병원 식별자(clinic_id)로 구분됩니다. 클리닉톡은 이 격리를 인프라와 애플리케이션 두 계층에서 이중으로 강제하여, 구조적으로 크로스 테넌트(cross-tenant) 오염을 차단합니다.

인프라 계층

Row Level Security (RLS)

데이터베이스(Supabase/PostgreSQL)의 행 단위 보안 정책을 전 테이블에 적용했습니다. 인증되지 않은 접근은 전면 차단되며, 인증된 사용자도 user_can_access_clinic() 검증을 통과한 본인 소속 병원의 행만 조회·수정할 수 있습니다. 데이터 쓰기(INSERT) 권한은 서버 측 신뢰 경로로만 제한됩니다. 데이터베이스는 국내(서울) 리전에서 운영됩니다.

애플리케이션 계층

clinicScoped Fail-fast 가드

서버 코드의 모든 데이터 접근은 clinicScoped() 헬퍼를 거칩니다. 이 헬퍼는 쿼리마다 clinic_id 조건을 자동으로 주입하고, 식별자가 누락되면 즉시 예외를 발생(fail-fast)시켜 처리를 중단합니다. "조건을 빠뜨려 다른 병원 데이터가 새는" 실수가 애초에 코드 단에서 불가능합니다.

🛡️
결과 — 인프라(RLS)와 코드(clinicScoped)가 서로를 보완합니다. 한 계층에 결함이 있어도 다른 계층이 검증하므로, 단일 실수로 인한 데이터 노출 위험을 크게 낮춥니다.
GUARDRAIL 02

API 남용 및 무단 임베드 방어

Anti-Abuse & Cost Protection

AI 응답은 호출당 비용이 발생합니다. 따라서 무단으로 위젯을 복제·임베드해 트래픽과 비용을 탈취하려는 시도를 막는 것이 중요합니다. 클리닉톡은 두 가지 독립적인 방어선으로 허가되지 않은 출처의 요청을 차단합니다.

요청 계층

Origin 기반 도메인 화이트리스트

챗봇 API는 매 요청의 Origin/Referer 출처를 병원별 허용 도메인 목록과 실시간 대조합니다. 등록되지 않은 도메인에서의 호출은 응답 생성 이전에 HTTP 403으로 즉시 차단(fail-fast)되어, AI 호출 비용이 발생하지 않습니다.

브라우저 계층

Content Security Policy (frame-ancestors)

챗봇 페이지 응답에 frame-ancestors CSP 헤더를 실어, 허가된 부모 사이트가 아니면 브라우저가 위젯의 렌더링 자체를 거부합니다. 무단 사이트에서는 위젯이 뜨지 않으므로 API 호출이 0건이 됩니다. 헤더 조회 실패 시에도 기본 출처만 허용하는 안전 우선(fail-safe) 정책으로 동작합니다.

🛡️
결과 — 직접적인 API 호출은 Origin 검증이, 브라우저 임베드는 CSP가 걸러냅니다. 서로 다른 경로를 각각 방어해 무단 트래픽과 비용 남용 가능성을 구조적으로 낮춥니다.
GUARDRAIL 03

민감 개인정보(PII) 전송 전 마스킹

Data Privacy by Design

클리닉톡은 환자의 개인 식별 정보가 외부 LLM(Claude) 서버로 전송되기 전에, 서버리스 파이프라인 내부에서 마스킹 처리합니다. 개인정보 노출을 사람의 주의가 아니라 데이터 흐름의 구조에서 줄이는 방식입니다.

환자 입력 정규식 PII 탐지·마스킹 LLM 처리 응답

이름·전화번호·주민등록번호·생년월일 등은 서버에 도달하는 즉시 정규식(Regex) 기반 탐지 엔진이 식별해 [이름]·[전화번호] 같은 라벨로 치환합니다. 마스킹된 텍스트만 외부 AI로 전달되며, 저장되는 문의 기록에도 동일하게 마스킹된 형태로 남습니다. 개인 식별 정보가 다수 포함된 문의는 AI가 답하지 않고 직원 확인 경로로 전환됩니다.

🔒
결과 — 탐지된 개인정보는 외부 AI 서버로 전달되지 않습니다. 컴플라이언스를 사후 점검이 아니라 전송 전 단계에서 구조적으로 다룹니다.
GUARDRAIL 04

의료법 가드레일 및 인프라 안정화

Safety & Stability

의료 정보는 잘못된 답변이 곧 위험으로 이어집니다. 클리닉톡은 의료법 준수 규칙을 관리자가 편집할 수 없는 코어단에 고정하고, 장애 상황에서도 환자가 방치되지 않도록 안정화 로직을 갖췄습니다.

안전성

진료과별 가드레일 프롬프트 고정

증상·진단·검사결과처럼 의료 판단이 필요한 영역은 진료과별 시스템 가드레일이 코드 코어단에 고정되어 자동으로 직원 확인 또는 내원 안내로 전환됩니다. 이 규칙은 병원 관리자도 수정할 수 없으며, "이전 지시를 무시하라"는 식의 프롬프트 인젝션 시도에도 역할을 고수하도록 방어 규칙이 포함되어 있습니다.

안정성

타임아웃 확장 & Graceful Fallback

서버리스 함수의 실행 시간을 maxDuration 60s로 확장해, 응답이 길어질 때 강제 종료되는 것을 방지합니다. 그럼에도 지연·장애가 발생하면, 오류를 그대로 노출하지 않고 "문의량이 많아 연결이 지연되고 있습니다. 급하신 문의는 병원으로 전화 부탁드립니다" 라는 우아한 예외 안내(graceful fallback)를 제공합니다.

🩺
결과 — 위험한 의료 답변이 나갈 가능성을 구조적으로 낮추고, 시스템 장애 시에도 환자는 명확한 대안(전화 안내)을 받습니다. 안전과 안정성을 함께 고려한 설계입니다.

더 자세한 기술 검토가 필요하신가요?

보안 실사·기술 검토 요청을 포함해, 도입 관련 문의에 1영업일 이내 답변드립니다.

도입 문의하기 →