← 보안 페이지로
SECURITY WHITE PAPER

MeshLaw 보안 백서

2026-05-21 v0.1 · 법무·IT 팀 검토용

본 문서는 MeshLaw 의 데이터 처리·격리·암호화·접근 통제 정책을 정리합니다. 구현 사실 (코드·마이그레이션·운영 설정) 기준이며, 검증·실사 시 해당 라인을 함께 제시합니다.

1. 시스템 구성

컴포넌트기술비고
게이트웨이Moleculer (Node/Bun) :4098HTTP 입구. JWT 검증 + RLS 컨텍스트 주입
DBPostgreSQL 16 + pgvector단일 인스턴스. RLS team_id 격리
AI 백엔드vLLM (사내 호스팅)외부 API 송신 X — 매터 데이터가 외부 LLM 사로 나가지 않음
메일Resend (도메인 verify)가입·비밀번호만, 매터 콘텐츠 송신 X
모바일 푸시APNs + FCMtitle/body + data 만 — 매터 본문 X

호스팅: Vultr 서울 리전 — 데이터 reside in Korea. 운영 SSH: key auth only (password disabled).

2. 테넌트 격리

2.1 PostgreSQL Row-Level Security

모든 도메인 테이블이 FORCE ROW LEVEL SECURITY 활성:

  • 직접 격리 (team_id 컬럼): matters, clients, advisories, audit_log, notifications, llm_usage, team_token_quota, messages, device_tokens, stripe_webhook_events, invoice_receipts
  • JOIN 격리 (matter_id → matters.team_id): matter_events, invoices, timesheet_entries, writs, approvals, matter_refs, vault_files, matter_acl, deadlines

정책: team_id = app_current_team_id() (USING + WITH CHECK). app_current_team_id() 는 트랜잭션 GUC app.team_id 를 읽음.

2.2 NOSUPERUSER ROLE 분리

운영 게이트웨이는 meshlaw_app (NOSUPERUSER · NOBYPASSRLS) ROLE 로 DB 접속. dev / 마이그레이션 도구는 별도 superuser 로 분리 — 일상 운영 트래픽에 BYPASSRLS 사용자가 끼지 않음. 2026-05-05 적용.

2.3 트랜잭션 GUC 주입

