メインコンテンツへスキップ
データマスキングは、元のデータのフォーマットや構造を維持したまま、個人を特定できる情報 (PII) や機密情報を取り除いた別のデータに置き換えることで、データを保護する手法です。 このガイドでは、ClickHouse でデータをマスキングするためのいくつかの方法を紹介します。
  • マスキングポリシー (ClickHouse Cloud, 25.12+): 特定のユーザー/ロールに対して、クエリ時に適用されるネイティブの動的マスキング
  • 文字列置換関数: 組み込み関数を使用した基本的なマスキング
  • マスクされたビュー: 変換ロジックを含むビューの作成
  • マテリアライズドカラム: 元のデータと並行してマスク済みバージョンを保存
  • クエリマスキングルール: ログ内の機密データをマスク (ClickHouse OSS)

マスキングポリシーを使用する (ClickHouse Cloud)

マスキングポリシーは、ClickHouse Cloud バージョン 25.12 以降で利用できます。
CREATE MASKING POLICY ステートメントを使用すると、クエリ実行時に特定のユーザーまたはロールに対してカラムの値を動的にマスクできます。他の方法とは異なり、マスキングポリシーでは個別のビューを作成したり、マスク済みのデータを保存したりする必要はありません。変換は、ユーザーがテーブルにクエリを実行する際に透過的に行われます。

基本的なマスキングポリシー

マスキングポリシーを説明するために、顧客情報を含む orders テーブルを作成してみましょう。
次に、マスクされたデータを閲覧するユーザー向けのロールを作成します。
masked_data_viewer ロールに適用するマスキングポリシーを作成します:
masked_data_viewer ロールを持つユーザーが orders テーブルをクエリすると、マスクされたデータが自動的に表示されます。
Query
Response (for masked_data_viewer role)
masked_data_viewer ロールを持たないユーザーには、元の未マスクのデータが表示されます。

条件付きマスキング

WHERE句を使用すると、特定の行にのみマスキングを適用できます。たとえば、高額な注文だけをマスキングするには、次のようにします。

優先度付きの複数のポリシー

同じカラムに複数のマスキングポリシーが適用される場合は、どの変換を適用するかを制御するために PRIORITY 句を使用します。優先度の値が高いものほど、最後に適用されます。
この例では、total_amount > 100 の注文では、name カラムに対して refined_masking ポリシー (優先度 10) が basic_masking ポリシー (優先度 0) より優先される一方、email には引き続き基本マスキングが適用されます。

ハッシュベースのマスキング

一貫性のあるマスキング (同じ入力から常に同じマスク済みの出力が得られる) 必要がある場合は、ハッシュ関数を使用します。

マスキングポリシーの管理

すべてのマスキングポリシーを表示する:
マスキングポリシーを削除します:
既存のポリシーを置き換える:
詳細は、CREATE MASKING POLICY のドキュメントを参照してください。

文字列置換関数を使用する

基本的なデータマスキングの用途では、replace 関数ファミリーを使うことで、手軽にデータをマスクできます。 たとえば、replaceOne 関数を使って、名前 “John Smith” をプレースホルダー [CUSTOMER_NAME] に置き換えることができます。
Query
Response
より汎用的には、replaceRegexpOne を使用して任意の顧客名を置き換えることができます:
Query
Response
また、replaceRegexpAll 関数を使って社会保障番号をマスキングし、最後の4桁だけを残すこともできます。
Query
上記のクエリでは、\3 を使用して3番目のキャプチャグループを結果の文字列に埋め込んでおり、その結果は次のようになります。
Response

マスクされた VIEW を作成する

