はじめに
Model Context Protocol(MCP)を活用したLLMアプリケーションでは、外部データソースとの連携が不可欠です。しかし、セキュリティ監査のための透明性確保と、機密情報を含むコンテキストデータのプライバシー保護という、相反する要件への対応が課題となっています。
本記事では、MCPアーキテクチャにおいて、この2つの要件をどのように両立させるか、実装レベルのアプローチを解説します。
💡 1. 透明性とプライバシーのジレンマ
MCPでは、LLMがツールやリソースを通じて外部データにアクセスします。このとき、以下の相反する要件が生じます。
透明性の要件
- 監査証跡:どのリソースにアクセスしたか
- 実行追跡:どのツールが呼び出されたか
- デバッグ情報:エラー発生時の状況再現
プライバシーの要件
- 個人情報(PII)の保護
- 企業機密情報の漏洩防止
- コンプライアンス要件(GDPR、個人情報保護法等)への準拠
課題: 透明性を高めるほどログに機密情報が記録されるリスクが増大し、プライバシー保護が困難になる。
🔒 2. 実装アプローチ
2.1. メタデータベースの監査証跡
コンテンツの実体ではなく、そのメタデータを記録することで透明性を確保します。
import hashlib
from datetime import datetime
class AuditLogger:
def log_resource_access(self, content: str, resource_id: str):
# コンテンツのハッシュ値を計算
content_hash = hashlib.sha256(content.encode()).hexdigest()
audit_record = {
"timestamp": datetime.utcnow().isoformat(),
"resource_id": resource_id,
"content_hash": content_hash, # 実データは記録しない
"size_bytes": len(content.encode())
}
self._store_audit_log(audit_record)
利点:
- ログから機密情報が漏洩しない
- コンテンツの改ざん検知が可能
- 必要に応じてハッシュ値からの逆引きで検証可能
2.2. アクセス制御の記録
誰が何にアクセスしようとしたかを詳細に記録します。
class AccessControlLogger:
def log_access_attempt(
self,
user_id: str,
resource_uri: str,
action: str,
granted: bool,
reason: str = None
):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"user_id": user_id,
"resource_uri": resource_uri, # URIのみ、内容は含めない
"action": action,
"granted": granted,
"denial_reason": reason if not granted else None
}
self._store_access_log(log_entry)
2.3. 動的データマスキング
ユーザーの権限に応じて、MCPサーバー側でコンテキストをフィルタリングします。
class ContextFilter:
def filter_by_role(self, data: dict, user_role: str) -> dict:
"""ロールに基づいてデータをフィルタリング"""
# 機密フィールドの定義
sensitive_fields = {
"employee": ["salary", "ssn", "medical_records"],
"customer": ["credit_card", "bank_account"]
}
filtered_data = data.copy()
# 一般ユーザーの場合は機密フィールドをマスク
if user_role not in ["admin", "hr_manager"]:
for entity_type, fields in sensitive_fields.items():
if entity_type in filtered_data:
for field in fields:
if field in filtered_data[entity_type]:
filtered_data[entity_type][field] = "[REDACTED]"
return filtered_data
2.4. セキュアコンピューティング環境
高リスクな処理は隔離された環境で実行します。
class SecureToolExecutor:
def execute_in_sandbox(self, tool_name: str, params: dict) -> dict:
"""サンドボックス環境でツールを実行"""
# 実行前の検証
self._validate_tool(tool_name)
self._validate_params(params)
# 隔離環境での実行
result = self._run_in_isolated_env(tool_name, params)
# 結果のサニタイズ
sanitized_result = self._remove_sensitive_data(result)
return sanitized_result
🔐 3. 高度な技術的アプローチ
3.1. 差分プライバシー
統計的な情報のみを提供し、個別のデータポイントを保護します。
import numpy as np
class DifferentialPrivacyProvider:
def __init__(self, epsilon: float = 1.0):
self.epsilon = epsilon # プライバシー予算
def add_noise(self, true_value: float, sensitivity: float) -> float:
"""ラプラスノイズを追加"""
scale = sensitivity / self.epsilon
noise = np.random.laplace(0, scale)
return true_value + noise
def get_aggregate_stat(self, data: list) -> float:
"""プライバシーを保護した集約統計"""
true_mean = np.mean(data)
sensitivity = (max(data) - min(data)) / len(data)
return self.add_noise(true_mean, sensitivity)
3.2. 属性ベース暗号化(ABE)
データの属性に基づいたアクセス制御を暗号レベルで実現します。
from typing import Set
class AttributeBasedEncryption:
"""ABEの概念的な実装例"""
def encrypt(self, data: str, access_policy: str) -> bytes:
"""
アクセスポリシーに基づいて暗号化
例: "department:engineering AND clearance:secret"
"""
# 実際の実装ではABEライブラリを使用
return self._abe_encrypt(data, access_policy)
def decrypt(self, ciphertext: bytes, user_attributes: Set[str]) -> str:
"""
ユーザーの属性がポリシーを満たす場合のみ復号化可能
"""
if self._check_policy(user_attributes):
return self._abe_decrypt(ciphertext)
raise PermissionError("Attributes do not satisfy policy")
⚖️ 4. 実装時の考慮事項
4.1. パフォーマンスとセキュリティのバランス
- 軽量な操作: ハッシュ計算、メタデータ記録
- コスト高な操作: ゼロ知識証明、完全準同型暗号
- 推奨: リスクレベルに応じた段階的なセキュリティ適用
4.2. ログの保存期間と管理
class LogRetentionPolicy:
RETENTION_PERIODS = {
"audit_logs": 365, # 1年
"access_logs": 90, # 3ヶ月
"debug_logs": 30 # 1ヶ月
}
def apply_retention(self, log_type: str):
"""保存期間ポリシーを適用"""
days = self.RETENTION_PERIODS.get(log_type, 30)
self._delete_logs_older_than(days)
4.3. コンプライアンス対応
- GDPR: 「忘れられる権利」への対応
- 個人情報保護法: 安全管理措置の実施
- 業界標準: SOC 2、ISO 27001等への準拠
📊 5. アーキテクチャ例
┌─────────────┐
│ LLM Client │
└──────┬──────┘
│ MCP Protocol
▼
┌─────────────────────────┐
│ MCP Server │
│ ┌──────────────────┐ │
│ │ Access Control │ │
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ Context Filter │ │ ← ロールベースフィルタリング
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ Audit Logger │ │ ← ハッシュ・メタデータ記録
│ └──────────────────┘ │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Data Sources │
│ (データベース、API等) │
└─────────────────────────┘
まとめ
MCPにおける透明性とプライバシーの両立には、以下の階層的なアプローチが有効です:
- 最小権限の原則: 必要最小限のデータのみアクセス可能に
- メタデータ中心の監査: 実データではなく証跡情報を記録
- 動的なフィルタリング: ユーザー権限に応じた情報開示
- 暗号技術の適用: 高リスクデータには高度な保護を
これらを組み合わせることで、セキュリティ監査の要件を満たしつつ、プライバシー保護を実現できます。
参考資料
注意: MCPはAnthropicが開発した比較的新しいプロトコルです。最新の情報については、公式ドキュメントを参照してください。