sql.begin(async (tx) => 
  await tx`select set_config('app.team_id', ${teamId}, true)`
  await tx`select set_config('app.user_id', ${userId}, true)`
  return fn(tx)

SET LOCAL 라 트랜잭션 종료 시 자동 해제. 50/50 도메인 액션이 wrap 적용. 잔여 7건은 auth.signup/login 의 password_hash lookup 등 의도적 raw — 데이터 누출 경로 없음.

2.4 JWT → ctx.meta.user 매핑

게이트웨이 onBeforeCall 이 JWT 검증 → ctx.meta.user = { id, team, role } 주입. 모든 도메인 라우트 AUTH_REQUIRED_PREFIXES 에 포함되어 토큰 없으면 401.

2.5 회귀 보호

테넌트 격리는 매 배포 전 e2e §7 (RLS) 회귀:

  • 미인증 호출 → 401
  • 잘못된 JWT → 401
  • 정상 JWT 의 본인 team 데이터만 200

3. 개인정보 보호 (PII)

3.1 주민등록번호

저장: pgp_sym_encrypt 암호화 (BYTEA rrn_encrypted) + 마지막 4자리 (rrn_last4). 노출: 클라이언트 UI 는 maskRRN() 으로 강제 마스킹 → XXXXXX-XXX{last4}. 형식 어긋남이면 빈 문자열 (raw 노출 차단). 8 단위 테스트 회귀.

3.2 비밀번호

bcrypt 해시 저장. 클라이언트는 입력 시 4-rule 실시간 시각화 (8자 / 영문 / 숫자 / 특수문자). HTTPS only — iOS Release 빌드 NSAllowsArbitraryLoads 미설정.

3.3 토큰 관리

  • JWT: 짧은 TTL (기본 30분), HS256
  • Refresh: rotation + reuse detection. 평문은 사용자에게 1회 전달, DB 에는 bcrypt 해시만. 재사용 감지 시 chain 전체 revoke

3.4 매터 단위 ACL

RLS team scope 위에 매터 단위 추가 격리 (matter_acl). 4 역할 (owner ⊃ editor ⊃ viewer). 메신저 v0.1.6 가 채택 — matter 채널 list 는 viewer 이상, 작성은 editor 이상.

4. 감사 로그

audit_log 테이블에 자동 기록되는 액션:

  • 매터 CRUD, ACL grant/revoke
  • 결재 승인/반려/수정요청 (status_before/after, comment)
  • 청구서 발행, 수금 receipt (delta_won, total)
  • 사용량 → invoice/timesheet rollup
  • 참고문서 CRUD

각 row: actor_name, target_kind, target_id, http_status, matter_id, meta(JSONB), created_at. RLS 적용 — 다른 테넌트 audit 조회 불가.

5. 권한 통제

5.1 결재 (matter approvals)

서버측 actor 가드 — computeApprovalChainAdvance(steps, status, currentUserId). 활성 단계의 approver_id 와 일치하는 사용자만 액션. 불일치 시 403 NOT_APPROVER. 데스크톱·모바일 동일 가드. 7 단위 테스트.

5.2 RBAC (시스템 역할)

users.role_idroles 테이블 (admin/partner/associate/staff). auth.invite 가 역할 부여 (admin 만 발급 가능).

6. 데이터 처리

6.1 AI 모델 호출

사내 vLLM (Tailscale 내부망) — 외부 API 송신 X. LLM 요청 본문 (매터 컨텍스트·문서) 은 사외로 안 나감. llm_usage 테이블에 호출 토큰·비용 기록 (RLS team scope).

6.2 파일 (Vault)

  • 저장: 서버 디스크 (storage_directory 매터별 분리)
  • 메타데이터: vault_files 테이블 (file_name, mime, size_bytes, text_content)
  • 인덱싱: text 추출 후 text_content 저장 → ⌘K 통합검색 (RLS 적용)
  • PDF 멀티모달: mupdf 로 페이지 JPEG 변환 → vLLM 비전 인코더 (외부 X)

6.3 메일

Resend 도메인 meshlaw.ai (DKIM/SPF/DMARC verify). 콘텐츠: 가입·invite·비밀번호 재설정만 — 매터 내용 X.

7. 인프라 보안

7.1 전송

게이트웨이: HTTPS only (Caddy). iOS Release / Android Release 모두 prod URL 만 (Debug 만 localhost).

7.2 모바일 푸시

  • APNs JWT (.p8) — Apple Developer Team ID + Key ID
  • FCM HTTP v1 — Firebase service account JSON
  • 푸시 본문은 메타데이터만 (title/body + data.type 라우팅 hint) — 매터 본문 X
  • 디바이스 토큰: device_tokens 테이블 (RLS team scope)

7.3 운영 접근

  • SSH 접속: key 기반 인증 (운영 권장)
  • DB: docker-compose 가 127.0.0.1:54322localhost bind only — 외부 인터넷 노출 X. 호스트 내 게이트웨이 컨테이너만 접근 (network_mode: host)
  • 백업: /var/backups/meshlaw-db-*.sql.gz (현재 수동, 자동화 예정)
  • 마이그 적용 시 사전 백업 의무 (운영 규율)

7.4 Stripe 결제

Webhook signature 검증 + 멱등성 가드 (stripe_webhook_events). 카드 정보는 Stripe Vault — 자사 저장 X (PCI 범위 최소화).

8. 컴플라이언스 자세

항목상태
개인정보보호법 (PIPA)통상 처리 · DPA 별도 제공
ISMS-P검토 중 (인증 신청 시점 별도 공지)
KISA 마크검토 중
GDPR적용 외 (국내 한정)
ZDR (Zero Data Retention)정책 옵션 — Pro+ 플랜 계약 시 약정 부속. 현재 사내 vLLM 만 사용하므로 외부 학습 노출 자체 없음

⚠️ ISMS-P / KISA 마크는 검토 단계입니다. 인증 마크 사용은 획득 후에만 가능합니다.

9. 사고 대응

9.1 토큰 유출

Refresh 재사용 감지 시 사용자 chain 전체 자동 revoke. /auth/logout 또는 비번 변경 → 모든 refresh revoke.

9.2 데이터 노출

발견 즉시 docker-compose 롤백 + DB 백업 복원.

9.3 사용자 통보

정책 목표: 72시간 안에 영향 범위·복구 절차·사용자 액션 안내 (개인정보보호법 §34 권고 수준). 현재 자동화는 없음 — 발생 시 운영자가 수동으로 영향 범위 산출·일괄 메일 발송.

10. 데이터 이전·삭제

  • Export: 사용자가 자기 team 데이터를 JSON 으로 export (v0.2 예정)
  • 삭제: UI 직접 삭제 + 계정 삭제는 이메일 요청 → 30일 grace → cascade
  • 보관: 기본 무기한. 법정 의무 보관 (소득세법 5년 등) 은 사용자 책임

11. 검증 요청

본 백서의 사실 검증·실사 협조를 원하시면 contact 페이지 또는 영업 담당 이메일로 요청 — 코드 경로 (라인 번호) · 마이그 SQL 사본 · 침투 테스트 결과 (수행 후) 제공.

별도 보안 담당 메일박스(compliance@meshlaw.ai 등) 는 도메인 verify 및 운영 준비 완료 시 별도 공지.


검토용 PDF 가 필요하면

⌘P (Mac) / Ctrl+P (Win) 로 "PDF 로 저장". 또는 마크다운 원본 다운로드.