← セキュリティページへ
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 への送信なし — マターデータが外部 LLM 事業者へ出ない
メールResend(ドメイン検証済み)登録・パスワードのみ、マター内容の送信なし
モバイルプッシュAPNs + FCMtitle/body + data のみ — マター本文なし

ホスティング: Vultr ソウルリージョン — データは韓国に所在。運用 SSH: 鍵認証のみ(パスワード無効)。

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 ルックアップなど意図的な 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 ルールをリアルタイムに可視化(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 スコープの上に、マター単位の追加分離(matter_acl)。4 ロール(owner ⊃ editor ⊃ viewer)。メッセンジャー v0.1.6 が採用 — マターのチャネル一覧は 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 への送信なし。LLM リクエスト本文(マターコンテキスト・文書)は社外へ出ません。llm_usage テーブルに呼び出しトークン・コストを記録(RLS team スコープ)。

6.2 ファイル(Vault)

  • 保存: サーバディスク(storage_directory をマターごとに分離)
  • メタデータ: vault_files テーブル(file_name, mime, size_bytes, text_content)
  • インデックス: テキスト抽出後に text_content へ保存 → ⌘K 統合検索(RLS 適用)
  • PDF マルチモーダル: mupdf でページを JPEG 変換 → vLLM のビジョンエンコーダ(外部へ出ない)

6.3 メール

Resend ドメイン meshlaw.ai(DKIM/SPF/DMARC 検証済み)。コンテンツ: 登録・invite・パスワード再設定のみ — マター内容なし。

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)— マター本文なし
  • デバイストークン: device_tokens テーブル(RLS team スコープ)

7.3 運用アクセス

  • SSH 接続: 鍵ベース認証(運用推奨)
  • DB: docker-compose が 127.0.0.1:54322localhost bind only — 外部インターネットへの露出なし。ホスト内のゲートウェイコンテナのみアクセス可能(network_mode: host)
  • バックアップ: /var/backups/meshlaw-db-*.sql.gz(現在は手動、自動化予定)
  • マイグ適用時は事前バックアップ必須(運用規律)

7.4 Stripe 決済

Webhook signature 検証 + 冪等性ガード(stripe_webhook_events)。カード情報は Stripe Vault — 自社保存なし(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 など)は、ドメイン検証および運用準備の完了後に別途告知します。


検討用 PDF が必要な場合

⌘P (Mac) / Ctrl+P (Win) で「PDF として保存」。または Markdown 原本をダウンロード