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?

個人情報保護法(APPI)対応:PostgreSQLにおける機密データの動的マスキング手法と実装

0
Posted at

個人情報保護法(APPI)対応:PostgreSQLにおける機密データの動的マスキング手法と実装

Feature(213).png

はじめに

こんにちは、NKKTech Global 技術チームです。

日本市場向けサービスやエンタープライズシステムを運用する際、**個人情報保護法(APPI)が定める「技術的安全管理措置」**への適合は避けて通れません。

特に現場で問題となるのが、以下のジレンマです。

  • 「データ分析チームに購買履歴を提供したいが、顧客の氏名や電話番号は見せられない」
  • 「不具合調査のために本番DBを参照したいが、エンジニアに平文の個人情報(PII)を閲覧させたくない」
  • 「かといってバッチで別DBにデータをコピー・匿名化(静的マスキング)するのは運用工数とストレージ費用がかさむ」

この課題をスマートに解決するのが、**動的データマスキング(DDM: Dynamic Data Masking)**です。
元データは暗号化・保護された状態で保持しつつ、アクセスするユーザーのデータベースロール(Role)に応じて、クエリ実行時にリアルタイムでデータを伏せ字(マスク)化します。


1. 静的マスキング vs 動的データマスキング(DDM)

比較項目 静的マスキング (Static Masking) 動的データマスキング (Dynamic Masking)
処理タイミング DBエクスポート時・バッチ処理時 SQLクエリ実行時(オンザフライ)
物理データの変化 変化する(複製先DBを書き換える) 変化しない(ストレージ上の実データは保持)
ストレージコスト 複製DBの数だけ容量が倍増する ゼロ(単一のDBインスタンスで完結)
運用の柔軟性 リアルタイムな本番参照には不向き ロール(権限)の切り替えだけで即座に適用

2. 動的マスキングのアーキテクチャ

単一のテーブルに対し、接続元の権限に応じて異なる結果を返却します。


3. 実装パターンA:PostgreSQL Anonymizer(推奨標準)

PostgreSQLでDDMを実現する最も完成されたオープンソース拡張機能が PostgreSQL Anonymizer (anon) です。テーブル定義に「セキュリティラベル」を付与するだけで、宣言的にマスキングルールを定義できます。

① 拡張機能の有効化と初期化

-- 拡張機能のロード (postgresql.conf の shared_preload_libraries に 'anon' が必要)
CREATE EXTENSION IF NOT EXISTS anon CASCADE;

-- マスキングエンジンの初期化
SELECT anon.init();

② テーブルの作成とマスキングルールの宣言

氏名、メールアドレス、電話番号、郵便番号に対して、用途に応じたマスキング関数を割り当てます。

