SSN、クレジットカード、メール、住所。これらのカラムはサポート、分析、開発のために依然としてクエリ可能であり続ける必要があるので、ロックして閉じ込めるわけにはいきません。かといって、全員に平文を配るわけにもいきません。データマスキングはその中間解です。GDPR、HIPAA、PCI のワークロードでは、そもそも選択の余地すらありません。規制が要求するからです。
SQL Server はDynamic Data Maskingを 2016 年以降、すべてのエディションのコアに同梱しています。Bytebase Dynamic Data Masking はその前段に位置します。すべての SQL Server ディストリビューション、そしてフリート内のあらゆる他エンジンにまたがる 1 つのポリシーモデルに、申請・レビュー・承認を上乗せします。本記事で両者を比較します。
SQL Server Dynamic Data Masking
DDM は SQL Server 2016 以降(Express を含む全エディション)、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、Microsoft Fabric の SQL database で GA です。プラグイン不要。エディションゲート無し。MASKED WITH は CREATE TABLE と ALTER TABLE の一部です。
マスクはカラムごとに定義します。サーバーは UNMASK を持たないプリンシパルに対してクエリ結果を書き換えます。ディスク上のデータは変更されません。
5 つのマスク種別
| Function | 挙動 |
|---|---|
default() | 完全マスク。文字列は XXXX、数値は 0、日時は 1900-01-01、バイナリは 1 バイトのゼロ。 |
email() | 先頭 1 文字と固定の .com サフィックスを露出: aXXX@XXXX.com。 |
random(start, end) | 数値を範囲内のランダム値に置換。クエリごとに再生成。 |
partial(prefix, [padding], suffix) | 任意の文字列マスク。先頭 N と末尾 M 文字を露出し、中央をパディングで埋める。 |
datetime("Y"|"M"|"D"|"h"|"m"|"s") | SQL Server 2022 のみ。datetime の構成要素(年、月、日、時、分、秒)の 1 つをマスク。 |
CREATE TABLE Data.Membership (
MemberID INT IDENTITY(1,1) PRIMARY KEY,
FirstName VARCHAR(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
LastName VARCHAR(100) NOT NULL,
Phone VARCHAR(12) MASKED WITH (FUNCTION = 'default()') NULL,
Email VARCHAR(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,
DiscountCode SMALLINT MASKED WITH (FUNCTION = 'random(1, 100)') NULL,
BirthDay DATETIME MASKED WITH (FUNCTION = 'datetime("Y")') NULL
);
-- Add a mask to an existing column.
ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');
-- A user without UNMASK sees masked values.
EXECUTE AS USER = 'MaskingTestUser';
SELECT FirstName, LastName, Phone, Email FROM Data.Membership;
-- Rxxxxxo Taxxxxo xxxx RXXX@XXXX.com
REVERT;権限
モデルを統制するのは 2 つの権限です:
UNMASKはSELECTで平文を返します。基となるデータが必要なプリンシパルに付与します。ALTER ANY MASKはマスクの追加、変更、削除を行います。テーブルのALTERとは別に、通常はセキュリティ担当者へ付与します。
sysadmin、db_owner、データベースに対する CONTROL を持つ者は常に平文を見られます。CONTROL は両者を暗黙的に含みます。db_owner を持つ DBA は DDM の対象外です。
SQL Server 2022 の粒度の細かい UNMASK
2022 以前、UNMASK はデータベース全体に対するものでした。一度付与すれば、そのプリンシパルはデータベース内のすべてのマスク済みカラムを見られました。**SQL Server 2022(16.x)**は 4 段階のスコープ付き付与を追加しました:
-- Column-level: only Data.Membership.FirstName.
GRANT UNMASK ON Data.Membership(FirstName) TO ServiceAttendant;
-- Table-level: every masked column on Data.Membership.
GRANT UNMASK ON Data.Membership TO ServiceLead;
-- Schema-level: every masked column under the Data schema.
GRANT UNMASK ON SCHEMA::Data TO ServiceManager;
-- Database-level: equivalent to the pre-2022 grant.
GRANT UNMASK TO ServiceHead;付与先は Microsoft Entra(旧 Azure AD)のユーザーやグループに直接指定できます。ディレクトリ駆動のアクセスモデルへ、変換層を挟まず DDM を組み込めます。
DDM がしないこと
- アドホックな推測を防ぐ。
SELECTを持ちUNMASKを持たないプリンシパルは、述語で探りを入れられます。WHERE Salary BETWEEN 99999 AND 100001はマスクされた0を返しますが、どの行が一致したかは露見します。DDM は事故的な露出を塞ぎますが、悪意ある推測は塞ぎません。行レベルセキュリティと監査を併用してください。 CONTROL保有者を止める。sysadmin、db_owner、データベースに対するCONTROLは平文を見られます。これらを持つ者を制限してください。- 書き込みをゲートする。 マスク済み
SELECTとUPDATEを持つユーザーは、依然としてカラムを上書きできます。マスクの認可と書き込みの認可は別の判断です。 SELECT INTO/INSERT INTOでマスクを剥がす。UNMASK無しでマスク済みカラムからコピーすると、宛先にマスク値が書き込まれます。環境クローンはマスクを継承します。ETL パイプラインはソース側でUNMASKを必要とします。- 式の中でマスク種別を保つ。 マスク済みカラムを参照する式は常にマスクされますが、必ずデフォルトマスクになります。
LEFT(email, 3)はemail()の形ではなくXXXを返します。 - あらゆるカラム種別に適用する。 Always Encrypted カラム、
FILESTREAM、COLUMN_SET内のスパースカラム、計算列から参照されるカラム、フルテキストインデックスのキー、PolyBase 外部テーブルはマスクできません。 - インデックス付きビューをサポートする。 基テーブルがインデックス付きビューから参照されている場合は非サポートです。
- マスク済みカラムでクロスデータベース結合を正しく返す。 リモート側はリンク越しにマスク値を送ります。結合や比較はマスク済みデータ上で実行されます。
- 行をフィルタする。 DDM はカラムをゲートします。行レベル制御が必要ならRow-Level Securityと併用します。
Bytebase Dynamic Data Masking
ネイティブ DDM には文書化された 2 つの隙があります。CONTROL 保有者は平文を見られる。SELECT のみのユーザーは範囲述語で基の値を推測できる。どちらも同じ設計に由来します。DDM はエンジン内部で結果を書き換えますが、権限と述語はその書き換えの上流で動きます。隙を塞ぐには、結果だけでなくクエリそのものを統制する必要があります。
Bytebase Dynamic Data Masking はクエリを統制します。クエリは Bytebase の SQL Editor を経由し、Bytebase は結果をエディタから出る前にマスクします。バックエンドのインスタンスで db_owner や sysadmin であってもポリシーをバイパスできません。アドホックな推測はアクセス判断になります。Query 権限の付与は組み込みのワークフロー、申請・レビュー・承認を通り、すべてのステップが監査されます。
ポリシーは固定の優先順位で評価される 3 つのレイヤーから構成されます: マスキング例外 > グローバルマスキングルール > カラムマスキング。
- グローバルマスキングルール。 ワークスペース単位。ルールは上から評価され、最初に一致したものが勝ちます。一致条件は環境、プロジェクト、データベース、データ分類にまたがります。一致するたびに Semantic Type が適用され、それがマスキングアルゴリズム(full、partial、MD5、range、カスタム)を選びます。
- カラムマスキング。 プロジェクト単位のオーバーライド。グローバルルールが該当しない特定カラムに適用します。
- マスキング例外。 指名されたユーザーが特定のデータベースまたはテーブルに対して期限付きの
QueryまたはExport例外を受けます。サービスアカウントは対象外。すべての付与とすべてのアクセスが記録されます。
マスキングは伝播します。カラムがマスクされると、そのポリシーは依存するすべてのビューと派生構造に及びます。マスク済みカラム上の式もマスクされたままで、DDM の「すべてが default() に潰れる」という落とし穴はありません。
ポリシーは GitOps でコード化することもできます。
マスキングの決定は監査ログに記録されます。SQL 実行エントリは、マスクされたカラム、Semantic Type、一致したルールというカラム単位のマスキングメタデータを、ユーザー、送信元 IP、ステートメント、行数とともに記録します。例外の付与、例外の行使、ポリシーの編集はファーストクラスの監査イベントです。アクセス判断と強制の証跡は同じレコードに収まります。
1 つ明確にしておきます。強制の境界です。Bytebase は SQL Editor を経由するクエリをマスクします。SQL Server に直接到達するトラフィックはこれをバイパスし、そこはネイティブ DDM と UNMASK がカバーします。パターンは対称です。データベースではネイティブ DDM、承認と監査が要る人間のクエリ経路では Bytebase。1 つのポリシーが SQL Server、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse、Fabric SQL database、AWS RDS for SQL Server に適用されます。
比較
| SQL Server Dynamic Data Masking | Bytebase Dynamic Data Masking | |
|---|---|---|
| 互換性 | SQL Server 2016+、Azure SQL、MI、Synapse、Fabric | あらゆる SQL Server ディストリビューション ⭐️ |
| メカニズム | カラム上の MASKED WITH ⭐️ | Bytebase 内のポリシー、SQL Editor で適用 |
| 強制位置 | データベース、全読み取り経路 ⭐️ | SQL Editor |
| マスク種別 | 5 つの組み込み関数 | full、partial、MD5、range、カスタム |
| ポリシー管理 | 各データベースで T-SQL DDL | 集中 UI、付与、監査ログ ⭐️ |
| 権限スコープ | DB / スキーマ / テーブル / カラム(2022+) | プロジェクト、データベース、テーブル、カラム |
| ワークフロー | DDL のみ | 申請・レビュー・承認 ⭐️ |
| 行レベル制御 | 無し(Row-Level Security と併用) | 無し(アクセスポリシーと併用) |
| 価格 | 無料、全エディション ⭐️ | 有償 |
選び方
- 単一の SQL Server インスタンス、または単一の Azure SQL データベースで、クライアントを問わずマスキングを強制しなければならない場合。 ネイティブ DDM を使います。無料、コアに同梱、そして
UNMASKを持たないプリンシパルに対して BCP エクスポート、SSIS、SELECT INTOをマスクする唯一の選択肢です。SQL Server 2022 以降では、2016 のオールオアナッシングモデルよりスコープ付き付与(GRANT UNMASK ON SCHEMA::/ON table(column))を選びます。 - 混在フリート。SQL Server を Postgres、MySQL、Snowflake、RDS、マネージドフォークと併用する場合。 Bytebase を使います。1 つのポリシーモデル、すべてのエンジン、すべてのアンマスクに監査付きの付与、アクセスログと同じ場所に記録。
- 両方。 ネイティブ DDM はデータベースでマスクします。直接接続、エクスポート、アドホックツール向けです。Bytebase は人間のクエリ経路を SQL Editor 経由で統制し、承認と監査を提供します。両者は組み合わさります。
このチュートリアルで Bytebase Dynamic Data Masking を試せます。