ストーリー
主要なプライバシー規制
| 規制 | 地域 | 主な要件 | 制裁金 |
|---|---|---|---|
| GDPR | EU/EEA | 同意取得、データポータビリティ、忘れられる権利、DPO設置 | 最大2,000万EUR or 年間売上4% |
| 個人情報保護法 | 日本 | 利用目的の特定、第三者提供の制限、安全管理措置 | 1億円以下(法人) |
| CCPA/CPRA | カリフォルニア | オプトアウト権、販売禁止要求権、データ開示要求 | 1件あたり最大$7,500 |
| PIPL | 中国 | データのローカライゼーション、同意取得、越境移転の制限 | 年間売上5%以下 |
Privacy by Design の原則
// Privacy by Design の7原則をアーキテクチャに組み込む
interface PrivacyByDesignPrinciple {
principle: string;
architecturalImplementation: string;
technicalControl: string;
}
const privacyPrinciples: PrivacyByDesignPrinciple[] = [
{
principle: '1. 事後対応ではなく予防',
architecturalImplementation: 'データパイプラインにPII検出を組み込み、分類前のデータ利用を禁止',
technicalControl: 'Ingestion時の自動PII検出 + ブロッキングルール',
},
{
principle: '2. デフォルトでプライバシー保護',
architecturalImplementation: '新規テーブルはデフォルトで最小権限、PIIカラムはデフォルト暗号化',
technicalControl: 'Column-level encryption + RBAC デフォルトポリシー',
},
{
principle: '3. 設計に組み込む',
architecturalImplementation: 'データモデル設計時にPII分類カラムを必須化',
technicalControl: 'スキーマバリデーションでpii_classificationフィールドを要求',
},
{
principle: '4. 全機能の確保(ゼロサムではない)',
architecturalImplementation: 'プライバシーと分析を両立する匿名化パイプラインの設計',
technicalControl: 'k-匿名化、差分プライバシーによる分析可能な匿名データの生成',
},
{
principle: '5. エンドツーエンドのセキュリティ',
architecturalImplementation: 'データのライフサイクル全体で暗号化と監査',
technicalControl: '転送中(TLS) + 保存時(AES-256) + 処理中(Confidential Computing)',
},
{
principle: '6. 透明性',
architecturalImplementation: 'データリネージュで個人データの流れを完全に追跡可能',
technicalControl: 'DataHubリネージュ + 同意管理ダッシュボード',
},
{
principle: '7. ユーザー中心',
architecturalImplementation: '本人からのデータ開示・削除要求にAPIで自動対応',
technicalControl: 'DSAR(Data Subject Access Request)自動処理パイプライン',
},
];
匿名化・仮名化技術
// 匿名化手法の実装
interface AnonymizationTechnique {
name: string;
method: string;
reversible: boolean;
useCase: string;
}
const techniques: AnonymizationTechnique[] = [
{
name: 'ハッシュ化(SHA-256)',
method: '一方向関数で変換',
reversible: false,
useCase: 'ユーザーIDの匿名化(結合分析は可能)',
},
{
name: '仮名化(Pseudonymization)',
method: '鍵付きでIDを別の識別子に置換',
reversible: true,
useCase: 'GDPR準拠の分析(必要時に再特定可能)',
},
{
name: 'k-匿名化',
method: '同一の準識別子を持つレコードがk件以上存在するよう一般化',
reversible: false,
useCase: '統計データの公開(再特定リスクの低減)',
},
{
name: '差分プライバシー',
method: '統計結果にノイズを追加',
reversible: false,
useCase: '集計値の公開(個別レコードの特定を防止)',
},
{
name: 'データマスキング',
method: '元データの一部を置換(例: メール → t***@***.com)',
reversible: false,
useCase: '開発・テスト環境でのデータ利用',
},
];
-- PostgreSQL: カラムレベルの匿名化パイプライン
-- 仮名化関数: 鍵付きHMAC
CREATE OR REPLACE FUNCTION pseudonymize(
original_value TEXT,
secret_key TEXT DEFAULT current_setting('app.pseudonymization_key')
)
RETURNS TEXT AS $$
BEGIN
RETURN encode(
hmac(original_value, secret_key, 'sha256'),
'hex'
);
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- k-匿名化: 年齢の一般化
CREATE OR REPLACE FUNCTION generalize_age(age INT)
RETURNS TEXT AS $$
BEGIN
RETURN CASE
WHEN age < 20 THEN '10代以下'
WHEN age < 30 THEN '20代'
WHEN age < 40 THEN '30代'
WHEN age < 50 THEN '40代'
WHEN age < 60 THEN '50代'
ELSE '60代以上'
END;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 匿名化ビュー: 分析チームに提供
CREATE VIEW anonymized_customers AS
SELECT
pseudonymize(customer_id) AS customer_pseudo_id,
generalize_age(
EXTRACT(YEAR FROM AGE(CURRENT_DATE, date_of_birth))::INT
) AS age_group,
prefecture AS region, -- 市区町村は非表示
tier,
registration_date,
-- 直接的な個人情報は除外
-- full_name, email, phone, address は含めない
total_transaction_count,
total_amount
FROM customers;
同意管理(Consent Management)
// 同意管理システムの設計
interface ConsentRecord {
consentId: string;
userId: string;
purposes: ConsentPurpose[];
collectedAt: string;
expiresAt: string;
source: 'web' | 'app' | 'api' | 'paper';
version: string; // 同意規約のバージョン
ipAddress: string;
userAgent: string;
}
interface ConsentPurpose {
purposeId: string;
name: string;
granted: boolean;
legalBasis: 'consent' | 'legitimate_interest' | 'contract' | 'legal_obligation';
}
// 同意目的の定義
const consentPurposes: ConsentPurpose[] = [
{
purposeId: 'CORE_SERVICE',
name: 'サービス提供に必要なデータ処理',
granted: true, // 契約履行のため同意不要(法的根拠: contract)
legalBasis: 'contract',
},
{
purposeId: 'ANALYTICS',
name: 'サービス改善のための匿名化分析',
granted: true,
legalBasis: 'legitimate_interest',
},
{
purposeId: 'MARKETING',
name: 'マーケティングメール・プッシュ通知',
granted: false, // 明示的な同意が必要
legalBasis: 'consent',
},
{
purposeId: 'THIRD_PARTY',
name: '第三者へのデータ提供',
granted: false, // 明示的な同意が必要
legalBasis: 'consent',
},
];
// DSAR(Data Subject Access Request)自動処理
interface DSARRequest {
requestId: string;
userId: string;
requestType: 'access' | 'rectification' | 'erasure' | 'portability' | 'restriction';
status: 'received' | 'processing' | 'completed' | 'rejected';
slaDeadline: string; // GDPR: 30日以内
}
class DSARProcessor {
async processAccessRequest(userId: string): Promise<DataExport> {
// 全データソースからユーザーデータを収集
const userData = await Promise.all([
this.queryDB('SELECT * FROM customers WHERE id = $1', [userId]),
this.queryDB('SELECT * FROM transactions WHERE customer_id = $1', [userId]),
this.queryDB('SELECT * FROM consent_records WHERE user_id = $1', [userId]),
this.queryObjectStorage(`user-data/${userId}/`),
]);
return {
format: 'JSON',
data: this.mergeAndFormat(userData),
generatedAt: new Date().toISOString(),
};
}
async processErasureRequest(userId: string): Promise<ErasureReport> {
// 1. 法的保持義務のあるデータを特定(削除不可)
const retentionCheck = await this.checkLegalRetention(userId);
// 2. 削除可能なデータを物理削除
const deletedSources = await this.deleteFromAllSources(userId, retentionCheck.exempt);
// 3. 法的保持対象データは匿名化
const anonymizedSources = await this.anonymizeRetainedData(userId, retentionCheck.retained);
// 4. バックアップからの削除をスケジュール
await this.scheduleBackupPurge(userId);
return {
deletedSources,
anonymizedSources,
retainedWithReason: retentionCheck.retained,
completedAt: new Date().toISOString(),
};
}
}
コンプライアンスチェックの自動化
// パイプラインに組み込むコンプライアンスチェック
interface ComplianceCheck {
checkId: string;
name: string;
regulation: string;
automated: boolean;
implementation: string;
}
const complianceChecks: ComplianceCheck[] = [
{
checkId: 'CC-001',
name: 'PII自動検出',
regulation: 'GDPR / 個人情報保護法',
automated: true,
implementation: 'Ingestion時にカラム名 + サンプルデータで自動分類、未分類PIIはブロック',
},
{
checkId: 'CC-002',
name: '同意チェック',
regulation: 'GDPR Article 6',
automated: true,
implementation: 'マーケティング用データは同意済みユーザーのみ抽出するフィルタをパイプラインに組み込み',
},
{
checkId: 'CC-003',
name: 'データ保持期限チェック',
regulation: 'GDPR Article 5(1)(e)',
automated: true,
implementation: 'TTLポリシーの自動適用 + 期限超過データの月次削除ジョブ',
},
{
checkId: 'CC-004',
name: '越境移転チェック',
regulation: 'GDPR Chapter 5 / PIPL',
automated: false,
implementation: 'データフローマップで国境を越える転送を可視化、SCC/BCRの有無を確認',
},
{
checkId: 'CC-005',
name: '匿名化品質検証',
regulation: 'GDPR Recital 26',
automated: true,
implementation: 'k-匿名化後のデータに対して再特定リスクを統計的に評価(k≥5を保証)',
},
];
GDPRデータ処理の法的根拠の選択フロー
データ処理の目的を特定
│
├─ サービス提供に不可欠?
│ └─ Yes → 「契約履行」(Article 6(1)(b))
│
├─ 法的義務(規制報告等)?
│ └─ Yes → 「法的義務」(Article 6(1)(c))
│
├─ 組織の正当な利益があり、本人の権利を侵害しない?
│ └─ Yes → 「正当な利益」(Article 6(1)(f))
│ ※ LIA(Legitimate Interest Assessment)を実施・記録
│
└─ 上記いずれにも該当しない?
└─ 「明示的な同意」(Article 6(1)(a))を取得
※ 同意は自由に撤回可能であること
まとめ
| ポイント | 内容 |
|---|---|
| 主要規制 | GDPR、個人情報保護法、CCPA — 地域ごとの要件を把握 |
| Privacy by Design | 設計段階からプライバシーを組み込む7原則 |
| 匿名化技術 | ハッシュ / 仮名化 / k-匿名化 / 差分プライバシー / マスキング |
| 同意管理 | 目的別の法的根拠、DSARの自動処理 |
チェックリスト
- GDPR・個人情報保護法の主要要件を説明できる
- Privacy by Designの原則をアーキテクチャに組み込める
- 匿名化・仮名化の手法を使い分けられる
- 同意管理とDSAR処理のシステムを設計できる
次のステップへ
次はデータリネージュと監査証跡について学びます。
推定読了時間: 40分