VIEW は、前述の文字列関数と組み合わせることで、機密データを含むカラムがユーザーに表示される前に変換を適用できます。 これにより、元のデータは変更されず、VIEW に対してクエリを実行するユーザーにはマスクされたデータだけが表示されます。 例として、顧客の注文レコードを保存するテーブルがあるとします。 特定の従業員グループがこの情報を閲覧できるようにしたい一方で、顧客の完全な情報は見せたくありません。 以下のクエリを実行して、サンプルテーブル orders を作成し、そこに架空の顧客注文レコードをいくつか挿入します。
masked_orders という名前のビューを作成します:
上記のビュー作成クエリの SELECT 句では、部分的にマスクしたい機微情報を含む nameemailphoneshipping_address の各フィールドに対して、replaceRegexpOne を使った変換を定義しています。 ビューからデータを取得します:
Query
Response
ビューから返されるデータは一部がマスクされており、機密情報が見えないようになっていることに注意してください。 また、閲覧者に付与された情報アクセス権限のレベルに応じてマスキングの度合いを変えた複数のビューを作成することもできます。 ユーザーがマスクされたデータを返すビューにのみアクセスでき、元のマスクされていないデータを含むテーブルにはアクセスできないようにするには、特定のロールにそのビューに対する select の権限のみを付与するよう、ロールベースのアクセス制御を使用する必要があります。 まず、ロールを作成します。
次に、そのロールにビューへのSELECT権限を付与します。
ClickHouse のロールは権限が加算的に適用されるため、マスクされたビューだけを参照できるべきユーザーに、どのロール経由でも基となるテーブルへの SELECT 権限が付与されていないことを確認する必要があります。 そのため、安全策として基となるテーブルへのアクセス権を明示的に取り消す必要があります。
最後に、適切なユーザーにロールを付与します。
これにより、masked_orders_viewer ロールを持つユーザーは、ビュー内のマスク済みデータのみを参照でき、 テーブル内の元の未マスクデータは参照できなくなります。

MATERIALIZED カラムとカラムレベルのアクセス制限を使用する

別個のビューを作成したくない場合は、元のデータと並べて、マスクしたバージョンのデータを保存できます。 これには、materialized columns を使用します。 このようなカラムの値は、行の挿入時に、指定されたマテリアライズ式に基づいて自動的に計算されます。 これを利用して、データをマスクした新しいカラムを作成できます。 前の例ではマスクしたデータ用に別個の VIEW を作成しましたが、ここでは代わりに MATERIALIZED を使用してマスク済みカラムを作成します:
ここで次の SELECT クエリを実行すると、マスクされたデータが挿入時に「マテリアライズ」され、元のマスクされていないデータとあわせて保存されることがわかります。 ClickHouse では、デフォルトで SELECT * クエリにマテリアライズドカラムが自動的には含まれないため、マスクされたカラムは明示的に選択する必要があります。
Query
Response
ユーザーがマスク済みデータを含むカラムにのみアクセスできるようにするには、再度 ロールベースのアクセス制御 を使用して、特定のロールには orders のマスクされたカラムに対する select 権限のみを付与します。 先ほど作成したロールを再作成します:
次に、ordersテーブルに対するSELECT権限を付与します:
機密性の高いカラムへのアクセス権を取り消します:
最後に、適切なユーザーにそのロールを割り当てます:
orders テーブルにマスク済みデータのみを保存したい場合は、 機密性の高い未マスクのカラムを EPHEMERAL として指定できます。 これにより、この型のカラムはテーブルに保存されなくなります。
先ほどと同じクエリを実行すると、マテリアライズされたマスク済みデータだけがテーブルに挿入されていることがわかります。
Query
Response

ログデータにクエリマスキングルールを使用する

特にログデータをマスクしたい ClickHouse OSS ユーザーは、データのマスキングに クエリマスキングルール (ログマスキング) を利用できます。 そのためには、サーバー設定で正規表現ベースのマスキングルールを定義します。 これらのルールは、クエリとすべてのログメッセージがサーバーログやシステムテーブル (system.query_logsystem.text_logsystem.processes など) に保存される前に適用されます。 これにより、機密データがログにのみ漏洩するのを防ぐのに役立ちます。 ただし、クエリ結果内のデータはマスクされません。 たとえば、社会保障番号をマスクするには、次のルールを server configuration に追加できます。
最終更新日 2026年6月12日