-- 顧客個人情報テーブル
CREATE TABLE customers (
    id SERIAL PRIMARY KEY,
    full_name VARCHAR(100),
    email VARCHAR(150),
    phone_number VARCHAR(20),
    credit_card_last4 VARCHAR(4),
    registered_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- テストデータの挿入
INSERT INTO customers (full_name, email, phone_number, credit_card_last4)
VALUES 
('山田 太郎', 'yamada.taro@example.com', '090-1234-5678', '4321'),
('佐藤 花子', 'sato.hanako@example.jp', '080-9876-5432', '8765');

-- 各カラムへの動的マスキングルールの付与
SECURITY LABEL FOR anon ON COLUMN customers.full_name
  IS 'MASKED WITH FUNCTION anon.fake_last_name() || '' '' || anon.fake_first_name()';

SECURITY LABEL FOR anon ON COLUMN customers.email
  IS 'MASKED WITH FUNCTION anon.partial(email, 2, ''*****'', 4)';

SECURITY LABEL FOR anon ON COLUMN customers.phone_number
  IS 'MASKED WITH FUNCTION anon.partial(phone_number, 3, ''-****-'', 4)';

③ ロール(ユーザー)ごとの適用制御

本番バックエンド用ロールと、分析・保守用ロールを作成し、分析用ロールにのみマスキングを強制します。

-- 1. アプリケーション用ロール(平文参照可能)
CREATE ROLE app_backend WITH LOGIN PASSWORD 'SecureAppPass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON customers TO app_backend;

-- 2. 分析・開発者用ロール(マスク強制)
CREATE ROLE bi_analyst WITH LOGIN PASSWORD 'AnalystPass123!';
GRANT SELECT ON customers TO bi_analyst;

-- bi_analyst に対して動的マスキングを有効化
SECURITY LABEL FOR anon ON ROLE bi_analyst IS 'MASKED';

④ 参照結果の比較検証

-- 【検証1】app_backend ロールで参照した場合
SET ROLE app_backend;
SELECT id, full_name, email, phone_number FROM customers;

-- 結果: 平文のまま取得できる
-- 1 | 山田 太郎 | yamada.taro@example.com | 090-1234-5678
-- 2 | 佐藤 花子 | sato.hanako@example.jp  | 080-9876-5432

-- 【検証2】bi_analyst ロールで参照した場合
SET ROLE bi_analyst;
SELECT id, full_name, email, phone_number FROM customers;

-- 結果: 自動でマスキングされる!
-- 1 | 加藤 翔太 | ya*****com            | 090-****-5678
-- 2 | 鈴木 芽衣 | sa*****jp             | 080-****-5432

4. 実装パターンB:拡張機能が使えないマネージドDB向け(Pure SQL + RLS)

AWS RDSや一部のクラウドマネージド環境で anon 拡張が許可されていない場合、PostgreSQL標準の Row-Level Security(RLS)と条件付き関数ビュー を組み合わせて同等の仕組みを構築します。

-- 1. 権限判定関数の作成
CREATE OR REPLACE FUNCTION mask_email(email TEXT, allowed_role TEXT) 
RETURNS TEXT AS $$
BEGIN
    IF pg_has_role(current_user, allowed_role, 'MEMBER') THEN
        RETURN email; -- 許可ロールなら平文
    ELSE
        -- 非許可ロールならマスク処理 (例: a***z@domain.com)
        RETURN regexp_replace(email, '^(.)(.*)(.@.*)$', '\1***\3');
    END IF;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 2. マスキングビューの提供
CREATE OR REPLACE VIEW v_customers AS
SELECT 
    id,
    mask_email(email, 'app_backend') AS email,
    credit_card_last4,
    registered_at
FROM customers;

-- 開発者には元テーブルへの権限を与えず、ビューのみ参照を許可
REVOKE ALL ON customers FROM bi_analyst;
GRANT SELECT ON v_customers TO bi_analyst;

5. 個人情報保護法(APPI)監査をクリアする運用のベストプラクティス

  1. 「アンマスク(平文開示)」の例外申請ワークフロー:
    本番障害対応等でエンジニアが一時的に平文データを見る必要がある場合、恒久的な権限を与えてはいけません。AWS STSの一時認証情報や、事前承認制のワークフロー(Jira連携)経由で「有効期限1時間」の一時ロールを付与します。
  2. アクセスログの確実な記録(監査証跡):
    PostgreSQLの pgaudit 拡張を併用し、誰が・いつ・どの顧客レコードを参照したかを監査ログとしてS3へ転送・保管します。APPIでは「漏洩事案発生時の報告義務」が課されているため、影響範囲を特定できるログが必須です。
  3. ダミーデータ生成との併用:
    ローカル開発環境(Docker等)にはそもそも本番データを一切同期させず、前述のFaker等を用いた合成ダミーデータのみを流し込むポリシーを徹底します。

まとめ:コンプライアンスを「開発生産性の足かせ」にしない

個人情報保護法への対応を「アクセスの全面禁止」で解決しようとすると、データ分析や障害対応のスピードが著しく鈍化します。

  • 動的データマスキング(DDM) を採用し、本番同等のリレーションを保った安全なデータを即時提供する。
  • PostgreSQL Anonymizer で宣言的なガバナンスルールをコード管理する。
  • 最小権限の原則 に基づき、業務上本当に平文が必要なアプリケーションにのみ生データを開示する。

この仕組みを導入することで、法規制のコンプライアンス要件を100%満たしながら、開発チームや分析チームがストレスなく成果を出せるセキュアな開発環境が実現します。


お問い合わせ先

個人情報保護法(APPI)に準拠したデータベース設計、PostgreSQLセキュリティチューニング、セキュアなデータ基盤構築に関するご相談は、下記よりお気軽にお問い合わせください。

著者:NKKTech Global 技術チーム
私たちは、高度なセキュリティガバナンスと実践的なデータエンジニアリングで、企業の信頼とDXをグローバルに支援します。

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?