機微なカラム — SSN、クレジットカード、メール、住所 — はサポート、分析、開発のためにクエリ可能であり続けなければなりません。広範な平文アクセスは答えではありません。データマスキングが答えです。一部のワークロード(GDPR、HIPAA、PCI)では、マスキングは法的要件でもあります。
Postgres はコアにマスキングのプリミティブを持ちません。実運用上の選択肢は 2 つです。データベース内部に存在するコミュニティ拡張の PostgreSQL Anonymizer、そしてその前段に置くポリシーレイヤーの Bytebase Dynamic Data Masking。本記事で比較します。
PostgreSQL Anonymizer
PostgreSQL Anonymizer は Damaen と Dalibo のチームによるコミュニティ拡張です。バージョン 2.0 は PGRX フレームワーク上で Rust によって完全に書き直されました — メモリ安全性が向上し、オーバーヘッドが下がり、SQL/PL-pgSQL ベースの先代より拡張面がクリーンになりました。

マスキング設定は PostgreSQL Security Labels に格納されます。pg_seclabel の仕組みはセキュリティモジュール向けに設計されましたが、一般化すると、任意のデータベースオブジェクトに対してトランザクション対応・MVCC 対応の方法でカスタムメタデータを付与する手段になります — コアパッチ不要です。Anonymizer はこのパターンをマスキング用に開拓し、pgEdge は同じプリミティブをレプリケーションメタデータに適用しています。仕組み自体は堅牢です。
5 つの戦略
Anonymizer 2.0 は 5 つの異なるマスキング戦略を提供します。見た目ではなくアクセスパターンで選びます。
- Dynamic Masking。 ロールを
MASKEDとして宣言します。そのロールで実行されるセッションはマスク済み出力を見て、他のロールは平文を見ます。ロールベース、透過、アプリケーション変更不要。 - Static Masking。 その場でデータを書き換えます。破壊的 — クローンや下位環境のみ向けです。大きなテーブルでは遅く、Postgres はマスクされた列を 1 つでも含む行をすべて書き換えます。
- Anonymous Dumps。
pg_dump_anonは下流の消費者向けに匿名化されたダンプを生成します。元のクラスタはそのままです。 - Masking Views。 ベーステーブル上のビューにマスキング式を適用します。テーブルではなくビューへのアクセスを付与します。
- Masking Data Wrappers。 連邦化されたソース全体を読み取り時にマスクする外部データラッパーです。
マスキング変換
Anonymizer 2.0 は 8 つの変換ファミリーを同梱します: substitution、randomization、faking、pseudonymization、partial scrambling、shuffling、noise addition、generalization。2.0 のフェイカーは 1.x より明らかに現実的 — ロケール対応のデータ生成器が、古い静的辞書を置き換えています。
-- 1. 拡張をロードし、マスク対象ロールを宣言する。
CREATE EXTENSION anon CASCADE;
SELECT anon.start_dynamic_masking();
CREATE ROLE analyst LOGIN PASSWORD '…';
SECURITY LABEL FOR anon ON ROLE analyst IS 'MASKED';
-- 2. カラムにセキュリティラベルでマスキングルールを紐づける。
SECURITY LABEL FOR anon ON COLUMN customers.email
IS 'MASKED WITH FUNCTION anon.fake_email()';
-- 3. analyst にはフェイクメール、postgres には本物が見える。
SET ROLE analyst;
SELECT email FROM customers LIMIT 1;
-- email
-- ------------------------------
-- irma.fritsch@hahn-davis.test2.0 の新機能
- ロールベース透過動的マスキング — 以前は単一のマスクロールに紐づいていたが、2.0 ではきめ細かなロールポリシーに対応。
- 複数マスキングポリシー — ワークロードごとにポリシーセットを定義し切り替え可能(例: アナリスト用と、サポート用)。
- ファーストクラスのワークフローとしての匿名ダンプ — 後付けスクリプトではない。
- Debian パッケージ — ディストリビューションからインストール可能。手動コンパイル不要。
知っておくべき制約
- GUI クライアント互換性。 ドキュメントによると、DBeaver や pgAdmin のようなツールが発行する特定のクエリパターンは、動的マスキング下で想定外の挙動を示すことがあります。
- ビュー一覧。 Masking Views はバリエーションごとに増え続けます。スキーマ変更はビュー一覧全体に波及します。
- 拡張単位、クラスタ単位。 Anonymizer は単一の Postgres クラスタ内で動作します。Postgres + RDS + Aurora + Postgres 系クラウドのフリートでは、各クラスタで拡張とラベルを維持する必要があります。
- Postgres 限定。 異種フリート(Postgres + MySQL + Snowflake)では、Postgres 以外のエンジン向けに別途マスキング方針が必要です。
Bytebase Dynamic Data Masking

