0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MCPにおける透明性とプライバシーの両立:実装アプローチ

Last updated at Posted at 2025-10-21

はじめに

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における透明性とプライバシーの両立には、以下の階層的なアプローチが有効です:

  1. 最小権限の原則: 必要最小限のデータのみアクセス可能に
  2. メタデータ中心の監査: 実データではなく証跡情報を記録
  3. 動的なフィルタリング: ユーザー権限に応じた情報開示
  4. 暗号技術の適用: 高リスクデータには高度な保護を

これらを組み合わせることで、セキュリティ監査の要件を満たしつつ、プライバシー保護を実現できます。

参考資料


注意: MCPはAnthropicが開発した比較的新しいプロトコルです。最新の情報については、公式ドキュメントを参照してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?