エンドツーエンドのワークフローでの pg_columnmask の実装
このセクションでは、機密データを含むサンプル従業員テーブル pg_columnmask を使用するための完全な実装を示します。カスタムマスキング関数を作成し、さまざまなロール (内部、サポート、アナリスト) の異なる重みレベルを持つ複数のマスキングポリシーを定義し、単一または複数のロールメンバーシップを持つユーザーがさまざまなレベルのマスクされたデータを表示する方法を確認します。この例では、RETURNING 句を使用した DML ステートメントのマスキング動作、テーブルとビューのトリガー、名前の変更、重みの変更、クリーンアップなどのポリシー管理オペレーションについても説明します。
機密データを含むサンプルテーブルを作成します。
CREATE SCHEMA hr; CREATE TABLE hr.employees ( id INT PRIMARY KEY, name TEXT NOT NULL, email TEXT, ssn TEXT, salary NUMERIC(10,2) ); INSERT INTO hr.employees VALUES (1, 'John Doe', 'john.doe@example.com', '123-45-6789', 50000.00), (2, 'Jane Smith', 'jane.smith@example.com', '987-65-4321', 60000.00);-
カスタムマスキング関数を作成します。
CREATE OR REPLACE FUNCTION public.mask_ssn(ssn TEXT) RETURNS TEXT AS $$ BEGIN RETURN 'XXX-XX-' || RIGHT(ssn, 4); END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION public.mask_salary(salary NUMERIC, multiplier NUMERIC DEFAULT 0.0) RETURNS NUMERIC AS $$ BEGIN RETURN salary * multiplier; END; $$ LANGUAGE plpgsql; -
ユーザーロールに基づいて異なるマスキングレベルで複数のポリシーを作成します。
-- Create different roles CREATE ROLE analyst_role; CREATE ROLE support_role; CREATE ROLE intern_role; GRANT USAGE ON SCHEMA hr TO analyst_role, support_role, intern_role; GRANT SELECT ON hr.employees TO analyst_role, support_role, intern_role; ---------------------------------------------------------------------- -- Low-Weight Policy (Intern) CALL pgcolumnmask.create_masking_policy( 'employee_mask_strict', 'hr.employees', JSON_BUILD_OBJECT('name', 'pgcolumnmask.mask_text(name, ''*'')', 'email', 'pgcolumnmask.mask_email(email)', 'ssn', 'pgcolumnmask.mask_text(ssn, ''*'')', 'salary', 'public.mask_salary(salary)')::JSONB, ARRAY['intern_role'], 10 -- Lowest weight ); ---------------------------------------------------------------------- -- Medium-Weight Policy (Support) CALL pgcolumnmask.create_masking_policy( 'employee_mask_moderate', 'hr.employees', JSON_BUILD_OBJECT('email', 'pgcolumnmask.mask_email(email, ''#'')', 'ssn', 'public.mask_ssn(ssn)', 'salary', 'public.mask_salary(salary)')::JSONB, ARRAY['support_role'], 50 -- Medium weight ); ---------------------------------------------------------------------- -- High-Weight Policy (Analyst) CALL pgcolumnmask.create_masking_policy( 'employee_mask_light', 'hr.employees', JSON_BUILD_OBJECT('ssn', 'public.mask_ssn(ssn)', 'salary', 'public.mask_salary(salary, 0.9)')::JSONB, ARRAY['analyst_role'], 100 -- Highest weight ); -
次の例は、ロールメンバーシップとポリシーの重みに基づいてさまざまなユーザーがデータを表示する方法を示しています。
-- Create users CREATE USER sarah_intern; GRANT intern_role TO sarah_intern; CREATE USER lisa_support; GRANT support_role TO lisa_support; CREATE USER mike_analyst; GRANT analyst_role TO mike_analyst; CREATE USER ethan_support_intern; GRANT support_role, intern_role TO ethan_support_intern; CREATE USER john_analyst_intern; GRANT analyst_role, intern_role TO john_analyst_intern;インターンとして (最も厳格なマスキング):
SET ROLE sarah_intern; SELECT * FROM hr.employees; id | name | email | ssn | salary ----+------------+------------------------+-------------+-------- 1 | ******** | XXXXXXXX@XXXXXXX.com | *********** | 0.00 2 | ********** | XXXXXXXXXX@XXXXXXX.com | *********** | 0.00サポートユーザーとして (中程度のマスキング):
SET ROLE lisa_support; SELECT * FROM hr.employees; id | name | email | ssn | salary ----+------------+------------------------+-------------+-------- 1 | John Doe | ########@#######.com | XXX-XX-6789 | 0.00 2 | Jane Smith | ##########@#######.com | XXX-XX-4321 | 0.00アナリストとして (最小のマスキング):
SET ROLE mike_analyst; SELECT * FROM hr.employees; id | name | email | ssn | salary ----+------------+------------------------+-------------+---------- 1 | John Doe | john.doe@example.com | XXX-XX-6789 | 45000.00 2 | Jane Smith | jane.smith@example.com | XXX-XX-4321 | 54000.00インターンユーザーとサポートユーザーの両方である ethan_support_intern ユーザーとして:
SET ROLE ethan_support_intern; -- masking policies appliable to this user: employee_mask_strict and employee_mask_moderate -- id : unmasked because no masking policy appliable on ethan_support_intern -- masks these columns -- name : masked because of employee_mask_strict policy -- email, ssn, salary : both employee_mask_strict and employee_mask_moderate mask these columns -- but employee_mask_moderate will be use because of higher weight SELECT * FROM hr.employees; id | name | email | ssn | salary ----+------------+------------------------+-------------+-------- 1 | ******** | ########@#######.com | XXX-XX-6789 | 0.00 2 | ********** | ##########@#######.com | XXX-XX-4321 | 0.00インターンとアナリストの両方である john_analyst_intern として:
SET ROLE john_analyst_intern; -- masking policies appliable to this user: employee_mask_strict and employee_mask_light -- id : unmasked because no masking policy appliable on john_analyst_intern -- masks these columns -- name, email : masked because of employee_mask_strict -- ssn, salary : both employee_mask_strict and employee_mask_light mask these columns -- but employee_mask_light will be use because of higher weight SELECT * FROM hr.employees; id | name | email | ssn | salary ----+------------+------------------------+-------------+---------- 1 | ******** | XXXXXXXX@XXXXXXX.com | XXX-XX-6789 | 45000.00 2 | ********** | XXXXXXXXXX@XXXXXXX.com | XXX-XX-4321 | 54000.00