Bytebase Dynamic Data Masking はポリシーを Bytebase で定義し、SQL Editor のクエリ結果で強制します。拡張不要。維持すべきセキュリティラベルも不要。あらゆる PostgreSQL ディストリビューションで 1 つのポリシーモデル — そしてフリート内の他のあらゆるエンジンでも同じ。ポリシー変更と例外申請は組み込みのワークフロー — 申請。レビュー。承認。 — を通り、すべてのステップが監査されます。
ポリシーは固定の優先順位で評価される 3 つのレイヤーから構成されます: マスキング例外 > グローバルマスキングルール > カラムマスキング。
- グローバルマスキングルール。 ワークスペース単位、iptables のように順序付け — 最初に一致したルールが勝ちます。一致条件は環境、プロジェクト、データベース、データ分類レベルにまたがります。一致するたびに Semantic Type が適用され、その Semantic Type がマスキングアルゴリズム(full、partial、MD5、range、カスタム)を選びます。

- カラムマスキング。 プロジェクト単位のオーバーライド。
Project Ownerがグローバルルールに該当しない特定カラムに Semantic Type を割り当てます。グローバルルールはカラムマスキングに優先します。

- マスキング例外。 指名されたユーザーが特定のデータベースまたはテーブルに対して期限付きの
QueryまたはExport例外を受けます。サービスアカウントは対象外 — 例外は SQL Editor でクエリする人間ユーザー向けです。すべての付与とすべてのアクセスが記録されます。

マスキングは 感染性 があります。カラムがマスクされると、そのポリシーは依存するすべてのビューと派生構造に伝播します。結果は SQL Editor に直接届きます。

ポリシーは GitOps でコード化することもできます。
マスキングの決定は監査ログに記録されます。SQL 実行エントリは、どのカラムがマスクされて返ったか、どの Semantic Type がそれを発火させたか、どのルールが一致したかというカラム単位のマスキングメタデータを、ユーザー、送信元 IP、ステートメント、行数とともに記録します。例外の付与、例外の行使、ポリシーの編集はファーストクラスの監査イベントです。ポリシーと、それが強制された証跡は同じレコードに収まります。
強制の境界: Bytebase は SQL Editor を経由するクエリをマスクします。データベースに直接到達するトラフィックはバイパスします。運用上のパターンは、人間のアクセスを Bytebase 経由に集約することです — それができれば、Postgres community、RDS、Aurora、Cloud SQL、AlloyDB、マネージドフォーク全体にマスキングが一様に適用されます。
比較
| PostgreSQL Anonymizer 2.0 | Bytebase Dynamic Data Masking | |
|---|---|---|
| 互換性 | anon 拡張が入った Postgres クラスタ | あらゆる PostgreSQL ディストリビューション ⭐️ |
| メカニズム | セキュリティラベル + 拡張関数 ⭐️ | Bytebase 内のポリシー、SQL Editor で適用 |
| 強制位置 | データベース、全読み取り経路 ⭐️ | SQL Editor |
| 戦略 | Dynamic、static、dumps、views、FDW ⭐️ | Dynamic のみ |
| ポリシー管理 | オブジェクト単位の SQL SECURITY LABEL | 集中 UI、付与、監査ログ ⭐️ |
| ワークフロー | DDL のみ | 申請。レビュー。承認。 ⭐️ |
| 行レベル制御 | 無し(RLS と併用) | 無し(アクセスポリシーと併用) |
| 価格 | 無料 ⭐️ | 有償 |
選び方
- 単一の Postgres クラスタで、クライアントを問わず強制したい場合。 PostgreSQL Anonymizer 2.0 を使う。アナリストアクセスは動的マスキング、環境クローンは
pg_dump_anon、本当にデータを破壊しなければならないときだけ静的マスキング。 - 異種フリート — Postgres と MySQL、Snowflake、RDS、Aurora、マネージドフォークが並ぶ場合。 Bytebase を使う。1 つのポリシーモデル。すべてのエンジン。すべてのアンマスクが、アクセスログと同じ場所に記録された監査付き付与で実行される。
- 両方。 Anonymizer は破壊的なワークフロー(匿名化ダンプ、下位環境のリフレッシュ)を担当し、Bytebase は人間のクエリトラフィックを承認と監査付きで担当する。両者は併用できます。
このチュートリアルで Bytebase Dynamic Data Masking を試せます。質問は Discord チャンネルへどうぞ。