ストーリー
高橋アーキテクトがデータの一覧を広げました。
データ分類レベル
| レベル | 名称 | 説明 | 例 |
|---|---|---|---|
| Level 1 | 公開 | 公開されても問題ないデータ | 公開プロフィール、商品情報 |
| Level 2 | 内部 | 社内利用のデータ | 社内文書、会議メモ |
| Level 3 | 機密 | 漏洩すると損害が発生するデータ | 個人情報、顧客リスト |
| Level 4 | 最高機密 | 漏洩すると重大な損害が発生するデータ | クレジットカード、医療情報 |
データ分類マトリクス
// データ分類の定義
interface DataClassification {
field: string;
level: 1 | 2 | 3 | 4;
encryptionAtRest: boolean;
encryptionInTransit: boolean;
masking: boolean;
retentionDays: number;
accessLog: boolean;
}
const userDataClassification: DataClassification[] = [
{
field: "userId",
level: 1,
encryptionAtRest: false,
encryptionInTransit: true,
masking: false,
retentionDays: -1, // 無期限
accessLog: false,
},
{
field: "displayName",
level: 1,
encryptionAtRest: false,
encryptionInTransit: true,
masking: false,
retentionDays: -1,
accessLog: false,
},
{
field: "email",
level: 3,
encryptionAtRest: true,
encryptionInTransit: true,
masking: true, // 表示時: t***@example.com
retentionDays: 365,
accessLog: true,
},
{
field: "phoneNumber",
level: 3,
encryptionAtRest: true,
encryptionInTransit: true,
masking: true, // 表示時: ***-****-1234
retentionDays: 365,
accessLog: true,
},
{
field: "creditCardNumber",
level: 4,
encryptionAtRest: true,
encryptionInTransit: true,
masking: true, // 表示時: ****-****-****-1234
retentionDays: 90,
accessLog: true,
},
{
field: "passwordHash",
level: 4,
encryptionAtRest: true,
encryptionInTransit: true,
masking: false, // そもそも表示しない
retentionDays: -1,
accessLog: true,
},
];
レベル別の保護策
| 保護策 | Level 1 | Level 2 | Level 3 | Level 4 |
|---|---|---|---|---|
| 通信時暗号化(TLS) | o | o | o | o |
| 保存時暗号化 | - | - | o | o |
| フィールドレベル暗号化 | - | - | - | o |
| データマスキング | - | - | o | o |
| アクセスログ | - | - | o | o |
| バックアップ暗号化 | - | o | o | o |
| 自動削除 | - | - | o | o |
| DLP(情報漏洩防止) | - | - | - | o |
データマスキングの実装
// データマスキングのユーティリティ
const maskingRules: Record<string, (value: string) => string> = {
email: (email: string): string => {
const [local, domain] = email.split("@");
return `${local[0]}${"*".repeat(Math.max(local.length - 1, 2))}@${domain}`;
},
phone: (phone: string): string => {
// 下4桁のみ表示: ***-****-1234
return phone.replace(/\d(?=\d{4})/g, "*");
},
creditCard: (cc: string): string => {
// 下4桁のみ表示: ****-****-****-1234
return cc.replace(/\d(?=\d{4})/g, "*");
},
name: (name: string): string => {
// 最初の1文字 + マスク: 田***
return name[0] + "*".repeat(Math.max(name.length - 1, 2));
},
};
// レスポンスのフィルタリング
const sanitizeResponse = (
user: User,
viewerRole: string,
): Partial<User> => {
if (viewerRole === "admin") {
// 管理者でもマスキング(生データは監査ログ経由でのみアクセス)
return {
...user,
email: maskingRules.email(user.email),
phone: user.phone ? maskingRules.phone(user.phone) : undefined,
};
}
// 一般ユーザーには最小限の情報のみ
return {
id: user.id,
displayName: user.displayName,
avatarUrl: user.avatarUrl,
};
};
データライフサイクル管理
// データの保存期間と自動削除
interface RetentionPolicy {
dataType: string;
retentionDays: number;
action: "delete" | "anonymize" | "archive";
}
const retentionPolicies: RetentionPolicy[] = [
{ dataType: "sessionLogs", retentionDays: 30, action: "delete" },
{ dataType: "accessLogs", retentionDays: 365, action: "archive" },
{ dataType: "paymentInfo", retentionDays: 90, action: "delete" },
{ dataType: "userProfiles", retentionDays: -1, action: "anonymize" },
// userProfilesは退会時に匿名化
];
// 定期実行の削除ジョブ
const enforceRetention = async (): Promise<void> => {
for (const policy of retentionPolicies) {
if (policy.retentionDays < 0) continue;
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - policy.retentionDays);
switch (policy.action) {
case "delete":
await db.query(
`DELETE FROM ${policy.dataType} WHERE created_at < $1`,
[cutoffDate],
);
break;
case "anonymize":
await db.query(
`UPDATE ${policy.dataType} SET email = 'deleted', name = 'deleted' WHERE created_at < $1`,
[cutoffDate],
);
break;
case "archive":
await archiveToS3(policy.dataType, cutoffDate);
break;
}
}
};
まとめ
| ポイント | 内容 |
|---|---|
| データ分類 | 4段階のレベルでデータを分類 |
| レベル別保護 | 重要度に応じた暗号化・マスキング |
| マスキング | 表示時に機密部分を隠す |
| ライフサイクル | 保存期間を定めて自動削除・匿名化 |
チェックリスト
- データの4段階分類レベルを理解した
- レベル別の保護策を把握した
- データマスキングの実装方法を理解した
- データライフサイクル管理の重要性を認識した
次のステップへ
次は「シークレット管理」を学びます。APIキー、パスワード、証明書などの機密情報を安全に管理する方法を身につけましょう。
推定読了時間: 40分